Merge remote-tracking branch 'origin/dev' into fixt push-health-check-redis-disabled-detection

This commit is contained in:
Owen Greenhalgh
2026-05-28 19:07:31 +01:00
255 changed files with 24255 additions and 3788 deletions

View File

@@ -18,7 +18,7 @@ env:
AWS_REGION: us-west-2
# Branches allowed to deploy to staging via workflow_dispatch with tag=deploy-staging.
# Add short-lived PR branches here when you need staging without merging to dev.
STAGING_DEPLOY_BRANCH_ALLOWLIST: fix-health-check-redis-disabled-detection
STAGING_DEPLOY_BRANCH_ALLOWLIST: fix-health-check-redis-disabled-detection feat/track-rate-limit-redis
jobs:
checks:

View File

@@ -39,5 +39,6 @@
".cursor": true,
".mcp.json": true,
".zed": true
}
},
"typescript.native-preview.tsdk": "/Users/johnyeocx/autumn/main/node_modules/@typescript/native-preview"
}

View File

@@ -0,0 +1,50 @@
---
title: "Batch Track Usage"
openapi: "openapi POST /v1/balances.batch_track"
---
import { DynamicParamField } from "/snippets/dynamic-param-field.jsx";
import { DynamicResponseField } from "/snippets/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/snippets/dynamic-response-example.jsx";
<Note>
Batch track enqueues up to **1000 usage events** in a single request. Items are validated synchronously, then enqueued for asynchronous processing. The response returns **202 immediately** without balance information — balances are deducted by background workers.
Use this when you're sending high volumes of tracking events and don't need an immediate balance read for each one.
</Note>
### Common Use Cases
<CodeGroup>
```typescript Batch many customers
await autumn.balances.batchTrack([
{ customerId: "cus_alice", featureId: "ai_messages", value: 1 },
{ customerId: "cus_bob", featureId: "ai_messages", value: 1 },
{ customerId: "cus_carol", featureId: "ai_messages", value: 3 },
]);
```
```typescript Mixed features and entities
await autumn.balances.batchTrack([
{ customerId: "cus_123", featureId: "ai_messages", value: 5 },
{ customerId: "cus_123", featureId: "api_calls", value: 12 },
{ customerId: "cus_123", featureId: "seats", entityId: "team_a", value: 1 },
]);
```
</CodeGroup>
### Partial-Failure Semantics
Batch track is designed for fire-and-forget metering. On partial failure, **the endpoint still returns 202** and logs the failed items server-side. Clients should NOT retry the batch — retrying re-enqueues the already-succeeded items, which causes double-deduction. The trade-off is silent loss of the small subset that didn't enqueue vs. duplicate processing of the much larger subset that did. For event-logging workloads, gaps are preferable to duplicates.
A 503 is returned only when **zero items were successfully enqueued** (the queue is entirely unavailable). In that case the whole request is safe to retry.
If your workload requires per-item delivery guarantees, use the [single-event track endpoint](/api-reference/core/track) with client-side retry semantics instead.
### Limits
- **Maximum batch size:** 1000 items per request
- **Minimum batch size:** 1 item
- **Rate limit:** 10 requests/second per organization (separate bucket from the single `/v1/balances.track` limiter)

View File

@@ -40,4 +40,13 @@ await autumn.track({
});
```
```typescript Async (fire-and-forget)
await autumn.track({
customerId: "cus_123",
featureId: "ai_messages",
value: 1,
async: true // Returns 202 immediately; usage processed in the background
});
```
</CodeGroup>

View File

@@ -132,7 +132,7 @@ This is useful for attaching custom metadata to the Stripe subscription created
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required>
The ID of the feature to configure.

View File

@@ -99,7 +99,7 @@ const response = await autumn.billing.update({
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required>
The ID of the feature to configure.

View File

@@ -65,7 +65,7 @@ import { DynamicResponseExample } from "/snippets/dynamic-response-example.jsx";
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required>
The ID of the feature to configure.

View File

@@ -65,7 +65,7 @@ import { DynamicResponseExample } from "/snippets/dynamic-response-example.jsx";
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required>
The ID of the feature to configure.

View File

@@ -65,7 +65,7 @@ import { DynamicResponseExample } from "/snippets/dynamic-response-example.jsx";
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required>
The ID of the feature to configure.

View File

@@ -0,0 +1,103 @@
---
title: "Batch Track Usage"
openapi: "openapi POST /v1/balances.batch_track"
---
import { DynamicParamField } from "/snippets/dynamic-param-field.jsx";
import { DynamicResponseField } from "/snippets/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/snippets/dynamic-response-example.jsx";
<Note>
Batch track enqueues up to **1000 usage events** in a single request. Items are validated synchronously, then enqueued for asynchronous processing. The response returns **202 immediately** without balance information — balances are deducted by background workers.
Use this when you're sending high volumes of tracking events and don't need an immediate balance read for each one.
</Note>
### Common Use Cases
<CodeGroup>
```typescript Batch many customers
await autumn.balances.batchTrack([
{ customerId: "cus_alice", featureId: "ai_messages", value: 1 },
{ customerId: "cus_bob", featureId: "ai_messages", value: 1 },
{ customerId: "cus_carol", featureId: "ai_messages", value: 3 },
]);
```
```typescript Mixed features and entities
await autumn.balances.batchTrack([
{ customerId: "cus_123", featureId: "ai_messages", value: 5 },
{ customerId: "cus_123", featureId: "api_calls", value: 12 },
{ customerId: "cus_123", featureId: "seats", entityId: "team_a", value: 1 },
]);
```
</CodeGroup>
### Partial-Failure Semantics
Batch track is designed for fire-and-forget metering. On partial failure, **the endpoint still returns 202** and logs the failed items server-side. Clients should NOT retry the batch — retrying re-enqueues the already-succeeded items, which causes double-deduction. The trade-off is silent loss of the small subset that didn't enqueue vs. duplicate processing of the much larger subset that did. For event-logging workloads, gaps are preferable to duplicates.
A 503 is returned only when **zero items were successfully enqueued** (the queue is entirely unavailable). In that case the whole request is safe to retry.
If your workload requires per-item delivery guarantees, use the [single-event track endpoint](/api-reference/core/track) with client-side retry semantics instead.
### Limits
- **Maximum batch size:** 1000 items per request
- **Minimum batch size:** 1 item
- **Rate limit:** 10 requests/second per organization (separate bucket from the single `/v1/balances.track` limiter)
### Body Parameters
<DynamicParamField body="items" type="object">
Array item
<Expandable title="properties">
<DynamicParamField body="customer_id" type="string" required>
The ID of the customer.
</DynamicParamField>
<DynamicParamField body="feature_id" type="string">
The ID of the feature to track usage for. Required if event_name is not provided.
</DynamicParamField>
<DynamicParamField body="entity_id" type="string">
The ID of the entity for entity-scoped balances (e.g., per-seat limits).
</DynamicParamField>
<DynamicParamField body="event_name" type="string">
Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event.
</DynamicParamField>
<DynamicParamField body="value" type="number">
The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat).
</DynamicParamField>
<DynamicParamField body="properties" type="object">
Additional properties to attach to this usage event.
</DynamicParamField>
<DynamicParamField body="async" type="boolean">
If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information.
</DynamicParamField>
<DynamicParamField body="lock" type="object">
<Expandable title="properties">
<DynamicParamField body="lock_id" type="string" required>
A unique identifier for this lock. Used to finalize the lock later via balances.finalize.
</DynamicParamField>
<DynamicParamField body="enabled" type="any" required>
Must be true to enable locking.
</DynamicParamField>
<DynamicParamField body="expires_at" type="number">
Unix timestamp (ms) when the lock automatically expires and releases the held balance.
</DynamicParamField>
</Expandable>
</DynamicParamField>
</Expandable>
</DynamicParamField>

View File

@@ -40,6 +40,15 @@ await autumn.track({
});
```
```typescript Async (fire-and-forget)
await autumn.track({
customerId: "cus_123",
featureId: "ai_messages",
value: 1,
async: true // Returns 202 immediately; usage processed in the background
});
```
</CodeGroup>
### Body Parameters
@@ -68,6 +77,10 @@ await autumn.track({
Additional properties to attach to this usage event.
</DynamicParamField>
<DynamicParamField body="async" type="boolean">
If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information.
</DynamicParamField>
<DynamicParamField body="lock" type="object">
<Expandable title="properties">
<DynamicParamField body="lock_id" type="string" required>

View File

@@ -39,6 +39,10 @@ import { DynamicResponseExample } from "/snippets/dynamic-response-example.jsx";
Filter by parent customer processor type (stripe, revenuecat, vercel).
</DynamicParamField>
<DynamicParamField body="customer_id" type="string">
Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get.
</DynamicParamField>
### Response

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,18 @@ mode: "center"
description: "Some new things we've shipped at Autumn HQ"
---
<Update label="May 28th 2026">
## Batch track and async track
Two new ways to record usage when you don't need an immediate balance read:
- [`POST /v1/balances.batch_track`](/api-reference/core/batchTrack) — enqueue up to **1000 usage events** in one request. Returns 202 immediately; balances are deducted by background workers.
- **`async: true`** on the existing [`POST /v1/balances.track`](/api-reference/core/track) — same fire-and-forget shape for single-event callers that want the speed without switching to the batch endpoint.
Both paths are intended for high-volume metering (event logging, per-action usage counters) where you'd previously be limited by the synchronous deduction's HTTP round-trip. Partial enqueue failures are logged server-side and do NOT surface as errors to the client — see the [batch track reference](/api-reference/core/batchTrack#partial-failure-semantics) for the trade-off.
</Update>
<Update label="May 20th 2026">
## `billing.updated` webhook

View File

@@ -205,6 +205,7 @@
"pages": [
"api-reference/core/check",
"api-reference/core/track",
"api-reference/core/batchTrack",
"api-reference/balances/createBalance",
"api-reference/balances/updateBalance",
"api-reference/balances/deleteBalance",

View File

@@ -0,0 +1,20 @@
FROM oven/bun:1.3.10 AS pruner
WORKDIR /app
COPY . .
RUN bunx turbo@2.9.14 prune @autumn/mcp-server --docker
FROM oven/bun:1.3.10
WORKDIR /app
COPY --from=pruner /app/out/json/ .
RUN mkdir -p scripts && touch scripts/preload-env.ts
RUN bun -e 'const fs = require("fs"); const pkg = JSON.parse(fs.readFileSync("package.json", "utf8")); pkg.workspaces.packages = ["shared", "apps/mcp-server", "packages/ksuid", "packages/mcp"]; delete pkg.dependencies; delete pkg.devDependencies; delete pkg.scripts; fs.writeFileSync("package.json", JSON.stringify(pkg, null, 2));'
RUN rm bun.lock && bun install --production --ignore-scripts
COPY --from=pruner /app/out/full/ .
ENV NODE_ENV=production
EXPOSE 8080
CMD ["bun", "-F", "@autumn/mcp-server", "start"]

View File

@@ -0,0 +1,20 @@
{
"name": "@autumn/mcp-server",
"private": true,
"type": "module",
"scripts": {
"dev": "bun --watch src/index.ts",
"start": "bun src/index.ts",
"ts": "tsc --noEmit"
},
"dependencies": {
"@autumn/mcp": "workspace:*",
"@hono/node-server": "^1.19.5",
"hono": "4.12.7"
},
"devDependencies": {
"@types/bun": "^1.2.13",
"@types/node": "^18.19.3",
"typescript": "~5.8.3"
}
}

100
apps/mcp-server/src/http.ts Normal file
View File

@@ -0,0 +1,100 @@
import type { HttpBindings } from "@hono/node-server";
import { RESPONSE_ALREADY_SENT } from "@hono/node-server/utils/response";
import {
buildAuthForRequest,
createAskAutumnMCPServer,
createAutumnOperationsMCPServer,
getAuthorizationServerMetadata,
getProtectedResourceMetadata,
type ConsoleLogger,
type MCPServerFlags,
type OAuthEnvironment,
OAuthHttpError,
} from "@autumn/mcp";
import type { Context } from "hono";
import { Hono } from "hono";
export interface CreateMcpHttpAppOptions extends MCPServerFlags {
readonly "oauth-enabled": boolean;
readonly "oauth-environment": OAuthEnvironment;
readonly logger: ConsoleLogger;
}
type AppContext = Context<{ Bindings: HttpBindings }>;
type McpPath = "/mcp" | "/internal/mcp";
export function createMcpHttpApp(options: CreateMcpHttpAppOptions) {
const app = new Hono<{ Bindings: HttpBindings }>();
app.use("*", async (c, next) => {
c.header("Access-Control-Allow-Origin", "*");
c.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
c.header("Access-Control-Allow-Headers", "*");
return c.req.method === "OPTIONS" ? c.body(null, 204) : next();
});
app.get("/.well-known/oauth-protected-resource/mcp", (c) =>
c.json(getProtectedResourceMetadata(c.req.raw.headers, options, "/mcp")),
);
app.get("/.well-known/oauth-protected-resource/internal/mcp", (c) =>
c.json(
getProtectedResourceMetadata(
c.req.raw.headers,
options,
"/internal/mcp",
),
),
);
app.get("/.well-known/oauth-authorization-server", (c) =>
c.json(getAuthorizationServerMetadata(options)),
);
const handleMcp = async (
c: AppContext,
path: McpPath,
server: ReturnType<typeof createAskAutumnMCPServer>,
) => {
let auth: Awaited<ReturnType<typeof buildAuthForRequest>>;
try {
auth = await buildAuthForRequest(
c.req.raw.headers,
options,
options.logger,
path,
);
} catch (error) {
if (error instanceof OAuthHttpError) {
if (error.wwwAuthenticate) {
c.header("WWW-Authenticate", error.wwwAuthenticate);
}
return c.json(
{ error: error.error, error_description: error.message },
{ status: error.status as 401 | 403 },
);
}
throw error;
}
(c.env.incoming as typeof c.env.incoming & { auth?: typeof auth }).auth =
auth;
await server.startHTTP({
url: new URL(c.req.url),
httpPath: path,
req: c.env.incoming,
res: c.env.outgoing,
options: { serverless: true },
});
return RESPONSE_ALREADY_SENT;
};
app.all("/mcp", (c) =>
handleMcp(c, "/mcp", createAutumnOperationsMCPServer()),
);
app.all("/internal/mcp", (c) =>
handleMcp(c, "/internal/mcp", createAskAutumnMCPServer()),
);
return app;
}

View File

@@ -0,0 +1,30 @@
import { serve } from "@hono/node-server";
import {
createConsoleLogger,
type OAuthEnvironment,
} from "@autumn/mcp";
import { createMcpHttpApp } from "./http.js";
const port = Number.parseInt(process.env.PORT ?? process.env.MCP_PORT ?? "2718", 10);
const serverURL =
process.env.MCP_SERVER_URL ??
(process.env.NODE_ENV === "production"
? "https://api.useautumn.com"
: "http://localhost:8080");
const oauthEnvironment: OAuthEnvironment =
process.env.MCP_OAUTH_ENVIRONMENT === "live" ? "live" : "sandbox";
const logger = createConsoleLogger("info");
const app = createMcpHttpApp({
"oauth-enabled": true,
"oauth-environment": oauthEnvironment,
"server-url": serverURL,
logger,
});
serve({
fetch: app.fetch,
hostname: "0.0.0.0",
port,
}, ({ address, port }) => {
logger.info("MCP server started", { host: `${address}:${port}` });
});

View File

@@ -0,0 +1,26 @@
{
"compilerOptions": {
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"lib": ["es2024"],
"module": "Preserve",
"moduleResolution": "bundler",
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"skipLibCheck": true,
"strict": true,
"target": "es2022",
"types": ["bun"],
"paths": {
"@api/*": ["../../shared/api/*"],
"@models/*": ["../../shared/models/*"],
"@utils/*": ["../../shared/utils/*"],
"@autumn/ksuid": ["../../packages/ksuid/src/index.ts"]
}
},
"include": ["src/**/*.ts"]
}

View File

@@ -1,19 +1,42 @@
"use client";
import { AnimatePresence, motion } from "motion/react";
import { type ReactNode, useState } from "react";
import { type ReactNode, useEffect, useRef, useState } from "react";
export function Expand({
id,
title = "",
children,
}: {
id?: string;
title?: string;
children?: ReactNode;
}) {
const [open, setOpen] = useState(false);
const rootRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!id) return;
const openIfMatches = () => {
if (window.location.hash.slice(1) !== id) return;
setOpen(true);
requestAnimationFrame(() => {
rootRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
});
};
openIfMatches();
window.addEventListener("hashchange", openIfMatches);
return () => window.removeEventListener("hashchange", openIfMatches);
}, [id]);
return (
<div className="my-4 rounded-lg border border-[#292929] bg-[#141414]">
<div
id={id}
ref={rootRef}
className="my-4 rounded-lg border border-[#292929] bg-[#141414] scroll-mt-24"
>
<button
type="button"
onClick={() => setOpen((o) => !o)}

View File

@@ -142,17 +142,17 @@ export default function Hero() {
<div className="flex flex-col gap-6 w-full px-0 lg:px-0">
<h1 className="hero-reveal lg:opacity-0 text-[44px] md:text-[56px] w-full max-w-sm sm:max-w-[480px] md:max-w-xl leading-[44px] tracking-[-5%] md:leading-14 font-sans">
<span className="text-[#FFFFFF99] font-normal">
The revenue runtime for
One API for
</span>{" "}
<span className="text-white block md:inline"> AI companies</span>
<span className="text-white block md:inline">plans, usage and AI credits</span>
</h1>
<p className="hero-reveal lg:opacity-0 tracking-[-2%] w-full max-w-xs sm:max-w-[480px] md:max-w-xl text-[#FFFFFF99] md:text-[16px] text-[14px] font-light leading-5 font-sans">
Your {" "}
Replace your in-house usage tracking, gating and asynchronous billing logic.
Autumn gives you a{" "}
<span className="text-white font-light">
real-time source of truth
flexible source of truth
</span>{" "}
for usage-based, PLG and sales-led monetization. Replace your usage limits, credit ledger and Stripe billing logic
with a flexible control plane.
across self-serve payments and enterprise deals.
</p>
</div>

View File

@@ -0,0 +1,385 @@
---
title: "Building an AI agent to automatically investigate support tickets"
description: "How we automated customer support investigations by structuring our logs and giving Claude Code the right primitives."
date: "2026-05-27"
author: "John, Autumn Co-Founder"
slug: "building-an-ai-agent-to-investigate-support-tickets"
image: "/images/blog/building-an-ai-agent-to-investigate-support-tickets.png"
---
Billing is inherently stateful. The outcome of an API call depends on a customer's billing state and history. For instance, if a customer schedules a cancellation, then later upgrades their plan, the cancellation may need to be automatically undone. This means that simple operations sometimes have confusing results, leading to more support tickets and bug reports.
Investigating these issues usually means digging through logs to reconstruct a customer's billing timeline: what actions they took leading up to the request, what state the customer was in at the time, and what happened after the request. So for a single ticket, we'd have to write a bunch of queries on Axiom (where we store all of our logs), sift through hundreds of logs and analyse the request / response payloads to piece together what happened.
You can imagine how tedious this would be if done manually. We'd sometimes spend entire days on investigations.
### Structuring our logs
To understand how we automate investigations, it's worth first understanding how we structure our logs. We spent a lot of time making them structured, queryable, and easy to reason about for ourselves, and incidentally, this also made them extremely effective for AI agents.
Firstly, logs are request centric — every log in our codebase adds context to the originating request by enriching a JSON payload which is outputted once at the end of the request. It adopts the principles of wide logging explained in this [article](https://loggingsucks.com/). At the minimum, each request will have the following properties:
- Tenant context (which org and customer made the request)
- Request / response body
- Miscellaneous info like timestamp, API version, etc.
This is implemented via middlewares, and an example of the one which adds tenant context is shown below:
```tsx
export const analyticsMiddleware = async (c: Context<HonoEnv>, next: Next) => {
const ctx = c.get("ctx");
const skipUrls = ["/v1/customers/all/search"];
ctx.logger = addAppContextToLogs({
logger: ctx.logger,
appContext: {
org_id: ctx.org?.id,
org_slug: ctx.org?.slug,
env: ctx.env,
auth_type: ctx.authType,
customer_id: ctx.customerId,
api_version: ctx.apiVersion?.semver,
scopes: ctx.scopes
},
});
await next();
const finalCtx = c.get("ctx");
logRequestResult({ ctx: finalCtx, skipUrls });
};
```
(ps. perhaps obvious, but if there's one thing to add to logs, it's tenant context. It's by far the most effective filter and often the starting point of most investigations)
Secondly, we treat logs as a first class citizen when shipping features. The way we do this is that we have a field in our request context object `extras` which is append only and a flexible schema.
For each endpoint, as we walk through the request, we intentionally write functions to add to this `extras` object — capturing the information necessary to understand the customer state at that point. For instance, during upgrades we log which plan is outgoing, which plan is incoming, if there was a previous cancelation and so on. Here's an example of the information we log for an upgrade request:
```tsx
{
"checkoutMode": "stripe_checkout",
"invoiceMode": "default",
"planTiming": "immediate",
"product": "premium (v1) standard",
"currentProduct": "free",
"scheduledCustomerProduct": "none",
"stripe": "no sub | no schedule",
"timestamps": "Current: 25 May 2026 09:33:34 | Billing Anchor: now | Reset: now",
"transition": "free -> premium (immediate)",
"trialContext": "none"
}
```
### Teaching our AI agent how to investigate
With our logs structure in place, investigations became much more definable. It's simply a process of iterating over queries until you have the right set of logs to make an accurate assumption on what happened.
To pass this information to an agent, all we did was:
- Hook Claude Code up to Axiom's MCP and skills
- Write a couple of custom skills detailing how we structure our logs, the different "domains" of investigations (billing, stripe webhooks, entitlements, etc.)
- For each domain, add core pieces of information on how it roughly works under the hood (for instance, with entitlements, how our caching structure works)
Here's an example of the top level skill and one of the domain specific reference files:
<Expand id="axiom-investigate" title="/axiom-investigate">
````mdx
---
name: axiom-investigate
description: "Investigate support tickets and debug customer issues using Axiom logs via the user-axiom MCP. Use when asked to investigate, debug, check logs, diagnose billing (attach, upgrade, cancel), entitlements (check, track, balance, rollover), or any customer issue."
---
# Axiom Investigation
## MCP tools
Use the `user-axiom` MCP server:
- `queryDataset` -- run APL queries. Accepts `apl`, `startTime` (default "now-30m"), `endTime` (default "now").
- `getDatasetFields` -- list all fields in a dataset. Use to discover schema before querying.
Always restrict `startTime`/`endTime` to the smallest range that covers the incident.
When confirmation requires live DB state, use the `planetscale` MCP to query directly — but ALWAYS ask the user for permission first.
## Query precision rule
Never use `search` unless absolutely necessary. Broad search scans every field across many rows, which is slow, expensive, and usually less precise.
Prefer structured filters on fields like `context.customer_id`, `context.org_slug`, `req.url`, `stripe_event.*`, and `workflow.*`. When listing requests, add `isnotnull(statusCode)` so you fetch the one result log per request instead of every internal log line for that request.
## Dataset
All server logs go to the **`express`** dataset via `@axiomhq/pino`.
## Field reference
Every log line has standard Pino fields plus structured bindings:
| Path | Fields | Description |
|------|--------|-------------|
| `context.*` | `org_id`, `org_slug`, `env`, `customer_id`, `auth_type`, `user_id`, `user_email`, `api_version` | App context -- org, customer, auth |
| `req.*` | `id`, `name`, `url`, `method`, `body`, `query`, `user_agent`, `ip_address`, `timestamp` | Request metadata. `req.id` is the trace ID for correlating logs within one request. |
| `stripe_event.*` | `id`, `type`, `object_id` | Stripe webhook event context |
| `workflow.*` | `id`, `name`, `payload` | Background worker/job context |
| (top-level) | `msg`, `level`, `statusCode`, `durationMs`, `res`, `extras`, `error`, `done` | Per-log-line fields |
**`level`** values are uppercase strings: `DEBUG`, `INFO`, `WARN`, `ERROR`.
**`extras`** is a JSON object with domain-specific data (billing plans, webhook changes, etc.). Parse with `parse_json(tostring(extras))`.
**`auth_type`** values: `PublicKey`, `SecretKey`, `Stripe`, `Worker`, `Vercel`, `Revenuecat`.
## Investigation workflow
### 1. Scope
Filter by `context.customer_id` or `context.org_slug` plus a time range. Always start narrow.
### 2. Find the incident window FIRST
Heavy queries over wide ranges time out. Run a cheap aggregate first to locate WHEN, then a focused query in a tight window.
**Pass A — cheap, wide.** `summarize` over `bin(_time, ...)`, ≤3 columns:
```
['express']
| where ['context.customer_id'] == 'CUSTOMER_ID'
| summarize errors = countif(level == 'ERROR'), total = count() by bin(_time, 5m)
| sort by _time desc
```
**Pass B — heavy, narrow.** Use MCP `startTime`/`endTime` to bound to ≤1h around the bucket Pass A surfaced. Use `parse_json`, joins on `req.id`, etc. Skip `project` — pulling the full row keeps debugging interactive (you don't have to re-run when you realize you need another field). Skip `sort by _time asc` too — Axiom's natural order suffices. Only add an explicit `sort by` when you genuinely want the OPPOSITE direction (`desc` for newest-first browsing).
If Pass A is empty, widen Pass A or change the predicate — don't run Pass B. If Pass A finds multiple buckets, run Pass B once per bucket.
### 3. Triage
Inside the narrowed window, look at errors and warnings first (`level == "ERROR" or level == "WARN"`), then broaden to INFO if needed.
### 4. Trace
Use `req.id` to follow a single request across all its log lines. Use `stripe_event.id` to trace a webhook through its handlers.
## Query templates
**All logs for a customer in a time window:**
```
['express']
| where ['context.customer_id'] == 'CUSTOMER_ID'
| where ['context.org_slug'] == 'ORG_SLUG'
```
**Errors/warnings for a customer:**
```
['express']
| where ['context.customer_id'] == 'CUSTOMER_ID'
| where level in ('ERROR', 'WARN')
| sort by _time desc
```
**Stripe webhook events for a customer/org:**
```
['express']
| where ['context.org_slug'] == 'ORG_SLUG'
| where isnotempty(['stripe_event.type'])
| sort by _time desc
```
**Worker job failures:**
```
['express']
| where isnotempty(['workflow.name'])
| where level in ('ERROR', 'WARN')
| sort by _time desc
```
The omitted `project` is intentional — pull the whole row so you can pivot mid-investigation without re-running. The omitted `sort by _time asc` is intentional — Axiom's natural order is fine; only add `sort by _time desc` when you specifically want newest-first.
## Never use `search` unless absolutely necessary
Only fall back to `search` if (1) the identifier has no obvious structured field, AND (2) the time window is ≤1h. Otherwise: query a structured field, or use Pass A to find the time bucket first, then narrow.
## Domain-specific guides
Read these when the investigation falls into a specific domain:
- **Billing** (attach, upgrade, downgrade, cancel, payment, checkout, auto top-up): read [billing-investigation.md](billing-investigation.md)
- **Entitlements** (check, track, balances, rollovers, `allowed`): read [entitlement-investigation.md](entitlement-investigation.md)
- **Stripe Webhooks** (subscription lifecycle, invoice payment/failure, checkout, schedule changes, customer timeline): read [stripe-webhook-investigation.md](stripe-webhook-investigation.md)
- **Redis slow commands** (latency, cache perf, SLO breaches, V2 FullSubject cache): read [redis-slow-command-investigation.md](redis-slow-command-investigation.md)
- **Infrastructure** (worker queues, rate limiting): _coming soon_
````
</Expand>
<Expand id="entitlement-investigation" title="/entitlement-investigation">
````mdx
# Entitlement Investigation
Read this when investigating: wrong `allowed` on check, balance or rollover discrepancies, usage over time, track deductions, auto top-up, balance resets, or rate limits on check/track.
**Prerequisite:** Read [SKILL.md](SKILL.md) first for dataset, field paths, and general Axiom workflow.
## Confirm routes (do not rely only on the list below)
Routes change. Confirm current paths in:
| Router | Path |
|--------|------|
| Check, track, balance CRUD | `autumn/server/src/internal/balances/balancesRouter.ts` |
| Customer get/create/update | `autumn/server/src/internal/customers/cusRouter.ts` |
| Entity get/create/delete | `autumn/server/src/internal/entities/entityRouter.ts` |
**Preliminary paths** (all under `/v1` when mounted from `apiRouter`): check `/entitled`, `/check`, `/track`, `/events`, `/balances/*`, `GET /customers/:id`, `POST /customers.get_or_create`, entity GET/RPC equivalents.
## Investigation approach: parse `req.body` and `res`
Unlike billing (heavy `extras`), entitlement work is usually **timeline analysis** from request/response bodies:
```
| extend bodyJson = parse_json(tostring(['req.body']))
| extend resJson = parse_json(tostring(res))
```
Use `coalesce(tostring(bodyJson.customer_id), tostring(['context.customer_id']))` when customer id is only in context.
## Check / entitled response (`res`)
Typical feature-check shape (newer API versions; older clients get transformed shapes -- see `autumn/shared/api/balances/check/changes/`):
| Field | Notes |
|-------|--------|
| `allowed` | Main signal |
| `customer_id`, `entity_id` | |
| `balance.granted`, `balance.remaining`, `balance.usage` | Metered / credits |
| `balance.unlimited`, `balance.overage_allowed`, `balance.next_reset_at` | |
| `balance.breakdown[]` | Per slice: `included_grant`, `prepaid_grant`, `remaining`, `usage`, `reset`, `expires_at` |
| `balance.rollovers[]` | Rollover lines -- good for "where did rollovers drop off?" |
| `flag` | Boolean-feature path when not using balance object |
**Response filter:** public API responses may strip some internal fields (e.g. certain `object` keys, `overage` on breakdown). Dashboard / internal paths may show more. See `autumn/server/src/honoMiddlewares/responseFilter/responseFilterMiddleware.ts`.
## Track response (`res`)
| Field | Notes |
|-------|--------|
| `customer_id`, `entity_id`, `event_name`, `value` | Deduction amount |
| `balance` | Updated `ApiBalanceV1` after track |
| `balances` | Map of feature_id -> balance when multiple features |
## Get customer / get entity (`res`)
Both expose **`balances`** (record keyed by feature id) and **`flags`**. Best snapshot of "all balances at a point in time" for correlating with check/track.
## Other signals in logs
| Source | What to use |
|--------|-------------|
| `statusCode` | `402` insufficient balance; `429` rate limited |
| `msg` + object | `[QUEUE SYNC]`, `[SYNC V3]`, Postgres track fallback, `Deduction updates` with `data2` (cusEntId, featureId, balance, adjustment) |
| `extras.setCache` | Full-customer cache write (large; includes `fullCustomer`) |
| `extras.autoTopupContext` | On `auto-top-up` worker: threshold, quantity, feature, cusEnt balance |
## Background `workflow.name` values
| Name | Role |
|------|------|
| `sync-balance-batch-v3` | Redis -> Postgres after track |
| `insert-event-batch` | Batched event inserts |
| `auto-top-up` | Low balance top-up |
| `expire-lock-receipt` | Lock expiry |
| `batch-reset-cus-ents` | Interval resets |
## APL patterns
**Balance timeline (check, track, customer GET):**
```
['express']
| where ['context.customer_id'] == 'CUSTOMER_ID'
| where (
['req.url'] contains 'check' or ['req.url'] contains 'entitled'
or ['req.url'] contains 'track' or ['req.url'] contains 'events'
or ['req.url'] contains 'customers'
)
| where isnotnull(statusCode)
| extend resJson = parse_json(tostring(res))
| extend bodyJson = parse_json(tostring(['req.body']))
| extend featureId = coalesce(tostring(bodyJson.feature_id), tostring(bodyJson.event_name))
| extend allowed = tostring(resJson.allowed)
| extend remaining = toint(resJson.balance.remaining)
| extend usage = toint(resJson.balance.usage)
| extend granted = toint(resJson.balance.granted)
| project _time, ['req.url'], statusCode, featureId, allowed, remaining, usage, granted
| sort by _time asc
```
**Check returned `allowed: false`:**
```
['express']
| where ['context.customer_id'] == 'CUSTOMER_ID'
| where (['req.url'] contains 'check' or ['req.url'] contains 'entitled')
| where statusCode == 200
| extend resJson = parse_json(tostring(res))
| where tostring(resJson.allowed) == 'false'
| project _time, ['req.url'], resJson, ['req.body']
| sort by _time desc
```
**Rollovers dropped off:** compare `resJson.balance.rollovers` and `breakdown` across time; cross-reference plan changes with [billing-investigation.md](billing-investigation.md).
**Auto top-up errors:**
```
['express']
| where ['workflow.name'] == 'auto-top-up'
| where level in ('ERROR', 'WARN')
| project _time, msg, error, extras, ['context.customer_id']
| sort by _time desc
```
## Codebase pointers
| Area | Path |
|------|------|
| Check | `autumn/server/src/internal/api/check/handleCheck.ts` |
| Track | `autumn/server/src/internal/balances/handlers/handleTrack.ts` |
| Balance shape | `autumn/shared/api/customers/cusFeatures/apiBalanceV1.ts` |
| Deduction logging | `autumn/server/src/internal/balances/utils/deduction/logDeductionUpdates.ts` |
| Auto top-up | `autumn/server/src/internal/balances/autoTopUp/` |
````
</Expand>
With these skills, Claude would be able to run freely on its own and figure out the root cause of tickets. Sometimes, it even discovered things that a human never would! Not only did investigations get completed more quickly, but they also became more of a background task, so our engineers could handle several of these while building new features.
The agent was also accurate because it ran over our codebase. It could link log results to the actual code paths producing them, which made debugging much sharper.
It really felt like a step change for our team.
### Taking it one step further
/axiom-investigate alone has been a lifesaver, but ultimately, the end goal would be to have these tickets handled fully autonomously. The first step we've taken towards that is having investigations triggered automatically when tickets come in. To do this, we needed infrastructure to:
- host an AI agent in the cloud with access to our codebase, MCPs and skills
- connect the AI agent to slack and have it be able to ingest support tickets and the necessary context to make an investigation
While we could've used the Slack API directly, if there's anything we've learnt so far, it's that the right foundations matter. So we decided to use [Plain](https://plain.com/) as our support infrastructure since it would handle a lot of the "support" primitives that we didn't want to build ourselves. For instance, thread infrastructure, integration with channels, and webhook triggers.
As for hosting the AI agent, we decided to go with [Mastra](https://mastra.ai/) because it abstracted away a lot of the lower level tools like memory, loading skills, MCP support, file system support, etc. It was actually fairly straightforward spinning up an agent with all the tools our local Claude Code would normally have. So our set up looks something like this today:
![Autonomous support agent architecture](/images/blog/building-an-ai-agent-to-investigate-support-tickets-architecture.png)
To be honest though, this version of the agent has mostly been useful for straightforward investigations. Once an issue requires deeper iteration, we usually fall back to running investigations locally in Claude Code instead.
### Where agents could improve
It's surprisingly difficult to fully replicate the local Claude Code environment in the cloud. Locally, we've already gotten to the point where even fairly involved bug fixes can be handled autonomously through a test-driven workflow. Recreating that reliably in a hosted agent has been much harder than expected though — MCP auth is flaky, skills don't seem to trigger correctly, and the overall understanding of our codebase feels noticeably worse. It's hard to pinpoint exactly where things break down, but the quality gap between local and hosted agents is still very real.
The interaction model also changes. With our autonomous support agent, we interact with it over Slack — agent investigates a ticket, posts results to Slack, and we then converse in a thread to dig deeper. However, in comparison to Claude Code or Codex, the slack interface just feels kinda clunky. There are a lot of "features" which aren't quite optimised, like agent thinking, tool calling, etc. At some point, the overhead of continuing an investigation over Slack becomes higher than just opening a new Claude Code session locally.
I suspect that the future would be about exposing functionality to existing harnesses like Claude Code or Codex, rather than rebuilding those interaction patterns from scratch. I haven't been able to quite visualise what this looks like yet, but I imagine in our case, it would be something along the lines of a Plain webhook triggering a cloud Claude Code session, which we can then continue on locally, etc. What I do know though, is that there's something really powerful about having a single harness with access to all the relevant tools and context.

View File

@@ -84,7 +84,10 @@ const nextConfig = {
const withMDX = createMDX({
options: {
remarkPlugins: ["remark-frontmatter"],
rehypePlugins: [["rehype-pretty-code", rehypePrettyCodeOptions]],
rehypePlugins: [
["rehype-pretty-code", rehypePrettyCodeOptions],
"rehype-slug",
],
},
});

View File

@@ -26,11 +26,13 @@
"react": "19.2.4",
"react-dom": "19.2.4",
"react-syntax-highlighter": "^16.1.1",
"rehype-slug": "^6.0.0",
"remark-frontmatter": "^5.0.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.2.2",
"@tailwindcss/typography": "^0.5.19",
"@types/mdx": "^2.0.13",
"@types/react-syntax-highlighter": "^15.5.13",
"eslint": "^10.2.0",
"eslint-config-next": "16.2.1",

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

173
bun.lock
View File

@@ -1,6 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "autumn",
@@ -84,6 +84,19 @@
"typescript": "^5",
},
},
"apps/mcp-server": {
"name": "@autumn/mcp-server",
"dependencies": {
"@autumn/mcp": "workspace:*",
"@hono/node-server": "^1.19.5",
"hono": "4.12.7",
},
"devDependencies": {
"@types/bun": "^1.2.13",
"@types/node": "^18.19.3",
"typescript": "~5.8.3",
},
},
"apps/sdk-test": {
"name": "sdk-test",
"version": "0.1.0",
@@ -130,11 +143,13 @@
"react": "19.2.4",
"react-dom": "19.2.4",
"react-syntax-highlighter": "^16.1.1",
"rehype-slug": "^6.0.0",
"remark-frontmatter": "^5.0.0",
},
"devDependencies": {
"@tailwindcss/postcss": "^4.2.2",
"@tailwindcss/typography": "^0.5.19",
"@types/mdx": "^2.0.13",
"@types/react-syntax-highlighter": "^15.5.13",
"eslint": "^10.2.0",
"eslint-config-next": "16.2.1",
@@ -230,7 +245,7 @@
"@typescript/native-preview": "catalog:",
"@useautumn/sdk": "workspace:*",
"esbuild-plugin-path-alias": "^1.0.7",
"hono": "^4.7.9",
"hono": "4.12.7",
"next": "^15.2.3",
"react-dom": "^19.1.0",
"tsup": "^8.4.0",
@@ -257,6 +272,24 @@
"name": "@autumn/ksuid",
"version": "1.0.0",
},
"packages/mcp": {
"name": "@autumn/mcp",
"version": "0.0.1",
"dependencies": {
"@autumn/shared": "workspace:*",
"@axiomhq/js": "^1.6.1",
"@mastra/core": "^1.36.0",
"@mastra/mcp": "^1.8.0",
"date-fns": "^4.1.0",
"ioredis": "^5.5.0",
"zod": "^3.25.76",
},
"devDependencies": {
"@types/bun": "^1.2.13",
"@types/node": "^18.19.3",
"typescript": "~5.8.3",
},
},
"packages/openapi": {
"name": "@autumn/openapi",
"version": "1.0.0",
@@ -582,7 +615,7 @@
"@better-auth/core": "1.6.5",
"@better-auth/passkey": "1.6.5",
"@isaacs/brace-expansion": "5.0.1",
"@modelcontextprotocol/sdk": "1.26.0",
"@modelcontextprotocol/sdk": "1.29.0",
"@smithy/config-resolver": "^4.4.0",
"@types/pg": "8.11.10",
"better-auth": "1.6.5",
@@ -617,6 +650,8 @@
"vite-tsconfig-paths": "6.1.1",
},
"packages": {
"@a2a-js/sdk": ["@a2a-js/sdk@0.3.13", "", { "dependencies": { "uuid": "^11.1.0" }, "peerDependencies": { "@bufbuild/protobuf": "^2.10.2", "@grpc/grpc-js": "^1.11.0", "express": "^4.21.2 || ^5.1.0" }, "optionalPeers": ["@bufbuild/protobuf", "@grpc/grpc-js", "express"] }, "sha512-BZr0f9JVNQs3GKOM9xINWCh6OKIJWZFPyqqVqTym5mxO2Eemc6I/0zL7zWnljHzGdaf5aZQyQN5xa6PSH62q+A=="],
"@ai-sdk/anthropic": ["@ai-sdk/anthropic@3.0.78", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-0OY12G20cUt6iU6htpEA1491Oz++NVxZxlmWGX4B7rSbeZ5pnDmOu6YtW9BKzdZlNx5Gn23i6WMxyZFoMKNcgA=="],
"@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.116", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@ai-sdk/provider-utils": "4.0.27", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-k8P17w7Eho5Y4l3tZrYxqQdffkI4xwtl8GCxkZs+JdMWZhyrLLlozqWkKLaWrCSlEYQOeIhEnQLhqQgYYU86Rw=="],
@@ -625,8 +660,18 @@
"@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.27", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw=="],
"@ai-sdk/provider-utils-v5": ["@ai-sdk/provider-utils@3.0.25", "", { "dependencies": { "@ai-sdk/provider": "2.0.3", "@standard-schema/spec": "^1.0.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-CvsRu+32Y8a167s+lrIBtsybvgTHp8j9y+6BeTvLeoW3Q+okw/b4CnNUFOLIXsRaKHQKAH+IHNJPYWywfpw0LA=="],
"@ai-sdk/provider-utils-v6": ["@ai-sdk/provider-utils@4.0.27", "", { "dependencies": { "@ai-sdk/provider": "3.0.10", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.8" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ubkAJ+xODouwtmN1tYlvTPphH1hPOBfZaEQe8U7skGvFAnIRs9PPpsq57bC2+Ky/MB4yzhd6YOsxTAx9sGpazw=="],
"@ai-sdk/provider-v5": ["@ai-sdk/provider@2.0.3", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-h88OPkavHTiN9tMn2l5awAznGB0lXzjcLhgR1/rvjB2zlLprsNxbM2tt6OJsHUxduLC3klq0/eqaSf6fX5XVww=="],
"@ai-sdk/provider-v6": ["@ai-sdk/provider@3.0.10", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-Q3BZ27qfpYqnCYGvE3vt+Qi6LGOF9R5Nmzn+9JoM1lCRsD9mYaIhfJLkSunN48nfGXJ6n+XNV0J/XVpqGQl7Dw=="],
"@ai-sdk/react": ["@ai-sdk/react@3.0.187", "", { "dependencies": { "@ai-sdk/provider-utils": "4.0.27", "ai": "6.0.185", "swr": "^2.2.5", "throttleit": "2.1.0" }, "peerDependencies": { "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1" } }, "sha512-TJBhR18F7BOLj/mBLYoZNZVkQgDc7DBVz2ZyQEecpKnO+EAhdx3QA2q8BnEVqwNlDfOKOa6dr7ka4hU0wy/wDw=="],
"@ai-sdk/ui-utils-v5": ["@ai-sdk/ui-utils@1.2.11", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "@ai-sdk/provider-utils": "2.2.8", "zod-to-json-schema": "^3.24.1" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-3zcwCc8ezzFlwp3ZD15wAPjf2Au4s3vAbKsXQVyhxODHcmu0iyPO2Eua6D/vicq/AUm/BAo60r97O6HU+EI0+w=="],
"@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.1.3", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw=="],
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
@@ -661,6 +706,10 @@
"@autumn/ksuid": ["@autumn/ksuid@workspace:packages/ksuid"],
"@autumn/mcp": ["@autumn/mcp@workspace:packages/mcp"],
"@autumn/mcp-server": ["@autumn/mcp-server@workspace:apps/mcp-server"],
"@autumn/openapi": ["@autumn/openapi@workspace:packages/openapi"],
"@autumn/scripts": ["@autumn/scripts@workspace:scripts"],
@@ -1251,6 +1300,8 @@
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
"@isaacs/ttlcache": ["@isaacs/ttlcache@2.1.5", "", {}, "sha512-VwGZqqjAWPICTmxUZnbpEfO60LhPWzquik+bmyXGY7pYRn6diEvCI5i6Ca+J6o2y4vS73HrpuMTo2dOvUevH8w=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
@@ -1291,6 +1342,16 @@
"@levischuck/tiny-cbor": ["@levischuck/tiny-cbor@0.2.11", "", {}, "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow=="],
"@lukeed/csprng": ["@lukeed/csprng@1.1.0", "", {}, "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA=="],
"@lukeed/uuid": ["@lukeed/uuid@2.0.1", "", { "dependencies": { "@lukeed/csprng": "^1.1.0" } }, "sha512-qC72D4+CDdjGqJvkFMMEAtancHUQ7/d/tAiHf64z8MopFDmcrtbcJuerDtFceuAfQJ2pDSfCKCtbqoGBNnwg0w=="],
"@mastra/core": ["@mastra/core@1.36.0", "", { "dependencies": { "@a2a-js/sdk": "~0.3.13", "@ai-sdk/provider-utils-v5": "npm:@ai-sdk/provider-utils@3.0.25", "@ai-sdk/provider-utils-v6": "npm:@ai-sdk/provider-utils@4.0.27", "@ai-sdk/provider-v5": "npm:@ai-sdk/provider@2.0.3", "@ai-sdk/provider-v6": "npm:@ai-sdk/provider@3.0.10", "@ai-sdk/ui-utils-v5": "npm:@ai-sdk/ui-utils@1.2.11", "@isaacs/ttlcache": "^2.1.4", "@lukeed/uuid": "^2.0.1", "@mastra/schema-compat": "1.2.10", "@modelcontextprotocol/sdk": "^1.29.0", "@sindresorhus/slugify": "^2.2.1", "@standard-schema/spec": "^1.1.0", "ajv": "^8.18.0", "chat": "^4.29.0", "croner": "^10.0.1", "dotenv": "^17.3.1", "execa": "^9.6.1", "fastq": "^1.19.1", "gray-matter": "^4.0.3", "hono": "^4.12.8", "hono-openapi": "^1.3.0", "ignore": "^7.0.5", "json-schema": "^0.4.0", "lru-cache": "^11.2.7", "p-map": "^7.0.4", "p-retry": "^7.1.1", "picomatch": "^4.0.3", "posthog-node": "^5.30.6", "tokenx": "^1.3.0", "ws": "^8.20.0", "xxhash-wasm": "^1.1.0" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-BEhDZPQeDcJ6jQRHtpfFLuoRiWAuv9dTCIjeWbXokzwDamI3D9jkyNzpBFJwFwy2S/a4jBTu4+d61nOaP7knTQ=="],
"@mastra/mcp": ["@mastra/mcp@1.8.0", "", { "dependencies": { "@modelcontextprotocol/ext-apps": "^1.7.1", "@modelcontextprotocol/sdk": "^1.29.0", "exit-hook": "^5.1.0", "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "@mastra/core": ">=1.0.0-0 <2.0.0-0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-kA1YhDa/W/ZuhZ/AZpUFuKKFhINSVvLf+hDNmbCZMsM46rYjyqqgQR0xgqNaysCwv3Anta6KqDz8fp6mJ7RyuA=="],
"@mastra/schema-compat": ["@mastra/schema-compat@1.2.10", "", { "dependencies": { "json-schema-to-zod": "^2.7.0", "zod-from-json-schema": "^0.5.2", "zod-from-json-schema-v3": "npm:zod-from-json-schema@^0.0.5", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } }, "sha512-8Fg8PeO7GsRPOrEZAzc5udZgsF9ZDxih5JSoxjgnR79d0ImjKffhcoysPW6wIYXPEZ5i6/QDNR7rCazZZSD5Tg=="],
"@mdx-js/loader": ["@mdx-js/loader@3.1.1", "", { "dependencies": { "@mdx-js/mdx": "^3.0.0", "source-map": "^0.7.0" }, "peerDependencies": { "webpack": ">=5" }, "optionalPeers": ["webpack"] }, "sha512-0TTacJyZ9mDmY+VefuthVshaNIyCGZHJG2fMnGaDttCt8HmjUF7SizlHJpaCDoGnN635nK1wpzfpx/Xx5S4WnQ=="],
"@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="],
@@ -1323,7 +1384,9 @@
"@mishieck/ink-titled-box": ["@mishieck/ink-titled-box@0.3.0", "", { "peerDependencies": { "ink": "^6.0.0", "react": "^19.1.0", "typescript": "^5" } }, "sha512-ugzVH9hixp3hwKfQ8On/qnsrdAxS3y9rTu/aGOFed4zVUvtZyGZNIR4rxAwXult8HKI4vJEh0OM8wib9NPrwUg=="],
"@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.26.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-Y5RmPncpiDtTXDbLKswIJzTqu2hyBKxTNsgKqKclDbhIgg1wgtf1fRuvxgTnRfcnxtvvgbIEcqUOzZrJ6iSReg=="],
"@modelcontextprotocol/ext-apps": ["@modelcontextprotocol/ext-apps@1.7.2", "", { "dependencies": { "@standard-schema/spec": "^1.1.0" }, "peerDependencies": { "@modelcontextprotocol/sdk": "^1.29.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["react", "react-dom"] }, "sha512-OOWKDxdAjYDcgHkmzVzccyyag3FK+jBWPaWu4WvTxFsU4R/cgOX4eep66zPRA5n4v6WfxUNibPyvX4iJ7egYTg=="],
"@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.29.0", "", { "dependencies": { "@hono/node-server": "^1.19.9", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.2.1", "express-rate-limit": "^8.2.1", "hono": "^4.11.4", "jose": "^6.1.3", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.1" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ=="],
"@monaco-editor/loader": ["@monaco-editor/loader@1.7.0", "", { "dependencies": { "state-local": "^1.0.6" } }, "sha512-gIwR1HrJrrx+vfyOhYmCZ0/JcWqG5kbfG7+d3f/C1LXk2EvzAbHSg3MQ5lO2sMlo9izoAZ04shohfKLVT6crVA=="],
@@ -2019,7 +2082,7 @@
"@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="],
"@sindresorhus/slugify": ["@sindresorhus/slugify@2.2.0", "", { "dependencies": { "@sindresorhus/transliterate": "^1.0.0", "escape-string-regexp": "^5.0.0" } }, "sha512-9Vybc/qX8Kj6pxJaapjkFbiUJPk7MAkCh/GFCxIBnnsuYCFPIXKvnLidG8xlepht3i24L5XemUmGtrJ3UWrl6w=="],
"@sindresorhus/slugify": ["@sindresorhus/slugify@2.2.1", "", { "dependencies": { "@sindresorhus/transliterate": "^1.0.0", "escape-string-regexp": "^5.0.0" } }, "sha512-MkngSCRZ8JdSOCHRaYd+D01XhvU3Hjy6MGl06zhOk614hp9EOAp5gIkBeQg7wtmxpitU6eAL4kdiRMcJa2dlrw=="],
"@sindresorhus/transliterate": ["@sindresorhus/transliterate@1.6.0", "", { "dependencies": { "escape-string-regexp": "^5.0.0" } }, "sha512-doH1gimEu3A46VX6aVxpHTeHrytJAG6HgdxntYnCFiIFHEM/ZGpG8KiZGBChchjQmG0XFIBL552kBTjVcMZXwQ=="],
@@ -2119,6 +2182,10 @@
"@stablelib/base64": ["@stablelib/base64@1.0.1", "", {}, "sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ=="],
"@standard-community/standard-json": ["@standard-community/standard-json@0.3.5", "", { "peerDependencies": { "@standard-schema/spec": "^1.0.0", "@types/json-schema": "^7.0.15", "@valibot/to-json-schema": "^1.3.0", "arktype": "^2.1.20", "effect": "^3.16.8", "quansync": "^0.2.11", "sury": "^10.0.0", "typebox": "^1.0.17", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-to-json-schema": "^3.24.5" }, "optionalPeers": ["@valibot/to-json-schema", "arktype", "effect", "sury", "typebox", "valibot", "zod", "zod-to-json-schema"] }, "sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA=="],
"@standard-community/standard-openapi": ["@standard-community/standard-openapi@0.2.9", "", { "peerDependencies": { "@standard-community/standard-json": "^0.3.5", "@standard-schema/spec": "^1.0.0", "arktype": "^2.1.20", "effect": "^3.17.14", "openapi-types": "^12.1.3", "sury": "^10.0.0", "typebox": "^1.0.0", "valibot": "^1.1.0", "zod": "^3.25.0 || ^4.0.0", "zod-openapi": "^4" }, "optionalPeers": ["arktype", "effect", "sury", "typebox", "valibot", "zod", "zod-openapi"] }, "sha512-htj+yldvN1XncyZi4rehbf9kLbu8os2Ke/rfqoZHCMHuw34kiF3LP/yQPdA0tQ940y8nDq3Iou8R3wG+AGGyvg=="],
"@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="],
"@standard-schema/utils": ["@standard-schema/utils@0.3.0", "", {}, "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="],
@@ -2619,6 +2686,8 @@
"@wooorm/starry-night": ["@wooorm/starry-night@3.9.0", "", { "dependencies": { "@types/hast": "^3.0.0", "import-meta-resolve": "^4.0.0", "vscode-oniguruma": "^2.0.0", "vscode-textmate": "^9.0.0" } }, "sha512-LXVGKfYhTuFhoRuPAHz2XolS/J45L4lI/lCSIBugDpklXYDUPrJyA8tk17u7G32fcFaGODJXH/YDwQDfUXdPRw=="],
"@workflow/serde": ["@workflow/serde@4.1.0-beta.2", "", {}, "sha512-8kkeoQKLDaKXefjV5dbhBj2aErfKp1Mc4pb6tj8144cF+Em5SPbyMbyLCHp+BVrFfFVCBluCtMx+jjvaFVZGww=="],
"@xtuc/ieee754": ["@xtuc/ieee754@1.2.0", "", {}, "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA=="],
"@xtuc/long": ["@xtuc/long@4.2.2", "", {}, "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="],
@@ -2927,6 +2996,8 @@
"charset": ["charset@1.0.1", "", {}, "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg=="],
"chat": ["chat@4.29.0", "", { "dependencies": { "@workflow/serde": "4.1.0-beta.2", "mdast-util-to-string": "^4.0.0", "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "remend": "^1.2.1", "unified": "^11.0.5" }, "peerDependencies": { "ai": "^6.0.182", "zod": "^3.0.0 || ^4.0.0" }, "optionalPeers": ["ai", "zod"] }, "sha512-KdPfzaie5ivYytyRICTERg5xT+LeCbYefokvNAqTHe92eqkFaoTMXXkSitikxJVWhZIb2YoXF1b9UZHyzSzKzw=="],
"check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="],
"checkout": ["checkout@workspace:apps/checkout"],
@@ -3071,6 +3142,8 @@
"cron-parser": ["cron-parser@4.9.0", "", { "dependencies": { "luxon": "^3.2.1" } }, "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q=="],
"croner": ["croner@10.0.1", "", {}, "sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g=="],
"cronstrue": ["cronstrue@2.61.0", "", { "bin": { "cronstrue": "bin/cli.js" } }, "sha512-ootN5bvXbIQI9rW94+QsXN5eROtXWwew6NkdGxIRpS/UFWRggL0G5Al7a9GTBFEsuvVhJ2K3CntIIVt7L2ILhA=="],
"cross-env": ["cross-env@7.0.3", "", { "dependencies": { "cross-spawn": "^7.0.1" }, "bin": { "cross-env": "src/bin/cross-env.js", "cross-env-shell": "src/bin/cross-env-shell.js" } }, "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw=="],
@@ -3509,6 +3582,8 @@
"execa": ["execa@9.6.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.6", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.1", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.2.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.1.1" } }, "sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA=="],
"exit-hook": ["exit-hook@5.1.0", "", {}, "sha512-INjr2xyxHo7bhAqf5ong++GZPPnpcuBcaXUKt03yf7Fie9yWD7FapL4teOU0+awQazGs5ucBh7xWs/AD+6nhog=="],
"expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
"expr-eval-fork": ["expr-eval-fork@3.0.3", "", {}, "sha512-BhC+hbc5lIVjygr840n5DEkW3MQq7H9o+mc1/N7Z5uIiCFVyESLL5DIE7LNq4CYUNxy+XjA+3jRrL/h0Kt2xcg=="],
@@ -3689,7 +3764,7 @@
"get-stdin": ["get-stdin@9.0.0", "", {}, "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA=="],
"get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
"get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
"get-symbol-description": ["get-symbol-description@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" } }, "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg=="],
@@ -3703,6 +3778,8 @@
"github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
"glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
@@ -3769,6 +3846,8 @@
"hast-util-has-property": ["hast-util-has-property@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA=="],
"hast-util-heading-rank": ["hast-util-heading-rank@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA=="],
"hast-util-is-body-ok-link": ["hast-util-is-body-ok-link@3.0.1", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ=="],
"hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="],
@@ -3819,6 +3898,8 @@
"hono": ["hono@4.12.7", "", {}, "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw=="],
"hono-openapi": ["hono-openapi@1.3.0", "", { "peerDependencies": { "@hono/standard-validator": "^0.2.0", "@standard-community/standard-json": "^0.3.5", "@standard-community/standard-openapi": "^0.2.9", "@types/json-schema": "^7.0.15", "hono": "^4.8.3", "openapi-types": "^12.1.3" }, "optionalPeers": ["@hono/standard-validator", "hono"] }, "sha512-xDvCWpWEIv0weEmnl3EjRQzqbHIO8LnfzMuYOCmbuyE5aes6aXxLg4vM3ybnoZD5TiTUkA6PuRQPJs3R7WRBig=="],
"hono-rate-limiter": ["hono-rate-limiter@0.4.2", "", { "peerDependencies": { "hono": "^4.1.1" } }, "sha512-AAtFqgADyrmbDijcRTT/HJfwqfvhalya2Zo+MgfdrMPas3zSMD8SU03cv+ZsYwRU1swv7zgVt0shwN059yzhjw=="],
"hosted-git-info": ["hosted-git-info@5.2.1", "", { "dependencies": { "lru-cache": "^7.5.1" } }, "sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw=="],
@@ -4025,7 +4106,7 @@
"is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="],
"is-plain-obj": ["is-plain-obj@2.1.0", "", {}, "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="],
"is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
"is-plain-object": ["is-plain-object@5.0.0", "", {}, "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="],
@@ -4043,7 +4124,7 @@
"is-shared-array-buffer": ["is-shared-array-buffer@1.0.4", "", { "dependencies": { "call-bound": "^1.0.3" } }, "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A=="],
"is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
"is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="],
"is-string": ["is-string@1.1.1", "", { "dependencies": { "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" } }, "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA=="],
@@ -4115,6 +4196,8 @@
"json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "ts-algebra": "^2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="],
"json-schema-to-zod": ["json-schema-to-zod@2.8.1", "", { "bin": { "json-schema-to-zod": "dist/cjs/cli.js" } }, "sha512-fRr1mHgZ7hboLKBUdR428gd9dIHUFGivUqOeiDcSmyXkNZCtB1uGaZLvsjZ4GaN5pwBIs+TGIOf6s+Rp5/R/zA=="],
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="],
@@ -4679,7 +4762,7 @@
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
"p-map": ["p-map@5.5.0", "", { "dependencies": { "aggregate-error": "^4.0.0" } }, "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg=="],
"p-map": ["p-map@7.0.4", "", {}, "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ=="],
"p-queue": ["p-queue@6.6.2", "", { "dependencies": { "eventemitter3": "^4.0.4", "p-timeout": "^3.2.0" } }, "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ=="],
@@ -4913,6 +4996,8 @@
"qs": ["qs@6.15.2", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw=="],
"quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="],
"query-selector-shadow-dom": ["query-selector-shadow-dom@1.0.1", "", {}, "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw=="],
"query-string": ["query-string@9.3.1", "", { "dependencies": { "decode-uri-component": "^0.4.1", "filter-obj": "^5.1.0", "split-on-first": "^3.0.0" } }, "sha512-5fBfMOcDi5SA9qj5jZhWAcTtDfKF5WFdd2uD9nVNlbxVv1baq65aALy6qofpNEGELHvisjjasxQp7BlM9gvMzw=="],
@@ -5049,6 +5134,8 @@
"rehype-sanitize": ["rehype-sanitize@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-sanitize": "^5.0.0" } }, "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg=="],
"rehype-slug": ["rehype-slug@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "github-slugger": "^2.0.0", "hast-util-heading-rank": "^3.0.0", "hast-util-to-string": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A=="],
"rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="],
"remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="],
@@ -5503,6 +5590,8 @@
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"tokenx": ["tokenx@1.3.0", "", {}, "sha512-NLdXTEZkKiO0gZuLtMoZKjCXTREXeZZt8nnnNeyoXtNZAfG/GKGSbQtLU5STspc0rMSwcA+UJfWZkbNU01iKmQ=="],
"touch": ["touch@3.1.1", "", { "bin": { "nodetouch": "bin/nodetouch.js" } }, "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA=="],
"tough-cookie": ["tough-cookie@5.1.2", "", { "dependencies": { "tldts": "^6.1.32" } }, "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A=="],
@@ -5795,6 +5884,8 @@
"xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
"xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="],
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
@@ -5829,6 +5920,10 @@
"zod-error": ["zod-error@1.5.0", "", { "dependencies": { "zod": "^3.20.2" } }, "sha512-zzopKZ/skI9iXpqCEPj+iLCKl9b88E43ehcU+sbRoHuwGd9F1IDVGQ70TyO6kmfiRL1g4IXkjsXK+g1gLYl4WQ=="],
"zod-from-json-schema": ["zod-from-json-schema@0.5.2", "", { "dependencies": { "zod": "^4.0.17" } }, "sha512-/dNaicfdhJTOuUd4RImbLUE2g5yrSzzDjI/S6C2vO2ecAGZzn9UcRVgtyLSnENSmAOBRiSpUdzDS6fDWX3Z35g=="],
"zod-from-json-schema-v3": ["zod-from-json-schema@0.0.5", "", { "dependencies": { "zod": "^3.24.2" } }, "sha512-zYEoo86M1qpA1Pq6329oSyHLS785z/mTwfr9V1Xf/ZLhuuBGaMlDGu/pDVGVUe4H4oa1EFgWZT53DP0U3oT9CQ=="],
"zod-openapi": ["zod-openapi@5.4.6", "", { "peerDependencies": { "zod": "^3.25.74 || ^4.0.0" } }, "sha512-P2jsOOBAq/6hCwUsMCjUATZ8szkMsV5VAwZENfyxp2Hc/XPJQpVwAgevWZc65xZauCwWB9LAn7zYeiCJFAEL+A=="],
"zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="],
@@ -5839,6 +5934,12 @@
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"@ai-sdk/provider-utils-v5/@ai-sdk/provider": ["@ai-sdk/provider@2.0.3", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-h88OPkavHTiN9tMn2l5awAznGB0lXzjcLhgR1/rvjB2zlLprsNxbM2tt6OJsHUxduLC3klq0/eqaSf6fX5XVww=="],
"@ai-sdk/ui-utils-v5/@ai-sdk/provider": ["@ai-sdk/provider@1.1.3", "", { "dependencies": { "json-schema": "^0.4.0" } }, "sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg=="],
"@ai-sdk/ui-utils-v5/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@2.2.8", "", { "dependencies": { "@ai-sdk/provider": "1.1.3", "nanoid": "^3.3.8", "secure-json-parse": "^2.7.0" }, "peerDependencies": { "zod": "^3.23.8" } }, "sha512-fqhG+4sCVv8x7nFzYnFo19ryhAa3w096Kmc3hWxMQfW/TubPOmt3A6tYZhl4mUfQWWQMsuSkLrtjlWuXBVSGQA=="],
"@antfu/install-pkg/tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="],
"@antfu/ni/ansis": ["ansis@4.3.0", "", {}, "sha512-44mvgtPvohuU/70DdY5Oz2AIrLJ9k6/5x4KmoSvPwO+5Moijo0+N9D0fKbbYZQWP1hNm5CpOf+E01jhxG/r8xg=="],
@@ -5861,6 +5962,14 @@
"@asyncapi/parser/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="],
"@autumn/mcp/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@autumn/mcp/typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"@autumn/mcp-server/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@autumn/mcp-server/typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"@autumn/openapi/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="],
"@autumn/server/@types/node": ["@types/node@25.8.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-TCFSk8IZh+iLX1xtksoBVtdmgL+1IX0fC9BeU4QqFSuNdN/K+HUlhqOzEmSYYpZUVsLYcPqc9KX+60iDuninSQ=="],
@@ -6097,6 +6206,12 @@
"@langchain/langgraph-sdk/uuid": ["uuid@13.0.2", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-vzi9uRZ926x4XV73S/4qQaTwPXM2JBj6/6lI/byHH1jOpCzb0zDbfytgA9LcN/hzb2l7WQSQnxITOVx5un/wGw=="],
"@mastra/core/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="],
"@mastra/core/hono": ["hono@4.12.22", "", {}, "sha512-7fvVPbB92zNRsQke+uiRGwtTuef0tB2Dg4hWxYfFNvkQhIltWoyi0ONReM5LWA+jJWS3nfT5lTq+qbsIpX0IQw=="],
"@mastra/core/p-retry": ["p-retry@7.1.1", "", { "dependencies": { "is-network-error": "^1.1.0" } }, "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w=="],
"@mermaid-js/parser/@chevrotain/types": ["@chevrotain/types@11.1.2", "", {}, "sha512-U+HFai5+zmJCkK86QsaJtoITlboZHBqrVketcO2ROv865xfCMSFpELQoz1GkX5GzME8pTa+3kbKrZHQtI0gdbw=="],
"@mintlify/cli/@inquirer/prompts": ["@inquirer/prompts@7.9.0", "", { "dependencies": { "@inquirer/checkbox": "^4.3.0", "@inquirer/confirm": "^5.1.19", "@inquirer/editor": "^4.2.21", "@inquirer/expand": "^4.0.21", "@inquirer/input": "^4.2.5", "@inquirer/number": "^3.0.21", "@inquirer/password": "^4.0.21", "@inquirer/rawlist": "^4.1.9", "@inquirer/search": "^3.2.0", "@inquirer/select": "^4.4.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-X7/+dG9SLpSzRkwgG5/xiIzW0oMrV3C0HOa7YHG1WnrLK+vCQHfte4k/T80059YBdei29RBC3s+pSMvPJDU9/A=="],
@@ -6125,6 +6240,8 @@
"@mintlify/cli/zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
"@mintlify/common/@sindresorhus/slugify": ["@sindresorhus/slugify@2.2.0", "", { "dependencies": { "@sindresorhus/transliterate": "^1.0.0", "escape-string-regexp": "^5.0.0" } }, "sha512-9Vybc/qX8Kj6pxJaapjkFbiUJPk7MAkCh/GFCxIBnnsuYCFPIXKvnLidG8xlepht3i24L5XemUmGtrJ3UWrl6w=="],
"@mintlify/common/acorn": ["acorn@8.11.2", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w=="],
"@mintlify/common/hast-util-to-html": ["hast-util-to-html@9.0.4", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^6.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA=="],
@@ -6845,6 +6962,8 @@
"ava/ignore-by-default": ["ignore-by-default@2.1.0", "", {}, "sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw=="],
"ava/p-map": ["p-map@5.5.0", "", { "dependencies": { "aggregate-error": "^4.0.0" } }, "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg=="],
"ava/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
"better-auth/@better-auth/telemetry": ["@better-auth/telemetry@1.6.5", "", { "peerDependencies": { "@better-auth/core": "^1.6.5", "@better-auth/utils": "0.4.0", "@better-fetch/fetch": "1.1.21" } }, "sha512-Ag3CjAP+tLretKPq+pYdU/gU4pFIcey/AoNQzw671wV5JQZXrMitS65INi8j8QuYfol2xgQrht5KVlcxGrkhHQ=="],
@@ -6859,6 +6978,8 @@
"better-call/set-cookie-parser": ["set-cookie-parser@3.1.0", "", {}, "sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw=="],
"better-call/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
"better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="],
"bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
@@ -6875,8 +6996,6 @@
"c12/pkg-types": ["pkg-types@2.3.1", "", { "dependencies": { "confbox": "^0.2.4", "exsolve": "^1.0.8", "pathe": "^2.0.3" } }, "sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg=="],
"cacheable-request/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
"cacheable-request/mimic-response": ["mimic-response@4.0.0", "", {}, "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg=="],
"camelcase-keys/camelcase": ["camelcase@7.0.1", "", {}, "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw=="],
@@ -6885,6 +7004,8 @@
"camelcase-keys/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="],
"chat/remend": ["remend@1.3.0", "", {}, "sha512-iIhggPkhW3hFImKtB10w0dz4EZbs28mV/dmbcYVonWEJ6UGHHpP+bFZnTh6GNWJONg5m+U56JrL+8IxZRdgWjw=="],
"checkout/@tanstack/react-query": ["@tanstack/react-query@5.100.11", "", { "dependencies": { "@tanstack/query-core": "5.100.11" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-J0f9s5x3LE1450nNNfYx+e/n0DMa0uOBdFJUy5r0RvmsXd4nB/n0rbHtHI1vYXhikNFan+wf51p6Tmp4c8ucrg=="],
"checkout/@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
@@ -7031,16 +7152,12 @@
"execa/figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="],
"execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="],
"execa/is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
"execa/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="],
"execa/pretty-ms": ["pretty-ms@9.3.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ=="],
"express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"favicons/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="],
@@ -7413,6 +7530,8 @@
"sync-content/path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
"tempy/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
"tempy/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="],
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
@@ -7455,8 +7574,6 @@
"unbzip2-stream/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
"unified/is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
"webpack/eslint-scope": ["eslint-scope@5.1.1", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw=="],
"whatwg-encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
@@ -7581,6 +7698,14 @@
"yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"yargs-unparser/is-plain-obj": ["is-plain-obj@2.1.0", "", {}, "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="],
"zod-from-json-schema/zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
"@ai-sdk/ui-utils-v5/@ai-sdk/provider-utils/nanoid": ["nanoid@3.3.12", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ=="],
"@ai-sdk/ui-utils-v5/@ai-sdk/provider-utils/secure-json-parse": ["secure-json-parse@2.7.0", "", {}, "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="],
"@anthropic-ai/sdk/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@artilleryio/int-core/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
@@ -7593,6 +7718,10 @@
"@asyncapi/parser/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"@autumn/mcp-server/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@autumn/mcp/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@autumn/server/@types/node/undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
"@autumn/server/@typescript/native-preview/@typescript/native-preview-darwin-arm64": ["@typescript/native-preview-darwin-arm64@7.0.0-dev.20260511.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-SYrqVOlapDxDG7FzHBIJbfgaix+mXPkYzYGqwpz/TAhoPA7sgbfAoGLaqi3ut9N88C/OYNhEX4tjz/0PC9i1nw=="],
@@ -8255,6 +8384,8 @@
"@trigger.dev/core/execa/human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="],
"@trigger.dev/core/execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="],
"@trigger.dev/core/execa/npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="],
"@trigger.dev/core/execa/strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="],
@@ -8453,8 +8584,6 @@
"c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
"cacheable-request/get-stream/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="],
"checkout/@tanstack/react-query/@tanstack/query-core": ["@tanstack/query-core@5.100.11", "", {}, "sha512-lmE0994apShXPj8CUxgx4ch5yUJhE9k/+tVwihBvPOyerACWdBocfFg24t8+0RhtlTd7tEgchDkhlCxNssvDxw=="],
"checkout/react-dom/scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
@@ -9413,6 +9542,8 @@
"msw/tough-cookie/tldts/tldts-core": ["tldts-core@7.0.30", "", {}, "sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q=="],
"ngrok/got/cacheable-request/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
"ngrok/got/cacheable-request/keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
"ngrok/got/cacheable-request/normalize-url": ["normalize-url@6.1.0", "", {}, "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="],

View File

@@ -11,9 +11,11 @@ COPY shared/package.json ./shared/package.json
COPY vite/package.json ./vite/package.json
COPY scripts/package.json ./scripts/package.json
COPY apps/checkout/package.json ./apps/checkout/package.json
COPY apps/mcp-server/package.json ./apps/mcp-server/package.json
COPY packages/autumn-js/package.json ./packages/autumn-js/package.json
COPY packages/atmn/package.json ./packages/atmn/package.json
COPY packages/atmn-tests/package.json ./packages/atmn-tests/package.json
COPY packages/mcp/package.json ./packages/mcp/package.json
COPY packages/openapi/package.json ./packages/openapi/package.json
COPY packages/ksuid/package.json ./packages/ksuid/package.json
COPY packages/stripe-sync/package.json ./packages/stripe-sync/package.json
@@ -32,4 +34,4 @@ ENV NODE_ENV=production
EXPOSE 8080
WORKDIR /app/server
CMD ["bun", "start"]
CMD ["bun", "start"]

View File

@@ -14,6 +14,7 @@
"ignoreWorkspaces": [
"packages/atmn",
"packages/autumn-js",
"packages/mcp",
"packages/openapi",
"packages/sdk"
],

View File

@@ -3,6 +3,35 @@ info:
title: CodeSamples overlay for python target
version: 0.0.0
actions:
- target: $["paths"]["/v1/balances.batch_track"]["post"]
update:
x-codeSamples:
- lang: python
label: Python (SDK)
source: |-
from autumn_sdk import Autumn
with Autumn(
x_api_version="2.3.0",
secret_key="<YOUR_BEARER_TOKEN_HERE>",
) as autumn:
res = autumn.batch_track(request=[
{
"customer_id": "cus_123",
"feature_id": "messages",
"value": 1,
},
{
"customer_id": "cus_123",
"event_name": "message.sent",
"value": 1,
},
])
# Handle response
print(res)
- target: $["paths"]["/v1/balances.check"]["post"]
update:
x-codeSamples:

View File

@@ -1,16 +1,16 @@
lockVersion: 2.0.0
id: 05940b80-1ef8-40f4-9878-822fb2792070
management:
docChecksum: f7445cb18c3f49c563032c18efee5a5e
docChecksum: e59e2727a19a8da7d72e098250662df0
docVersion: 2.3.0
speakeasyVersion: 1.762.0
generationVersion: 2.882.0
releaseVersion: 0.4.18
configChecksum: 2263d20254e354a1792248274002f650
persistentEdits:
generation_id: e37d7642-1d8b-4556-bb09-4e747cc0ecaf
pristine_commit_hash: aef17ce6561fe32d616dbb634223326f7aaee97f
pristine_tree_hash: c4c3e69e2fa148b268b701bbf97cf7c7d57bf3a0
generation_id: 8f470814-b251-45fc-81da-9aeae1e53fd6
pristine_commit_hash: 4545f0867e5974ed781c39f7cd40499b847df4ad
pristine_tree_hash: 0ecaf916b2aa009b294d42e1b386ae63816281c2
features:
python:
additionalDependencies: 1.0.0
@@ -149,8 +149,8 @@ trackedFiles:
pristine_git_object: 278b7f044f6b8e69ba9eb7ebc9d584425b0b758c
docs/models/attachcustomize.md:
id: 46261b03538b
last_write_checksum: sha1:67d5fa5d5011b9b04d808d58cb035965e9887564
pristine_git_object: bb3b56918489eb41dba5b829faf6efb9c2d166ef
last_write_checksum: sha1:4f3c1fd2b4970bddaa38509af6e3646c9c933b28
pristine_git_object: 89a080e3fd956f37d61ce07b2f41311edb8a35d0
docs/models/attachcustomlineitem.md:
id: 0a326be0f45d
last_write_checksum: sha1:1313d34f2ebb0fa8639087ed4da5edb8409ac5e5
@@ -327,6 +327,18 @@ trackedFiles:
id: 75c2cae544fe
last_write_checksum: sha1:09514e05b48bd58bd5f6a2bd6f33ba3f0b0ad957
pristine_git_object: 15b56e6a26511479ac90168ff02e708073684ad4
docs/models/batchtrackglobals.md:
id: fe146d5084f5
last_write_checksum: sha1:dad5e1556005f32abfb04c412c12bf0fbe7acc8c
pristine_git_object: 0e3543480265c6f6b3149c96816c6840123a9a1d
docs/models/batchtracklock.md:
id: 2ff96b3d9148
last_write_checksum: sha1:9ca761f1a5be6b3a3bb4d37c09efa7c521dbd35d
pristine_git_object: d1ecf0c99cf3005a8c86ad2a2904a1248260ffcd
docs/models/batchtrackresponse.md:
id: eb0338f653a0
last_write_checksum: sha1:18803a76985fc522a0cee96fd0bef3b910a8cb3f
pristine_git_object: 20dbbdc41bde67e521b8d043106d0767107dc55d
docs/models/billingbehavior.md:
id: 9c13c728c39d
last_write_checksum: sha1:5f00dce737f1449f727ee694ea6895d4822a73d0
@@ -405,8 +417,8 @@ trackedFiles:
pristine_git_object: b84d2bb18ea93dcf6314b5d3193dc413e94e897a
docs/models/billingupdatecustomize.md:
id: 72b14fed6d26
last_write_checksum: sha1:05828b5794d5822030e7a998ff4f6402ef4427af
pristine_git_object: beb0a52ae309e4ef5a0ada3cfc7bac87bb168a0d
last_write_checksum: sha1:48e0604661b2ed1d1cc67982937bfc10b348f667
pristine_git_object: 784b825bdd0d64e7147004f7affb16cf59c1a9c4
docs/models/billingupdatedurationtype.md:
id: fd1bfb929148
last_write_checksum: sha1:4ecc7d22519fc4f6b45ca394942f2e2bb7d6e008
@@ -2049,8 +2061,8 @@ trackedFiles:
pristine_git_object: 0d6ca7bd4d0aff01cfbb4b2d81703523d24b1e6e
docs/models/listentitiesparams.md:
id: a98fa41dacb7
last_write_checksum: sha1:92519d46339ac94f703fab562a52d26eb4b52cc1
pristine_git_object: 0fa5a5d8ee0d78889fb2049b2fe6c69632848b29
last_write_checksum: sha1:63179c73ff1e654f25b6a653706ace3ea7181c8e
pristine_git_object: 347a05bfd65517b8667f37b6cfa7ffb8adc346db
docs/models/listentitiesplan.md:
id: 35b85f6fd4b3
last_write_checksum: sha1:fa8c2a8ef01dfe81b72c9103d38db67585ac55ae
@@ -2617,8 +2629,8 @@ trackedFiles:
pristine_git_object: 0cf337f8ba27ffbb763473c34c1ccbc5a80c7863
docs/models/previewattachcustomize.md:
id: dd921922e55d
last_write_checksum: sha1:39e865730ee30ebcb1028ce24b45a369168bae14
pristine_git_object: 210625977adc46cdb10b8e33f82dbc72568056fe
last_write_checksum: sha1:27806a84bce815d3d141450e7a72007ea6ae7acd
pristine_git_object: f25e31787b5a48fdb939faff476d8d5e5af48d69
docs/models/previewattachcustomlineitem.md:
id: fb31b2febbbe
last_write_checksum: sha1:9ae0c9cd0145f3c867faa845a1ac73bc72c69606
@@ -3077,8 +3089,8 @@ trackedFiles:
pristine_git_object: 41e8d142a8eb87255d707fd3a8d6adde82058735
docs/models/previewupdatecustomize.md:
id: f4f7d5f4d0a3
last_write_checksum: sha1:07c901ba9eaf000fb26d3a0e89a47ee92b14ffa8
pristine_git_object: cbde6a8108400b87da76da6ef4efddf0fd7ca22d
last_write_checksum: sha1:1b1c6aaad3eb5bfd1c1cbea1984b6107298b9c32
pristine_git_object: c0d1278e718fe1a943c665af67d9138cd2632a37
docs/models/previewupdatediscount.md:
id: 0236831b0434
last_write_checksum: sha1:a714b6ae6d0d60d9fdcb50240e4053362b80e9be
@@ -3347,6 +3359,10 @@ trackedFiles:
id: 7a0bc0d8989b
last_write_checksum: sha1:d9f5922703066a3a4cf275d71b75330909c267ac
pristine_git_object: 8cad0f99cc3791479d89b3d78829e851094f11f0
docs/models/requestbody.md:
id: a15f5440d48c
last_write_checksum: sha1:792ae2d550cfbb56888ee2fe6342a0666c83d219
pristine_git_object: 49346d4858b332cd3d0e59f46c4af0116346bf14
docs/models/revenuecat.md:
id: 5418b6373a80
last_write_checksum: sha1:3cfb5781a5762c564d5b48ef1af6cba5db229435
@@ -3441,8 +3457,8 @@ trackedFiles:
pristine_git_object: 4f47f9305eb714597c85dad9a90548975cb89370
docs/models/setuppaymentcustomize.md:
id: a4431aa0e152
last_write_checksum: sha1:64d2a40c746be4ed9af00bb20a53edde4882d120
pristine_git_object: f5c69f6cb39bf1682ec6cfe3b5981b1a6cdd2e7b
last_write_checksum: sha1:739d12674560e19aef807c21b7e80cafe7190867
pristine_git_object: ee1f85ae0c1e8d32905de2a2a6e422ead80084a7
docs/models/setuppaymentcustomlineitem.md:
id: dc000338e2bd
last_write_checksum: sha1:40bdc935299ecb52884fa5b057629c25b71728b1
@@ -3589,8 +3605,8 @@ trackedFiles:
pristine_git_object: f1e697416673e14db7f4890c0e1bfcff448ce2de
docs/models/trackparams.md:
id: 516394b4d7e6
last_write_checksum: sha1:b7f5843914e63232886dcfa5e5e01cdb8040159a
pristine_git_object: 55d736bf4922089b3156933234268f3bfacb3b78
last_write_checksum: sha1:de2ba1651bde025ae48d85c5dadff4f6e5fb0ac2
pristine_git_object: 657c5c186c8a3f13f08ba4bfe9c2a9db468a7595
docs/models/trackreset1.md:
id: 40997136867c
last_write_checksum: sha1:e4f40f572375f9e48785d349612f74c876bd199f
@@ -4125,8 +4141,8 @@ trackedFiles:
pristine_git_object: 9632d9df66ca144a883a6a61092994f90b6b636c
docs/sdks/autumn/README.md:
id: d27c9292a1a3
last_write_checksum: sha1:10fe85a3489ddeb4e769136e5a5d8199901ca6a8
pristine_git_object: 140a3ecb60eafa96438e9b8723a8ac35f688fbcd
last_write_checksum: sha1:eebf60afdb680b0a6f5cd3a56fb67f7c0ee21796
pristine_git_object: d5d6c787a26c2277c28af9873450cfb33bc50130
docs/sdks/balances/README.md:
id: 6ca85866f00d
last_write_checksum: sha1:486057543b5d9ba28039e8c521c6da05b318a378
@@ -4141,8 +4157,8 @@ trackedFiles:
pristine_git_object: 45bb7e0da6bc397921f731c45f2a8bb8e1ecc664
docs/sdks/entities/README.md:
id: a140ac5181b9
last_write_checksum: sha1:ce657711d3d6ba38e92cd3d96964248dffafbabe
pristine_git_object: 51e73e75e6156f7471111069d2a84223089dd56e
last_write_checksum: sha1:ab85b1f4eb774ba87a36f850732043a4c03bba0a
pristine_git_object: 011261888d5a845d108a17b70893a23eadef04fe
docs/sdks/events/README.md:
id: cf45a4390b9b
last_write_checksum: sha1:2291068c2b8ae415d71094b02d38cdac7ad83284
@@ -4217,8 +4233,8 @@ trackedFiles:
pristine_git_object: aaf9171b48544d4e5039a9a210a67350bf2a8e71
src/autumn_sdk/entities.py:
id: 32ba2aa0874c
last_write_checksum: sha1:ced8d05bea86e3c180b1247bd3bbb6c72ed6c2f8
pristine_git_object: 8b05ef6046e2704c45a50c5149774c0aacaa552c
last_write_checksum: sha1:edbf5fd1fcd7d3ba91b86880d0badb2ef7cdd1f5
pristine_git_object: f1462f80caff8fa59f2a55f24d7370166d4923a6
src/autumn_sdk/errors/__init__.py:
id: 242853123cf2
last_write_checksum: sha1:1c4f4e0181a6598b531c2621340548b003df6e2a
@@ -4253,24 +4269,28 @@ trackedFiles:
pristine_git_object: 89560b566073785535643e694c112bedbd3db13d
src/autumn_sdk/models/__init__.py:
id: bcf3802243ff
last_write_checksum: sha1:827d959dcb8d6dd2bfe1f3afadd0ee1e2b0f9f70
pristine_git_object: 3d6f44b9a0b649a6ee82b500a2b7069ac27d9e5d
last_write_checksum: sha1:92533685e939fb502afebedd05da85692029e5c5
pristine_git_object: e8feabc95f366a3197c1572a233ee0f8daf2f38b
src/autumn_sdk/models/aggregateeventsop.py:
id: 01321099f2a5
last_write_checksum: sha1:bbaf78080f665b38e531d2427c787e40ca0635a7
pristine_git_object: 3a4476749ea87675039e23243ed3865d3bdf57ca
src/autumn_sdk/models/attachop.py:
id: ebb59e06476c
last_write_checksum: sha1:8f45e81656acb1f6aefb1f906bc845069637a773
pristine_git_object: b1dc3605a14e938b42f221a8693f0df50ad4492e
last_write_checksum: sha1:1042a36bd58ee6baf9dbde276b5372541f32d414
pristine_git_object: 9fb1b21c640571f3900697599a8311220f0dc8d5
src/autumn_sdk/models/balance.py:
id: a6354d7c4b97
last_write_checksum: sha1:54a4422123d262666370d2e1238d990ef1dba324
pristine_git_object: 10a5b2ae10d0daf7adc5e9f90de4d25665732a62
src/autumn_sdk/models/batchtrackop.py:
id: 5ebcf495dcb3
last_write_checksum: sha1:2b190852c3ee028f1b433c82f57c817ae41ee8c9
pristine_git_object: 4fc065eaa77c761dbe2461c74650a44421522d9b
src/autumn_sdk/models/billingupdateop.py:
id: a2f17c75cfd3
last_write_checksum: sha1:aade53f9ad5783e23c5141426ef05934d252a763
pristine_git_object: 25636ae22d123f0f378d41dc695dba42d18b4bee
last_write_checksum: sha1:486c326c6fa595b324f95d42f1fbfbb4104cce95
pristine_git_object: dc5897507cf0d6d90590cacf99826158d0aed0d9
src/autumn_sdk/models/checkop.py:
id: 31c2f84723c6
last_write_checksum: sha1:7cb0cbbf11f480372aa2c5a3466b07f78e301226
@@ -4369,8 +4389,8 @@ trackedFiles:
pristine_git_object: efb7ae861ed3c85269dea269465c198119fe37fe
src/autumn_sdk/models/listentitiesop.py:
id: 918a05430967
last_write_checksum: sha1:dbcc46f4782eab84662ba8426cadecdae7473927
pristine_git_object: 7fe4e89b0d9c2a6cb6df185e6f0fc995687a4f97
last_write_checksum: sha1:449f3fb97195ee88ead6093f6f2b2e05798d5d7b
pristine_git_object: b2cdd998afdeb5dfdc83210df15f9df4fa5e9ab2
src/autumn_sdk/models/listeventsop.py:
id: 751b0200d91d
last_write_checksum: sha1:a57b8d56c96c341e8572b4395c12209a62ff6b74
@@ -4397,16 +4417,16 @@ trackedFiles:
pristine_git_object: 99032117da3cc10b694f41fd0bc7a0c1f2bd7973
src/autumn_sdk/models/previewattachop.py:
id: 2b361be4bfa8
last_write_checksum: sha1:c3a5206503713084c1438eb00307ded46cdcdac0
pristine_git_object: af3e60dd107681e7b78da218a45bbaf29e43feb7
last_write_checksum: sha1:5093a6f3669c25ec437cc19b3c2ea3e49bac4664
pristine_git_object: 9daad94ae45ae8076da0c89dd3e6bb578e38083a
src/autumn_sdk/models/previewmultiattachop.py:
id: 963ffcd646a4
last_write_checksum: sha1:b8ff436f7435ce227a5426ae9fe5059e08cbef2b
pristine_git_object: 3a0561ab842ec6d09dda0e9bae06e6059c92e75a
src/autumn_sdk/models/previewupdateop.py:
id: 081d5f08508d
last_write_checksum: sha1:dbf17616256e92fb18393f95bd536098ee4b6f7a
pristine_git_object: 346a1eb769186d700e50c3243fdbe09fea9ea251
last_write_checksum: sha1:765e69f7f7f703c8e8e92bfa784221add4b6cba7
pristine_git_object: a2336686fd12de7950079aa5c104ee29e5abe5f6
src/autumn_sdk/models/redeemreferralcodeop.py:
id: 0abd7bfae718
last_write_checksum: sha1:b1a584450f1f79e796dd755a9305dc30a07ed601
@@ -4421,12 +4441,12 @@ trackedFiles:
pristine_git_object: aa686dd6f85ae1e27450392fcfe02527adfe8e61
src/autumn_sdk/models/setuppaymentop.py:
id: 603339ee67e3
last_write_checksum: sha1:150fe20e97a015206cebf298c977e9d5600077fd
pristine_git_object: d8b1e016389672f6e4fd96a20052e645423a2855
last_write_checksum: sha1:46900f03adbb063677a4190d461c0460c470618e
pristine_git_object: 417d43b99b409c1d4e003c593097ac05ec5da795
src/autumn_sdk/models/trackop.py:
id: 2a744315e781
last_write_checksum: sha1:a03320b078d71050927407e1149770bf357bb7ae
pristine_git_object: 6a5c9d1796caf9aab48df3315196337c1c82d028
last_write_checksum: sha1:216a03a195bb90ad24e42f62294a3de606b29142
pristine_git_object: b99b67ec38db2ea46d6a4478ffc3f3d77625be13
src/autumn_sdk/models/updatebalanceop.py:
id: cd80d90d4cae
last_write_checksum: sha1:729cd503f116f20564b7bccc79c60ac1011554f2
@@ -4465,8 +4485,8 @@ trackedFiles:
pristine_git_object: c52c86dd77e753356560ebcf0ee10f8dc46de593
src/autumn_sdk/sdk.py:
id: 9e733b372628
last_write_checksum: sha1:8bc4ad5c8c4c9835ad4b9e584ff4de90af45c135
pristine_git_object: 6a5908ff9c33517ffffdf5a26ad5c22e42941b3d
last_write_checksum: sha1:a51e0822250581aeecd610abcb8207849cd3c73c
pristine_git_object: 19d77062eea9e5010e454d71cb64f137f7001314
src/autumn_sdk/sdkconfiguration.py:
id: e65df2e44fc0
last_write_checksum: sha1:233b710dff940202f00e389e0c8fa6a33f6ae7b4
@@ -5134,4 +5154,14 @@ examples:
responses:
"200":
application/json: {"reward_id": "reward_789", "entitlements_granted": [{"feature_id": "messages", "balance": 100}]}
batchTrack:
speakeasy-default-batch-track:
parameters:
header:
x-api-version: "2.3.0"
requestBody:
application/json: [{"customer_id": "cus_123", "feature_id": "messages", "value": 1}, {"customer_id": "cus_123", "event_name": "message.sent", "value": 1}]
responses:
"202":
application/json: {"success": true}
examplesVersion: 1.0.2

View File

@@ -200,6 +200,7 @@ Use this to gate access before a feature action. Enable sendEvent when you want
* [track](docs/sdks/autumn/README.md#track) - Records usage for a customer feature and returns updated balances.
Use this after an action happens to decrement usage, or send a negative value to credit balance back.
* [batch_track](docs/sdks/autumn/README.md#batch_track) - Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.
### [Balances](docs/sdks/balances/README.md)

View File

@@ -446,6 +446,7 @@ class Entities(BaseSDK):
subscription_status: Optional[models.ListEntitiesSubscriptionStatus] = None,
search: Optional[str] = None,
processors: Optional[List[models.ListEntitiesProcessor]] = None,
customer_id: Optional[str] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
@@ -461,6 +462,7 @@ class Entities(BaseSDK):
:param subscription_status: Filter customer products used for entity hydration and plan matching. Defaults to active and scheduled.
:param search: Search entities by id or name.
:param processors: Filter by parent customer processor type (stripe, revenuecat, vercel).
:param customer_id: Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
@@ -485,6 +487,7 @@ class Entities(BaseSDK):
subscription_status=subscription_status,
search=search,
processors=processors,
customer_id=customer_id,
)
req = self._build_request(
@@ -557,6 +560,7 @@ class Entities(BaseSDK):
subscription_status: Optional[models.ListEntitiesSubscriptionStatus] = None,
search: Optional[str] = None,
processors: Optional[List[models.ListEntitiesProcessor]] = None,
customer_id: Optional[str] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
@@ -572,6 +576,7 @@ class Entities(BaseSDK):
:param subscription_status: Filter customer products used for entity hydration and plan matching. Defaults to active and scheduled.
:param search: Search entities by id or name.
:param processors: Filter by parent customer processor type (stripe, revenuecat, vercel).
:param customer_id: Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
@@ -596,6 +601,7 @@ class Entities(BaseSDK):
subscription_status=subscription_status,
search=search,
processors=processors,
customer_id=customer_id,
)
req = self._build_request_async(

View File

@@ -130,6 +130,16 @@ if TYPE_CHECKING:
Breakdown,
BreakdownTypedDict,
)
from .batchtrackop import (
BatchTrackGlobals,
BatchTrackGlobalsTypedDict,
BatchTrackLock,
BatchTrackLockTypedDict,
BatchTrackResponse,
BatchTrackResponseTypedDict,
RequestBody,
RequestBodyTypedDict,
)
from .billingupdateop import (
BillingUpdateAddItemBillingMethod,
BillingUpdateAddItemExpiryDurationType,
@@ -1895,6 +1905,12 @@ __all__ = [
"BalanceTierBehavior",
"BalanceType",
"BalanceTypedDict",
"BatchTrackGlobals",
"BatchTrackGlobalsTypedDict",
"BatchTrackLock",
"BatchTrackLockTypedDict",
"BatchTrackResponse",
"BatchTrackResponseTypedDict",
"BillingBehavior",
"BillingUpdateAddItemBillingMethod",
"BillingUpdateAddItemExpiryDurationType",
@@ -3150,6 +3166,8 @@ __all__ = [
"ReferralCustomer",
"ReferralCustomerTypedDict",
"ReferralTypedDict",
"RequestBody",
"RequestBodyTypedDict",
"Revenuecat",
"RevenuecatTypedDict",
"Rewards",
@@ -3593,6 +3611,14 @@ _dynamic_imports: dict[str, str] = {
"BalanceTypedDict": ".balance",
"Breakdown": ".balance",
"BreakdownTypedDict": ".balance",
"BatchTrackGlobals": ".batchtrackop",
"BatchTrackGlobalsTypedDict": ".batchtrackop",
"BatchTrackLock": ".batchtrackop",
"BatchTrackLockTypedDict": ".batchtrackop",
"BatchTrackResponse": ".batchtrackop",
"BatchTrackResponseTypedDict": ".batchtrackop",
"RequestBody": ".batchtrackop",
"RequestBodyTypedDict": ".batchtrackop",
"BillingUpdateAddItemBillingMethod": ".billingupdateop",
"BillingUpdateAddItemExpiryDurationType": ".billingupdateop",
"BillingUpdateAddItemOnDecrease": ".billingupdateop",

View File

@@ -926,7 +926,7 @@ class AttachCustomizeTypedDict(TypedDict):
price: NotRequired[Nullable[AttachBasePriceTypedDict]]
r"""Override the base price of the plan. Pass null to remove the base price."""
items: NotRequired[List[AttachItemPlanItemTypedDict]]
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: NotRequired[List[AttachAddItemPlanItemTypedDict]]
r"""Items to add to the plan."""
remove_items: NotRequired[List[AttachPlanItemFilterTypedDict]]
@@ -942,7 +942,7 @@ class AttachCustomize(BaseModel):
r"""Override the base price of the plan. Pass null to remove the base price."""
items: Optional[List[AttachItemPlanItem]] = None
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: Optional[List[AttachAddItemPlanItem]] = None
r"""Items to add to the plan."""

View File

@@ -0,0 +1,175 @@
"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
from __future__ import annotations
from autumn_sdk.types import BaseModel, UNSET_SENTINEL
from autumn_sdk.utils import FieldMetadata, HeaderMetadata, validate_const
import pydantic
from pydantic import model_serializer
from pydantic.functional_validators import AfterValidator
from typing import Any, Dict, Literal, Optional
from typing_extensions import Annotated, NotRequired, TypedDict
class BatchTrackGlobalsTypedDict(TypedDict):
x_api_version: NotRequired[str]
class BatchTrackGlobals(BaseModel):
x_api_version: Annotated[
Optional[str],
pydantic.Field(alias="x-api-version"),
FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
] = "2.3.0"
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["x-api-version"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
class BatchTrackLockTypedDict(TypedDict):
lock_id: str
r"""A unique identifier for this lock. Used to finalize the lock later via balances.finalize."""
enabled: Literal[True]
r"""Must be true to enable locking."""
expires_at: NotRequired[float]
r"""Unix timestamp (ms) when the lock automatically expires and releases the held balance."""
class BatchTrackLock(BaseModel):
lock_id: str
r"""A unique identifier for this lock. Used to finalize the lock later via balances.finalize."""
enabled: Annotated[
Annotated[Literal[True], AfterValidator(validate_const(True))],
pydantic.Field(alias="enabled"),
] = True
r"""Must be true to enable locking."""
expires_at: Optional[float] = None
r"""Unix timestamp (ms) when the lock automatically expires and releases the held balance."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(["expires_at"])
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
class RequestBodyTypedDict(TypedDict):
customer_id: str
r"""The ID of the customer."""
feature_id: NotRequired[str]
r"""The ID of the feature to track usage for. Required if event_name is not provided."""
entity_id: NotRequired[str]
r"""The ID of the entity for entity-scoped balances (e.g., per-seat limits)."""
event_name: NotRequired[str]
r"""Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event."""
value: NotRequired[float]
r"""The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat)."""
properties: NotRequired[Dict[str, Any]]
r"""Additional properties to attach to this usage event."""
async_: NotRequired[bool]
r"""If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information."""
lock: NotRequired[BatchTrackLockTypedDict]
class RequestBody(BaseModel):
customer_id: str
r"""The ID of the customer."""
feature_id: Optional[str] = None
r"""The ID of the feature to track usage for. Required if event_name is not provided."""
entity_id: Optional[str] = None
r"""The ID of the entity for entity-scoped balances (e.g., per-seat limits)."""
event_name: Optional[str] = None
r"""Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event."""
value: Optional[float] = None
r"""The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat)."""
properties: Optional[Dict[str, Any]] = None
r"""Additional properties to attach to this usage event."""
async_: Annotated[Optional[bool], pydantic.Field(alias="async")] = None
r"""If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information."""
lock: Optional[BatchTrackLock] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
[
"feature_id",
"entity_id",
"event_name",
"value",
"properties",
"async",
"lock",
]
)
serialized = handler(self)
m = {}
for n, f in type(self).model_fields.items():
k = f.alias or n
val = serialized.get(k, serialized.get(n))
if val != UNSET_SENTINEL:
if val is not None or k not in optional_fields:
m[k] = val
return m
class BatchTrackResponseTypedDict(TypedDict):
r"""Batch accepted. All items passed synchronous validation. Enqueue is best-effort: partial failures (some items enqueued, some not) are logged server-side and are NOT surfaced in the response body; clients must not retry on 202. See the endpoint description for full partial-failure semantics."""
success: Literal[True]
class BatchTrackResponse(BaseModel):
r"""Batch accepted. All items passed synchronous validation. Enqueue is best-effort: partial failures (some items enqueued, some not) are logged server-side and are NOT surfaced in the response body; clients must not retry on 202. See the endpoint description for full partial-failure semantics."""
success: Annotated[
Annotated[Literal[True], AfterValidator(validate_const(True))],
pydantic.Field(alias="success"),
] = True
try:
BatchTrackLock.model_rebuild()
except NameError:
pass
try:
RequestBody.model_rebuild()
except NameError:
pass
try:
BatchTrackResponse.model_rebuild()
except NameError:
pass

View File

@@ -930,7 +930,7 @@ class BillingUpdateCustomizeTypedDict(TypedDict):
price: NotRequired[Nullable[BillingUpdateBasePriceTypedDict]]
r"""Override the base price of the plan. Pass null to remove the base price."""
items: NotRequired[List[BillingUpdateItemPlanItemTypedDict]]
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: NotRequired[List[BillingUpdateAddItemPlanItemTypedDict]]
r"""Items to add to the plan."""
remove_items: NotRequired[List[BillingUpdatePlanItemFilterTypedDict]]
@@ -946,7 +946,7 @@ class BillingUpdateCustomize(BaseModel):
r"""Override the base price of the plan. Pass null to remove the base price."""
items: Optional[List[BillingUpdateItemPlanItem]] = None
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: Optional[List[BillingUpdateAddItemPlanItem]] = None
r"""Items to add to the plan."""

View File

@@ -100,6 +100,8 @@ class ListEntitiesParamsTypedDict(TypedDict):
r"""Search entities by id or name."""
processors: NotRequired[List[ListEntitiesProcessor]]
r"""Filter by parent customer processor type (stripe, revenuecat, vercel)."""
customer_id: NotRequired[str]
r"""Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get."""
class ListEntitiesParams(BaseModel):
@@ -121,6 +123,9 @@ class ListEntitiesParams(BaseModel):
processors: Optional[List[ListEntitiesProcessor]] = None
r"""Filter by parent customer processor type (stripe, revenuecat, vercel)."""
customer_id: Optional[str] = None
r"""Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get."""
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
@@ -131,6 +136,7 @@ class ListEntitiesParams(BaseModel):
"subscription_status",
"search",
"processors",
"customer_id",
]
)
serialized = handler(self)

View File

@@ -931,7 +931,7 @@ class PreviewAttachCustomizeTypedDict(TypedDict):
price: NotRequired[Nullable[PreviewAttachBasePriceTypedDict]]
r"""Override the base price of the plan. Pass null to remove the base price."""
items: NotRequired[List[PreviewAttachItemPlanItemTypedDict]]
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: NotRequired[List[PreviewAttachAddItemPlanItemTypedDict]]
r"""Items to add to the plan."""
remove_items: NotRequired[List[PreviewAttachPlanItemFilterTypedDict]]
@@ -947,7 +947,7 @@ class PreviewAttachCustomize(BaseModel):
r"""Override the base price of the plan. Pass null to remove the base price."""
items: Optional[List[PreviewAttachItemPlanItem]] = None
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: Optional[List[PreviewAttachAddItemPlanItem]] = None
r"""Items to add to the plan."""

View File

@@ -931,7 +931,7 @@ class PreviewUpdateCustomizeTypedDict(TypedDict):
price: NotRequired[Nullable[PreviewUpdateBasePriceTypedDict]]
r"""Override the base price of the plan. Pass null to remove the base price."""
items: NotRequired[List[PreviewUpdateItemPlanItemTypedDict]]
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: NotRequired[List[PreviewUpdateAddItemPlanItemTypedDict]]
r"""Items to add to the plan."""
remove_items: NotRequired[List[PreviewUpdatePlanItemFilterTypedDict]]
@@ -947,7 +947,7 @@ class PreviewUpdateCustomize(BaseModel):
r"""Override the base price of the plan. Pass null to remove the base price."""
items: Optional[List[PreviewUpdateItemPlanItem]] = None
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: Optional[List[PreviewUpdateAddItemPlanItem]] = None
r"""Items to add to the plan."""

View File

@@ -929,7 +929,7 @@ class SetupPaymentCustomizeTypedDict(TypedDict):
price: NotRequired[Nullable[SetupPaymentBasePriceTypedDict]]
r"""Override the base price of the plan. Pass null to remove the base price."""
items: NotRequired[List[SetupPaymentItemPlanItemTypedDict]]
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: NotRequired[List[SetupPaymentAddItemPlanItemTypedDict]]
r"""Items to add to the plan."""
remove_items: NotRequired[List[SetupPaymentPlanItemFilterTypedDict]]
@@ -945,7 +945,7 @@ class SetupPaymentCustomize(BaseModel):
r"""Override the base price of the plan. Pass null to remove the base price."""
items: Optional[List[SetupPaymentItemPlanItem]] = None
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items."""
r"""Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items."""
add_items: Optional[List[SetupPaymentAddItemPlanItem]] = None
r"""Items to add to the plan."""

View File

@@ -91,6 +91,8 @@ class TrackParamsTypedDict(TypedDict):
r"""The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat)."""
properties: NotRequired[Dict[str, Any]]
r"""Additional properties to attach to this usage event."""
async_: NotRequired[bool]
r"""If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information."""
lock: NotRequired[TrackLockTypedDict]
@@ -113,12 +115,23 @@ class TrackParams(BaseModel):
properties: Optional[Dict[str, Any]] = None
r"""Additional properties to attach to this usage event."""
async_: Annotated[Optional[bool], pydantic.Field(alias="async")] = None
r"""If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information."""
lock: Optional[TrackLock] = None
@model_serializer(mode="wrap")
def serialize_model(self, handler):
optional_fields = set(
["feature_id", "entity_id", "event_name", "value", "properties", "lock"]
[
"feature_id",
"entity_id",
"event_name",
"value",
"properties",
"async",
"lock",
]
)
serialized = handler(self)
m = {}
@@ -521,3 +534,7 @@ try:
TrackLock.model_rebuild()
except NameError:
pass
try:
TrackParams.model_rebuild()
except NameError:
pass

View File

@@ -8,12 +8,22 @@ from .utils.retries import RetryConfig
from autumn_sdk import errors, models, utils
from autumn_sdk._hooks import HookContext, SDKHooks
from autumn_sdk.models import internal
from autumn_sdk.types import OptionalNullable, UNSET
from autumn_sdk.types import BaseModel, OptionalNullable, UNSET
from autumn_sdk.utils.unmarshal_json_response import unmarshal_json_response
import httpx
import importlib
import sys
from typing import Any, Callable, Dict, Mapping, Optional, TYPE_CHECKING, Union, cast
from typing import (
Any,
Callable,
Dict,
List,
Mapping,
Optional,
TYPE_CHECKING,
Union,
cast,
)
import weakref
if TYPE_CHECKING:
@@ -450,6 +460,7 @@ class Autumn(BaseSDK):
event_name: Optional[str] = None,
value: Optional[float] = None,
properties: Optional[Dict[str, Any]] = None,
async_: Optional[bool] = None,
lock: Optional[Union[models.TrackLock, models.TrackLockTypedDict]] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
@@ -466,6 +477,7 @@ class Autumn(BaseSDK):
:param event_name: Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event.
:param value: The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat).
:param properties: Additional properties to attach to this usage event.
:param async_: If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information.
:param lock:
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
@@ -489,6 +501,7 @@ class Autumn(BaseSDK):
event_name=event_name,
value=value,
properties=properties,
async_=async_,
lock=utils.get_pydantic_model(lock, Optional[models.TrackLock]),
)
@@ -562,6 +575,7 @@ class Autumn(BaseSDK):
event_name: Optional[str] = None,
value: Optional[float] = None,
properties: Optional[Dict[str, Any]] = None,
async_: Optional[bool] = None,
lock: Optional[Union[models.TrackLock, models.TrackLockTypedDict]] = None,
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
@@ -578,6 +592,7 @@ class Autumn(BaseSDK):
:param event_name: Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event.
:param value: The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat).
:param properties: Additional properties to attach to this usage event.
:param async_: If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information.
:param lock:
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
@@ -601,6 +616,7 @@ class Autumn(BaseSDK):
event_name=event_name,
value=value,
properties=properties,
async_=async_,
lock=utils.get_pydantic_model(lock, Optional[models.TrackLock]),
)
@@ -664,3 +680,183 @@ class Autumn(BaseSDK):
)
raise errors.AutumnDefaultError("Unexpected response received", http_res)
def batch_track(
self,
*,
request: Union[List[models.RequestBody], List[models.RequestBodyTypedDict]],
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> models.BatchTrackResponse:
r"""Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.
:param request: The request object to send.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
url_variables = None
if timeout_ms is None:
timeout_ms = self.sdk_configuration.timeout_ms
if server_url is not None:
base_url = server_url
else:
base_url = self._get_url(base_url, url_variables)
if not isinstance(request, BaseModel):
request = utils.unmarshal(request, List[models.RequestBody])
request = cast(List[models.RequestBody], request)
req = self._build_request(
method="POST",
path="/v1/balances.batch_track",
base_url=base_url,
url_variables=url_variables,
request=request,
request_body_required=True,
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="application/json",
http_headers=http_headers,
_globals=models.BatchTrackGlobals(
x_api_version=self.sdk_configuration.globals.x_api_version,
),
security=self.sdk_configuration.security,
get_serialized_body=lambda: utils.serialize_request_body(
request, False, False, "json", List[models.RequestBody]
),
allow_empty_value=None,
timeout_ms=timeout_ms,
)
if retries == UNSET:
if self.sdk_configuration.retry_config is not UNSET:
retries = self.sdk_configuration.retry_config
retry_config = None
if isinstance(retries, utils.RetryConfig):
retry_config = (retries, ["429", "500", "502", "503", "504"])
http_res = self.do_request(
hook_ctx=HookContext(
config=self.sdk_configuration,
base_url=base_url or "",
operation_id="batchTrack",
oauth2_scopes=None,
security_source=self.sdk_configuration.security,
),
request=req,
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
if utils.match_response(http_res, "202", "application/json"):
return unmarshal_json_response(models.BatchTrackResponse, http_res)
if utils.match_response(http_res, "4XX", "*"):
http_res_text = utils.stream_to_text(http_res)
raise errors.AutumnDefaultError(
"API error occurred", http_res, http_res_text
)
if utils.match_response(http_res, "5XX", "*"):
http_res_text = utils.stream_to_text(http_res)
raise errors.AutumnDefaultError(
"API error occurred", http_res, http_res_text
)
raise errors.AutumnDefaultError("Unexpected response received", http_res)
async def batch_track_async(
self,
*,
request: Union[List[models.RequestBody], List[models.RequestBodyTypedDict]],
retries: OptionalNullable[utils.RetryConfig] = UNSET,
server_url: Optional[str] = None,
timeout_ms: Optional[int] = None,
http_headers: Optional[Mapping[str, str]] = None,
) -> models.BatchTrackResponse:
r"""Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.
:param request: The request object to send.
:param retries: Override the default retry configuration for this method
:param server_url: Override the default server URL for this method
:param timeout_ms: Override the default request timeout configuration for this method in milliseconds
:param http_headers: Additional headers to set or replace on requests.
"""
base_url = None
url_variables = None
if timeout_ms is None:
timeout_ms = self.sdk_configuration.timeout_ms
if server_url is not None:
base_url = server_url
else:
base_url = self._get_url(base_url, url_variables)
if not isinstance(request, BaseModel):
request = utils.unmarshal(request, List[models.RequestBody])
request = cast(List[models.RequestBody], request)
req = self._build_request_async(
method="POST",
path="/v1/balances.batch_track",
base_url=base_url,
url_variables=url_variables,
request=request,
request_body_required=True,
request_has_path_params=False,
request_has_query_params=True,
user_agent_header="user-agent",
accept_header_value="application/json",
http_headers=http_headers,
_globals=models.BatchTrackGlobals(
x_api_version=self.sdk_configuration.globals.x_api_version,
),
security=self.sdk_configuration.security,
get_serialized_body=lambda: utils.serialize_request_body(
request, False, False, "json", List[models.RequestBody]
),
allow_empty_value=None,
timeout_ms=timeout_ms,
)
if retries == UNSET:
if self.sdk_configuration.retry_config is not UNSET:
retries = self.sdk_configuration.retry_config
retry_config = None
if isinstance(retries, utils.RetryConfig):
retry_config = (retries, ["429", "500", "502", "503", "504"])
http_res = await self.do_request_async(
hook_ctx=HookContext(
config=self.sdk_configuration,
base_url=base_url or "",
operation_id="batchTrack",
oauth2_scopes=None,
security_source=self.sdk_configuration.security,
),
request=req,
is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
retry_config=retry_config,
)
if utils.match_response(http_res, "202", "application/json"):
return unmarshal_json_response(models.BatchTrackResponse, http_res)
if utils.match_response(http_res, "4XX", "*"):
http_res_text = await utils.stream_to_text_async(http_res)
raise errors.AutumnDefaultError(
"API error occurred", http_res, http_res_text
)
if utils.match_response(http_res, "5XX", "*"):
http_res_text = await utils.stream_to_text_async(http_res)
raise errors.AutumnDefaultError(
"API error occurred", http_res, http_res_text
)
raise errors.AutumnDefaultError("Unexpected response received", http_res)

View File

@@ -11,9 +11,11 @@
"apps/checkout",
"apps/docs",
"apps/website",
"apps/mcp-server",
"apps/sdk-test",
"packages/atmn",
"packages/atmn-tests",
"packages/mcp",
"packages/sdk",
"packages/autumn-js",
"packages/openapi",
@@ -49,7 +51,7 @@
"@better-auth/core": "1.6.5",
"@better-auth/passkey": "1.6.5",
"better-auth": "1.6.5",
"@modelcontextprotocol/sdk": "1.26.0",
"@modelcontextprotocol/sdk": "1.29.0",
"@isaacs/brace-expansion": "5.0.1",
"fast-xml-parser": "5.3.4",
"esbuild": "0.25.0",
@@ -63,7 +65,7 @@
"@better-auth/core": "1.6.5",
"@better-auth/passkey": "1.6.5",
"better-auth": "1.6.5",
"@modelcontextprotocol/sdk": "1.26.0",
"@modelcontextprotocol/sdk": "1.29.0",
"@isaacs/brace-expansion": "5.0.1",
"fast-xml-parser": "5.3.4",
"esbuild": "0.25.0",
@@ -123,13 +125,14 @@
"knip:fix-all": "knip --fix --allow-remove-files",
"prepare": "husky",
"api": "cd packages/openapi && bun generate",
"mcp": "bun scripts/mcp.ts",
"svix:push": "infisical run --env=dev --recursive -- bun packages/openapi/scripts/svixPush.ts",
"svix:push:prod": "infisical run --env=prod --recursive -- bun packages/openapi/scripts/svixPush.ts",
"docs:pull": "bun -F @autumn/docs pull",
"site": "cd apps/website && bun dev && cd ../..",
"docs": "bun -F @autumn/docs dev",
"docs:build": "bun -F @autumn/docs build",
"ts": "turbo run ts --filter=@autumn/server --filter=autumn-js --filter=@autumn/openapi --filter=atmn --filter=checkout",
"ts": "turbo run ts --filter=@autumn/server --filter=autumn-js --filter=@autumn/openapi --filter=atmn --filter=checkout --filter=@autumn/mcp --filter=@autumn/mcp-server",
"kill:ts": "while pgrep -f tsgo > /dev/null; do pkill -9 -f tsgo; sleep 0.1; done",
"atmn:build": "bun -F atmn build",
"openapi:ts": "bun -F @autumn/openapi ts",

View File

@@ -107,7 +107,7 @@
"@typescript/native-preview": "catalog:",
"@useautumn/sdk": "workspace:*",
"esbuild-plugin-path-alias": "^1.0.7",
"hono": "^4.7.9",
"hono": "4.12.7",
"next": "^15.2.3",
"react-dom": "^19.1.0",
"tsup": "^8.4.0",

View File

@@ -2,49 +2,64 @@
import { z } from "zod/v4";
export const aggregateEventsGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const aggregateEventsFeatureIdSchema = z.union([z.string(), z.array(z.string())]);
export const aggregateEventsFeatureIdSchema = z.union([
z.string(),
z.array(z.string()),
]);
export const aggregateEventsCustomRangeSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const aggregateEventsListSchema = z.object({
period: z.number(),
values: z.record(z.string(), z.number()),
groupedValues: z.union([z.record(z.string(), z.record(z.string(), z.number())), z.undefined()]).optional()
period: z.number(),
values: z.record(z.string(), z.number()),
groupedValues: z
.union([
z.record(z.string(), z.record(z.string(), z.number())),
z.undefined(),
])
.optional(),
});
export const totalSchema = z.object({
count: z.number(),
sum: z.number()
count: z.number(),
sum: z.number(),
});
export const aggregateEventsResponseSchema = z.object({
list: z.array(aggregateEventsListSchema),
total: z.record(z.string(), totalSchema)
list: z.array(aggregateEventsListSchema),
total: z.record(z.string(), totalSchema),
});
export const aggregateEventsFeatureIdOutboundSchema = z.union([z.string(), z.array(z.string())]);
export const aggregateEventsFeatureIdOutboundSchema = z.union([
z.string(),
z.array(z.string()),
]);
export const aggregateEventsCustomRangeOutboundSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const eventsAggregateParamsOutboundSchema = z.object({
customer_id: z.union([z.string(), z.undefined()]).optional(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
feature_id: z.union([z.string(), z.array(z.string())]),
group_by: z.union([z.string(), z.undefined()]).optional(),
range: z.union([z.string(), z.undefined()]).optional(),
bin_size: z.string(),
custom_range: z.union([aggregateEventsCustomRangeOutboundSchema, z.undefined()]).optional(),
filter_by: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
max_groups: z.union([z.number(), z.undefined()]).optional()
customer_id: z.union([z.string(), z.undefined()]).optional(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
feature_id: z.union([z.string(), z.array(z.string())]),
group_by: z.union([z.string(), z.undefined()]).optional(),
range: z.union([z.string(), z.undefined()]).optional(),
bin_size: z.string(),
custom_range: z
.union([aggregateEventsCustomRangeOutboundSchema, z.undefined()])
.optional(),
filter_by: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
max_groups: z.union([z.number(), z.undefined()]).optional(),
});
const closedEnumSchema = z.any();
@@ -54,13 +69,17 @@ export const rangeSchema = closedEnumSchema;
export const binSizeSchema = closedEnumSchema;
export const eventsAggregateParamsSchema = z.object({
customerId: z.union([z.string(), z.undefined()]).optional(),
entityId: z.union([z.string(), z.undefined()]).optional(),
featureId: z.union([z.string(), z.array(z.string())]),
groupBy: z.union([z.string(), z.undefined()]).optional(),
range: z.union([rangeSchema, z.undefined()]).optional(),
binSize: z.union([binSizeSchema, z.undefined()]).optional(),
customRange: z.union([aggregateEventsCustomRangeSchema, z.undefined()]).optional(),
filterBy: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
maxGroups: z.union([z.number(), z.undefined()]).optional()
customerId: z.union([z.string(), z.undefined()]).optional(),
entityId: z.union([z.string(), z.undefined()]).optional(),
featureId: z.union([z.string(), z.array(z.string())]),
groupBy: z.union([z.string(), z.undefined()]).optional(),
range: z.union([rangeSchema, z.undefined()]).optional(),
binSize: z.union([binSizeSchema, z.undefined()]).optional(),
customRange: z
.union([aggregateEventsCustomRangeSchema, z.undefined()])
.optional(),
filterBy: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
maxGroups: z.union([z.number(), z.undefined()]).optional(),
});

View File

@@ -2,243 +2,283 @@
import { z } from "zod/v4";
export const attachGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const attachFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const attachItemToSchema = z.union([z.number(), z.string()]);
export const attachItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemToSchema = z.union([z.number(), z.string()]);
export const attachAddItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const attachInvoiceModeSchema = z.object({
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional()
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional(),
});
export const attachAttachDiscountSchema = z.object({
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional()
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional(),
});
export const attachCustomLineItemSchema = z.object({
amount: z.number(),
description: z.string()
amount: z.number(),
description: z.string(),
});
export const attachCarryOverBalancesSchema = z.object({
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const attachCarryOverUsagesSchema = z.object({
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const attachInvoiceSchema = z.object({
status: z.string().nullable(),
stripeId: z.string(),
total: z.number(),
currency: z.string(),
hostedInvoiceUrl: z.string().nullable()
status: z.string().nullable(),
stripeId: z.string(),
total: z.number(),
currency: z.string(),
hostedInvoiceUrl: z.string().nullable(),
});
export const attachFeatureQuantityOutboundSchema = z.object({
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const attachBasePriceOutboundSchema = z.object({
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemToOutboundSchema = z.union([z.number(), z.string()]);
export const attachItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(attachItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(attachItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const attachItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([attachItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([attachItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([attachItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([attachItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z
.union([attachItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([attachItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const attachAddItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemToOutboundSchema = z.union([z.number(), z.string()]);
export const attachAddItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(attachAddItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(attachAddItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const attachAddItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachAddItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([attachAddItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([attachAddItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([attachAddItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachAddItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([attachAddItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z
.union([attachAddItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([attachAddItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const attachPlanItemFilterOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional(),
});
export const attachFreeTrialParamsOutboundSchema = z.object({
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional()
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional(),
});
export const attachCustomizeOutboundSchema = z.object({
price: z.union([attachBasePriceOutboundSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(attachItemPlanItemOutboundSchema), z.undefined()]).optional(),
add_items: z.union([z.array(attachAddItemPlanItemOutboundSchema), z.undefined()]).optional(),
remove_items: z.union([z.array(attachPlanItemFilterOutboundSchema), z.undefined()]).optional(),
free_trial: z.union([attachFreeTrialParamsOutboundSchema, z.undefined()]).optional().nullable()
price: z
.union([attachBasePriceOutboundSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(attachItemPlanItemOutboundSchema), z.undefined()])
.optional(),
add_items: z
.union([z.array(attachAddItemPlanItemOutboundSchema), z.undefined()])
.optional(),
remove_items: z
.union([z.array(attachPlanItemFilterOutboundSchema), z.undefined()])
.optional(),
free_trial: z
.union([attachFreeTrialParamsOutboundSchema, z.undefined()])
.optional()
.nullable(),
});
export const attachInvoiceModeOutboundSchema = z.object({
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean()
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean(),
});
export const attachAttachDiscountOutboundSchema = z.object({
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional()
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional(),
});
export const attachCustomLineItemOutboundSchema = z.object({
amount: z.number(),
description: z.string()
amount: z.number(),
description: z.string(),
});
export const attachCarryOverBalancesOutboundSchema = z.object({
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const attachCarryOverUsagesOutboundSchema = z.object({
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const attachParamsOutboundSchema = z.object({
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.string(),
feature_quantities: z.union([z.array(attachFeatureQuantityOutboundSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([attachCustomizeOutboundSchema, z.undefined()]).optional(),
invoice_mode: z.union([attachInvoiceModeOutboundSchema, z.undefined()]).optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(attachAttachDiscountOutboundSchema), z.undefined()]).optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
plan_schedule: z.union([z.string(), z.undefined()]).optional(),
starts_at: z.union([z.number(), z.undefined()]).optional(),
ends_at: z.union([z.number(), z.undefined()]).optional(),
checkout_session_params: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
custom_line_items: z.union([z.array(attachCustomLineItemOutboundSchema), z.undefined()]).optional(),
processor_subscription_id: z.union([z.string(), z.undefined()]).optional(),
carry_over_balances: z.union([attachCarryOverBalancesOutboundSchema, z.undefined()]).optional(),
carry_over_usages: z.union([attachCarryOverUsagesOutboundSchema, z.undefined()]).optional(),
metadata: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
tax_rate_id: z.union([z.string(), z.undefined()]).optional()
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.string(),
feature_quantities: z
.union([z.array(attachFeatureQuantityOutboundSchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([attachCustomizeOutboundSchema, z.undefined()]).optional(),
invoice_mode: z
.union([attachInvoiceModeOutboundSchema, z.undefined()])
.optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(attachAttachDiscountOutboundSchema), z.undefined()])
.optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
plan_schedule: z.union([z.string(), z.undefined()]).optional(),
starts_at: z.union([z.number(), z.undefined()]).optional(),
ends_at: z.union([z.number(), z.undefined()]).optional(),
checkout_session_params: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
custom_line_items: z
.union([z.array(attachCustomLineItemOutboundSchema), z.undefined()])
.optional(),
processor_subscription_id: z.union([z.string(), z.undefined()]).optional(),
carry_over_balances: z
.union([attachCarryOverBalancesOutboundSchema, z.undefined()])
.optional(),
carry_over_usages: z
.union([attachCarryOverUsagesOutboundSchema, z.undefined()])
.optional(),
metadata: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
tax_rate_id: z.union([z.string(), z.undefined()]).optional(),
});
const closedEnumSchema = z.any();
@@ -248,16 +288,16 @@ const openEnumSchema = z.any();
export const attachPriceIntervalSchema = closedEnumSchema;
export const attachBasePriceSchema = z.object({
amount: z.number(),
interval: attachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: attachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemResetIntervalSchema = closedEnumSchema;
export const attachItemResetSchema = z.object({
interval: attachItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: attachItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemTierBehaviorSchema = closedEnumSchema;
@@ -267,14 +307,16 @@ export const attachItemPriceIntervalSchema = closedEnumSchema;
export const attachItemBillingMethodSchema = closedEnumSchema;
export const attachItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(attachItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([attachItemTierBehaviorSchema, z.undefined()]).optional(),
interval: attachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: attachItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(attachItemTierSchema), z.undefined()]).optional(),
tierBehavior: z
.union([attachItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: attachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: attachItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemOnIncreaseSchema = closedEnumSchema;
@@ -282,34 +324,34 @@ export const attachItemOnIncreaseSchema = closedEnumSchema;
export const attachItemOnDecreaseSchema = closedEnumSchema;
export const attachItemProrationSchema = z.object({
onIncrease: attachItemOnIncreaseSchema,
onDecrease: attachItemOnDecreaseSchema
onIncrease: attachItemOnIncreaseSchema,
onDecrease: attachItemOnDecreaseSchema,
});
export const attachItemExpiryDurationTypeSchema = closedEnumSchema;
export const attachItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: attachItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: attachItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const attachItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachItemResetSchema, z.undefined()]).optional(),
price: z.union([attachItemPriceSchema, z.undefined()]).optional(),
proration: z.union([attachItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([attachItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachItemResetSchema, z.undefined()]).optional(),
price: z.union([attachItemPriceSchema, z.undefined()]).optional(),
proration: z.union([attachItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([attachItemRolloverSchema, z.undefined()]).optional(),
});
export const attachAddItemResetIntervalSchema = closedEnumSchema;
export const attachAddItemResetSchema = z.object({
interval: attachAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: attachAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemTierBehaviorSchema = closedEnumSchema;
@@ -319,14 +361,16 @@ export const attachAddItemPriceIntervalSchema = closedEnumSchema;
export const attachAddItemBillingMethodSchema = closedEnumSchema;
export const attachAddItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(attachAddItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([attachAddItemTierBehaviorSchema, z.undefined()]).optional(),
interval: attachAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: attachAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(attachAddItemTierSchema), z.undefined()]).optional(),
tierBehavior: z
.union([attachAddItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: attachAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: attachAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemOnIncreaseSchema = closedEnumSchema;
@@ -334,27 +378,27 @@ export const attachAddItemOnIncreaseSchema = closedEnumSchema;
export const attachAddItemOnDecreaseSchema = closedEnumSchema;
export const attachAddItemProrationSchema = z.object({
onIncrease: attachAddItemOnIncreaseSchema,
onDecrease: attachAddItemOnDecreaseSchema
onIncrease: attachAddItemOnIncreaseSchema,
onDecrease: attachAddItemOnDecreaseSchema,
});
export const attachAddItemExpiryDurationTypeSchema = closedEnumSchema;
export const attachAddItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: attachAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: attachAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const attachAddItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachAddItemResetSchema, z.undefined()]).optional(),
price: z.union([attachAddItemPriceSchema, z.undefined()]).optional(),
proration: z.union([attachAddItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([attachAddItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([attachAddItemResetSchema, z.undefined()]).optional(),
price: z.union([attachAddItemPriceSchema, z.undefined()]).optional(),
proration: z.union([attachAddItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([attachAddItemRolloverSchema, z.undefined()]).optional(),
});
export const attachRemoveItemBillingMethodSchema = closedEnumSchema;
@@ -362,9 +406,11 @@ export const attachRemoveItemBillingMethodSchema = closedEnumSchema;
export const attachRemoveItemIntervalSchema = closedEnumSchema;
export const attachPlanItemFilterSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z.union([attachRemoveItemBillingMethodSchema, z.undefined()]).optional(),
interval: z.union([attachRemoveItemIntervalSchema, z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z
.union([attachRemoveItemBillingMethodSchema, z.undefined()])
.optional(),
interval: z.union([attachRemoveItemIntervalSchema, z.undefined()]).optional(),
});
export const attachDurationTypeSchema = closedEnumSchema;
@@ -372,18 +418,25 @@ export const attachDurationTypeSchema = closedEnumSchema;
export const attachOnEndSchema = closedEnumSchema;
export const attachFreeTrialParamsSchema = z.object({
durationLength: z.number(),
durationType: z.union([attachDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([attachOnEndSchema, z.undefined()]).optional()
durationLength: z.number(),
durationType: z.union([attachDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([attachOnEndSchema, z.undefined()]).optional(),
});
export const attachCustomizeSchema = z.object({
price: z.union([attachBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(attachItemPlanItemSchema), z.undefined()]).optional(),
addItems: z.union([z.array(attachAddItemPlanItemSchema), z.undefined()]).optional(),
removeItems: z.union([z.array(attachPlanItemFilterSchema), z.undefined()]).optional(),
freeTrial: z.union([attachFreeTrialParamsSchema, z.undefined()]).optional().nullable()
price: z.union([attachBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(attachItemPlanItemSchema), z.undefined()]).optional(),
addItems: z
.union([z.array(attachAddItemPlanItemSchema), z.undefined()])
.optional(),
removeItems: z
.union([z.array(attachPlanItemFilterSchema), z.undefined()])
.optional(),
freeTrial: z
.union([attachFreeTrialParamsSchema, z.undefined()])
.optional()
.nullable(),
});
export const attachProrationBehaviorSchema = closedEnumSchema;
@@ -393,45 +446,63 @@ export const attachRedirectModeSchema = closedEnumSchema;
export const attachPlanScheduleSchema = closedEnumSchema;
export const attachParamsSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.string(),
featureQuantities: z.union([z.array(attachFeatureQuantitySchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([attachCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z.union([attachInvoiceModeSchema, z.undefined()]).optional(),
prorationBehavior: z.union([attachProrationBehaviorSchema, z.undefined()]).optional(),
redirectMode: z.union([attachRedirectModeSchema, z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(attachAttachDiscountSchema), z.undefined()]).optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
planSchedule: z.union([attachPlanScheduleSchema, z.undefined()]).optional(),
startsAt: z.union([z.number(), z.undefined()]).optional(),
endsAt: z.union([z.number(), z.undefined()]).optional(),
checkoutSessionParams: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
customLineItems: z.union([z.array(attachCustomLineItemSchema), z.undefined()]).optional(),
processorSubscriptionId: z.union([z.string(), z.undefined()]).optional(),
carryOverBalances: z.union([attachCarryOverBalancesSchema, z.undefined()]).optional(),
carryOverUsages: z.union([attachCarryOverUsagesSchema, z.undefined()]).optional(),
metadata: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
taxRateId: z.union([z.string(), z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.string(),
featureQuantities: z
.union([z.array(attachFeatureQuantitySchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([attachCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z.union([attachInvoiceModeSchema, z.undefined()]).optional(),
prorationBehavior: z
.union([attachProrationBehaviorSchema, z.undefined()])
.optional(),
redirectMode: z.union([attachRedirectModeSchema, z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(attachAttachDiscountSchema), z.undefined()])
.optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
planSchedule: z.union([attachPlanScheduleSchema, z.undefined()]).optional(),
startsAt: z.union([z.number(), z.undefined()]).optional(),
endsAt: z.union([z.number(), z.undefined()]).optional(),
checkoutSessionParams: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
customLineItems: z
.union([z.array(attachCustomLineItemSchema), z.undefined()])
.optional(),
processorSubscriptionId: z.union([z.string(), z.undefined()]).optional(),
carryOverBalances: z
.union([attachCarryOverBalancesSchema, z.undefined()])
.optional(),
carryOverUsages: z
.union([attachCarryOverUsagesSchema, z.undefined()])
.optional(),
metadata: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
taxRateId: z.union([z.string(), z.undefined()]).optional(),
});
export const attachCodeSchema = openEnumSchema;
export const attachRequiredActionSchema = z.object({
code: attachCodeSchema,
reason: z.string()
code: attachCodeSchema,
reason: z.string(),
});
export const attachResponseSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
invoice: z.union([attachInvoiceSchema, z.undefined()]).optional(),
paymentUrl: z.string().nullable(),
requiredAction: z.union([attachRequiredActionSchema, z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
invoice: z.union([attachInvoiceSchema, z.undefined()]).optional(),
paymentUrl: z.string().nullable(),
requiredAction: z
.union([attachRequiredActionSchema, z.undefined()])
.optional(),
});

View File

@@ -2,21 +2,21 @@
import { z } from "zod/v4";
export const createReferralCodeGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const createReferralCodeParamsSchema = z.object({
customerId: z.string(),
programId: z.string()
customerId: z.string(),
programId: z.string(),
});
export const createReferralCodeResponseSchema = z.object({
code: z.string(),
customerId: z.string(),
createdAt: z.number()
code: z.string(),
customerId: z.string(),
createdAt: z.number(),
});
export const createReferralCodeParamsOutboundSchema = z.object({
customer_id: z.string(),
program_id: z.string()
customer_id: z.string(),
program_id: z.string(),
});

View File

@@ -2,82 +2,108 @@
import { z } from "zod/v4";
export const getOrCreateCustomerGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const getOrCreateCustomerSpendLimitSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
overageLimit: z.union([z.number(), z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
overageLimit: z.union([z.number(), z.undefined()]).optional(),
});
export const getOrCreateCustomerOverageAllowedSchema = z.object({
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
});
export const getOrCreateCustomerConfigSchema = z.object({
disablePooledBalance: z.union([z.boolean(), z.undefined()]).optional()
disablePooledBalance: z.union([z.boolean(), z.undefined()]).optional(),
});
export const getOrCreateCustomerPurchaseLimitOutboundSchema = z.object({
interval: z.string(),
interval_count: z.number(),
limit: z.number()
interval: z.string(),
interval_count: z.number(),
limit: z.number(),
});
export const getOrCreateCustomerAutoTopupOutboundSchema = z.object({
feature_id: z.string(),
enabled: z.boolean(),
threshold: z.number(),
quantity: z.number(),
purchase_limit: z.union([getOrCreateCustomerPurchaseLimitOutboundSchema, z.undefined()]).optional(),
invoice_mode: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
enabled: z.boolean(),
threshold: z.number(),
quantity: z.number(),
purchase_limit: z
.union([getOrCreateCustomerPurchaseLimitOutboundSchema, z.undefined()])
.optional(),
invoice_mode: z.union([z.boolean(), z.undefined()]).optional(),
});
export const getOrCreateCustomerSpendLimitOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
overage_limit: z.union([z.number(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
overage_limit: z.union([z.number(), z.undefined()]).optional(),
});
export const getOrCreateCustomerUsageAlertOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
threshold: z.number(),
threshold_type: z.string(),
name: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
threshold: z.number(),
threshold_type: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
});
export const getOrCreateCustomerOverageAllowedOutboundSchema = z.object({
feature_id: z.string(),
enabled: z.boolean()
feature_id: z.string(),
enabled: z.boolean(),
});
export const getOrCreateCustomerBillingControlsOutboundSchema = z.object({
auto_topups: z.union([z.array(getOrCreateCustomerAutoTopupOutboundSchema), z.undefined()]).optional(),
spend_limits: z.union([z.array(getOrCreateCustomerSpendLimitOutboundSchema), z.undefined()]).optional(),
usage_alerts: z.union([z.array(getOrCreateCustomerUsageAlertOutboundSchema), z.undefined()]).optional(),
overage_allowed: z.union([z.array(getOrCreateCustomerOverageAllowedOutboundSchema), z.undefined()]).optional()
auto_topups: z
.union([z.array(getOrCreateCustomerAutoTopupOutboundSchema), z.undefined()])
.optional(),
spend_limits: z
.union([
z.array(getOrCreateCustomerSpendLimitOutboundSchema),
z.undefined(),
])
.optional(),
usage_alerts: z
.union([
z.array(getOrCreateCustomerUsageAlertOutboundSchema),
z.undefined(),
])
.optional(),
overage_allowed: z
.union([
z.array(getOrCreateCustomerOverageAllowedOutboundSchema),
z.undefined(),
])
.optional(),
});
export const getOrCreateCustomerConfigOutboundSchema = z.object({
disable_pooled_balance: z.union([z.boolean(), z.undefined()]).optional()
disable_pooled_balance: z.union([z.boolean(), z.undefined()]).optional(),
});
export const getOrCreateCustomerParamsOutboundSchema = z.object({
customer_id: z.string().nullable(),
name: z.union([z.string(), z.undefined()]).optional().nullable(),
email: z.union([z.string(), z.undefined()]).optional().nullable(),
fingerprint: z.union([z.string(), z.undefined()]).optional().nullable(),
metadata: z.union([z.record(z.string(), z.any()), z.undefined()]).optional().nullable(),
stripe_id: z.union([z.string(), z.undefined()]).optional().nullable(),
create_in_stripe: z.union([z.boolean(), z.undefined()]).optional(),
auto_enable_plan_id: z.union([z.string(), z.undefined()]).optional(),
send_email_receipts: z.union([z.boolean(), z.undefined()]).optional(),
billing_controls: z.union([getOrCreateCustomerBillingControlsOutboundSchema, z.undefined()]).optional(),
config: z.union([getOrCreateCustomerConfigOutboundSchema, z.undefined()]).optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional()
customer_id: z.string().nullable(),
name: z.union([z.string(), z.undefined()]).optional().nullable(),
email: z.union([z.string(), z.undefined()]).optional().nullable(),
fingerprint: z.union([z.string(), z.undefined()]).optional().nullable(),
metadata: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional()
.nullable(),
stripe_id: z.union([z.string(), z.undefined()]).optional().nullable(),
create_in_stripe: z.union([z.boolean(), z.undefined()]).optional(),
auto_enable_plan_id: z.union([z.string(), z.undefined()]).optional(),
send_email_receipts: z.union([z.boolean(), z.undefined()]).optional(),
billing_controls: z
.union([getOrCreateCustomerBillingControlsOutboundSchema, z.undefined()])
.optional(),
config: z
.union([getOrCreateCustomerConfigOutboundSchema, z.undefined()])
.optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional(),
});
const closedEnumSchema = z.any();
@@ -87,48 +113,63 @@ const customerExpandSchema = z.any();
export const getOrCreateCustomerIntervalSchema = closedEnumSchema;
export const getOrCreateCustomerPurchaseLimitSchema = z.object({
interval: getOrCreateCustomerIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
limit: z.number()
interval: getOrCreateCustomerIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
limit: z.number(),
});
export const getOrCreateCustomerAutoTopupSchema = z.object({
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
quantity: z.number(),
purchaseLimit: z.union([getOrCreateCustomerPurchaseLimitSchema, z.undefined()]).optional(),
invoiceMode: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
quantity: z.number(),
purchaseLimit: z
.union([getOrCreateCustomerPurchaseLimitSchema, z.undefined()])
.optional(),
invoiceMode: z.union([z.boolean(), z.undefined()]).optional(),
});
export const getOrCreateCustomerThresholdTypeSchema = closedEnumSchema;
export const getOrCreateCustomerUsageAlertSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
thresholdType: getOrCreateCustomerThresholdTypeSchema,
name: z.union([z.string(), z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
thresholdType: getOrCreateCustomerThresholdTypeSchema,
name: z.union([z.string(), z.undefined()]).optional(),
});
export const getOrCreateCustomerBillingControlsSchema = z.object({
autoTopups: z.union([z.array(getOrCreateCustomerAutoTopupSchema), z.undefined()]).optional(),
spendLimits: z.union([z.array(getOrCreateCustomerSpendLimitSchema), z.undefined()]).optional(),
usageAlerts: z.union([z.array(getOrCreateCustomerUsageAlertSchema), z.undefined()]).optional(),
overageAllowed: z.union([z.array(getOrCreateCustomerOverageAllowedSchema), z.undefined()]).optional()
autoTopups: z
.union([z.array(getOrCreateCustomerAutoTopupSchema), z.undefined()])
.optional(),
spendLimits: z
.union([z.array(getOrCreateCustomerSpendLimitSchema), z.undefined()])
.optional(),
usageAlerts: z
.union([z.array(getOrCreateCustomerUsageAlertSchema), z.undefined()])
.optional(),
overageAllowed: z
.union([z.array(getOrCreateCustomerOverageAllowedSchema), z.undefined()])
.optional(),
});
export const getOrCreateCustomerParamsSchema = z.object({
customerId: z.string().nullable(),
name: z.union([z.string(), z.undefined()]).optional().nullable(),
email: z.union([z.string(), z.undefined()]).optional().nullable(),
fingerprint: z.union([z.string(), z.undefined()]).optional().nullable(),
metadata: z.union([z.record(z.string(), z.any()), z.undefined()]).optional().nullable(),
stripeId: z.union([z.string(), z.undefined()]).optional().nullable(),
createInStripe: z.union([z.boolean(), z.undefined()]).optional(),
autoEnablePlanId: z.union([z.string(), z.undefined()]).optional(),
sendEmailReceipts: z.union([z.boolean(), z.undefined()]).optional(),
billingControls: z.union([getOrCreateCustomerBillingControlsSchema, z.undefined()]).optional(),
config: z.union([getOrCreateCustomerConfigSchema, z.undefined()]).optional(),
expand: z.union([z.array(customerExpandSchema), z.undefined()]).optional()
customerId: z.string().nullable(),
name: z.union([z.string(), z.undefined()]).optional().nullable(),
email: z.union([z.string(), z.undefined()]).optional().nullable(),
fingerprint: z.union([z.string(), z.undefined()]).optional().nullable(),
metadata: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional()
.nullable(),
stripeId: z.union([z.string(), z.undefined()]).optional().nullable(),
createInStripe: z.union([z.boolean(), z.undefined()]).optional(),
autoEnablePlanId: z.union([z.string(), z.undefined()]).optional(),
sendEmailReceipts: z.union([z.boolean(), z.undefined()]).optional(),
billingControls: z
.union([getOrCreateCustomerBillingControlsSchema, z.undefined()])
.optional(),
config: z.union([getOrCreateCustomerConfigSchema, z.undefined()]).optional(),
expand: z.union([z.array(customerExpandSchema), z.undefined()]).optional(),
});

View File

@@ -1,17 +1,17 @@
// Generated schemas from Speakeasy SDK types
// Run `bun api` to regenerate
export * from "./getOrCreateCustomerSchemas";
export * from "./attachSchemas";
export * from "./previewAttachSchemas";
export * from "./updateSubscriptionSchemas";
export * from "./previewUpdateSubscriptionSchemas";
export * from "./openCustomerPortalSchemas";
export * from "./setupPaymentSchemas";
export * from "./multiAttachSchemas";
export * from "./previewMultiAttachSchemas";
export * from "./listPlansSchemas";
export * from "./listEventsSchemas";
export * from "./aggregateEventsSchemas";
export * from "./attachSchemas";
export * from "./createReferralCodeSchemas";
export * from "./getOrCreateCustomerSchemas";
export * from "./listEventsSchemas";
export * from "./listPlansSchemas";
export * from "./multiAttachSchemas";
export * from "./openCustomerPortalSchemas";
export * from "./previewAttachSchemas";
export * from "./previewMultiAttachSchemas";
export * from "./previewUpdateSubscriptionSchemas";
export * from "./redeemReferralCodeSchemas";
export * from "./setupPaymentSchemas";
export * from "./updateSubscriptionSchemas";

View File

@@ -2,72 +2,87 @@
import { z } from "zod/v4";
export const listEventsGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const listEventsFeatureIdSchema = z.union([z.string(), z.array(z.string())]);
export const listEventsFeatureIdSchema = z.union([
z.string(),
z.array(z.string()),
]);
export const listEventsCustomRangeSchema = z.object({
start: z.union([z.number(), z.undefined()]).optional(),
end: z.union([z.number(), z.undefined()]).optional()
start: z.union([z.number(), z.undefined()]).optional(),
end: z.union([z.number(), z.undefined()]).optional(),
});
export const eventsListParamsSchema = z.object({
startCursor: z.union([z.string(), z.undefined()]).optional(),
limit: z.union([z.number(), z.undefined()]).optional(),
customerId: z.union([z.string(), z.undefined()]).optional(),
entityId: z.union([z.string(), z.undefined()]).optional(),
featureId: z.union([z.string(), z.array(z.string()), z.undefined()]).optional(),
customRange: z.union([listEventsCustomRangeSchema, z.undefined()]).optional()
startCursor: z.union([z.string(), z.undefined()]).optional(),
limit: z.union([z.number(), z.undefined()]).optional(),
customerId: z.union([z.string(), z.undefined()]).optional(),
entityId: z.union([z.string(), z.undefined()]).optional(),
featureId: z
.union([z.string(), z.array(z.string()), z.undefined()])
.optional(),
customRange: z.union([listEventsCustomRangeSchema, z.undefined()]).optional(),
});
export const listEventsFeatureIdOutboundSchema = z.union([z.string(), z.array(z.string())]);
export const listEventsFeatureIdOutboundSchema = z.union([
z.string(),
z.array(z.string()),
]);
export const listEventsCustomRangeOutboundSchema = z.object({
start: z.union([z.number(), z.undefined()]).optional(),
end: z.union([z.number(), z.undefined()]).optional()
start: z.union([z.number(), z.undefined()]).optional(),
end: z.union([z.number(), z.undefined()]).optional(),
});
export const eventsListParamsOutboundSchema = z.object({
start_cursor: z.string(),
limit: z.number(),
customer_id: z.union([z.string(), z.undefined()]).optional(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
feature_id: z.union([z.string(), z.array(z.string()), z.undefined()]).optional(),
custom_range: z.union([listEventsCustomRangeOutboundSchema, z.undefined()]).optional()
start_cursor: z.string(),
limit: z.number(),
customer_id: z.union([z.string(), z.undefined()]).optional(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
feature_id: z
.union([z.string(), z.array(z.string()), z.undefined()])
.optional(),
custom_range: z
.union([listEventsCustomRangeOutboundSchema, z.undefined()])
.optional(),
});
const openEnumSchema = z.any();
export const listEventsIntervalEnumSchema = openEnumSchema;
export const listEventsIntervalUnionSchema = z.union([listEventsIntervalEnumSchema, z.string()]);
export const listEventsIntervalUnionSchema = z.union([
listEventsIntervalEnumSchema,
z.string(),
]);
export const listEventsResetSchema = z.object({
interval: z.union([listEventsIntervalEnumSchema, z.string()]),
intervalCount: z.union([z.number(), z.undefined()]).optional(),
resetsAt: z.number().nullable()
interval: z.union([listEventsIntervalEnumSchema, z.string()]),
intervalCount: z.union([z.number(), z.undefined()]).optional(),
resetsAt: z.number().nullable(),
});
export const deductionsSchema = z.object({
balanceId: z.string(),
featureId: z.string(),
planId: z.string().nullable(),
reset: listEventsResetSchema.nullable(),
value: z.number()
balanceId: z.string(),
featureId: z.string(),
planId: z.string().nullable(),
reset: listEventsResetSchema.nullable(),
value: z.number(),
});
export const listEventsListSchema = z.object({
id: z.string(),
timestamp: z.number(),
featureId: z.string(),
customerId: z.string(),
value: z.number(),
properties: z.record(z.string(), z.any()),
deductions: z.array(deductionsSchema).nullable()
id: z.string(),
timestamp: z.number(),
featureId: z.string(),
customerId: z.string(),
value: z.number(),
properties: z.record(z.string(), z.any()),
deductions: z.array(deductionsSchema).nullable(),
});
export const listEventsResponseSchema = z.object({
list: z.array(listEventsListSchema),
nextCursor: z.string().nullable()
list: z.array(listEventsListSchema),
nextCursor: z.string().nullable(),
});

View File

@@ -2,43 +2,43 @@
import { z } from "zod/v4";
export const listPlansGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const listPlansParamsSchema = z.object({
customerId: z.union([z.string(), z.undefined()]).optional(),
entityId: z.union([z.string(), z.undefined()]).optional(),
includeArchived: z.union([z.boolean(), z.undefined()]).optional()
customerId: z.union([z.string(), z.undefined()]).optional(),
entityId: z.union([z.string(), z.undefined()]).optional(),
includeArchived: z.union([z.boolean(), z.undefined()]).optional(),
});
export const listPlansPriceDisplaySchema = z.object({
primaryText: z.string(),
secondaryText: z.union([z.string(), z.undefined()]).optional()
primaryText: z.string(),
secondaryText: z.union([z.string(), z.undefined()]).optional(),
});
export const listPlansFeatureDisplaySchema = z.object({
singular: z.string(),
plural: z.string()
singular: z.string(),
plural: z.string(),
});
export const listPlansCreditSchemaSchema = z.object({
meteredFeatureId: z.string(),
creditCost: z.number()
meteredFeatureId: z.string(),
creditCost: z.number(),
});
export const listPlansItemDisplaySchema = z.object({
primaryText: z.string(),
secondaryText: z.union([z.string(), z.undefined()]).optional()
primaryText: z.string(),
secondaryText: z.union([z.string(), z.undefined()]).optional(),
});
export const listPlansConfigSchema = z.object({
ignorePastDue: z.boolean()
ignorePastDue: z.boolean(),
});
export const listPlansParamsOutboundSchema = z.object({
customer_id: z.union([z.string(), z.undefined()]).optional(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
include_archived: z.union([z.boolean(), z.undefined()]).optional()
customer_id: z.union([z.string(), z.undefined()]).optional(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
include_archived: z.union([z.boolean(), z.undefined()]).optional(),
});
const openEnumSchema = z.any();
@@ -46,28 +46,34 @@ const openEnumSchema = z.any();
export const listPlansPriceIntervalSchema = openEnumSchema;
export const listPlansPriceSchema = z.object({
amount: z.number(),
interval: listPlansPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
display: z.union([listPlansPriceDisplaySchema, z.undefined()]).optional()
amount: z.number(),
interval: listPlansPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
display: z.union([listPlansPriceDisplaySchema, z.undefined()]).optional(),
});
export const listPlansTypeSchema = openEnumSchema;
export const listPlansFeatureSchema = z.object({
id: z.string(),
name: z.union([z.string(), z.undefined()]).optional().nullable(),
type: listPlansTypeSchema,
display: z.union([listPlansFeatureDisplaySchema, z.undefined()]).optional().nullable(),
creditSchema: z.union([z.array(listPlansCreditSchemaSchema), z.undefined()]).optional().nullable(),
archived: z.union([z.boolean(), z.undefined()]).optional().nullable()
id: z.string(),
name: z.union([z.string(), z.undefined()]).optional().nullable(),
type: listPlansTypeSchema,
display: z
.union([listPlansFeatureDisplaySchema, z.undefined()])
.optional()
.nullable(),
creditSchema: z
.union([z.array(listPlansCreditSchemaSchema), z.undefined()])
.optional()
.nullable(),
archived: z.union([z.boolean(), z.undefined()]).optional().nullable(),
});
export const listPlansResetIntervalSchema = openEnumSchema;
export const listPlansResetSchema = z.object({
interval: listPlansResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: listPlansResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const listPlansTierBehaviorSchema = openEnumSchema;
@@ -77,34 +83,36 @@ export const listPlansPriceItemIntervalSchema = openEnumSchema;
export const listPlansBillingMethodSchema = openEnumSchema;
export const listPlansItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(z.any().nullable()), z.undefined()]).optional(),
tierBehavior: z.union([listPlansTierBehaviorSchema, z.undefined()]).optional(),
interval: listPlansPriceItemIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.number(),
billingMethod: listPlansBillingMethodSchema,
maxPurchase: z.number().nullable()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(z.any().nullable()), z.undefined()]).optional(),
tierBehavior: z
.union([listPlansTierBehaviorSchema, z.undefined()])
.optional(),
interval: listPlansPriceItemIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.number(),
billingMethod: listPlansBillingMethodSchema,
maxPurchase: z.number().nullable(),
});
export const listPlansExpiryDurationTypeSchema = openEnumSchema;
export const listPlansRolloverSchema = z.object({
max: z.number().nullable(),
maxPercentage: z.union([z.number(), z.undefined()]).optional().nullable(),
expiryDurationType: listPlansExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.number().nullable(),
maxPercentage: z.union([z.number(), z.undefined()]).optional().nullable(),
expiryDurationType: listPlansExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const listPlansItemSchema = z.object({
featureId: z.string(),
feature: z.union([listPlansFeatureSchema, z.undefined()]).optional(),
included: z.number(),
unlimited: z.boolean(),
reset: listPlansResetSchema.nullable(),
price: listPlansItemPriceSchema.nullable(),
display: z.union([listPlansItemDisplaySchema, z.undefined()]).optional(),
rollover: z.union([listPlansRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
feature: z.union([listPlansFeatureSchema, z.undefined()]).optional(),
included: z.number(),
unlimited: z.boolean(),
reset: listPlansResetSchema.nullable(),
price: listPlansItemPriceSchema.nullable(),
display: z.union([listPlansItemDisplaySchema, z.undefined()]).optional(),
rollover: z.union([listPlansRolloverSchema, z.undefined()]).optional(),
});
export const listPlansDurationTypeSchema = openEnumSchema;
@@ -112,10 +120,10 @@ export const listPlansDurationTypeSchema = openEnumSchema;
export const listPlansOnEndSchema = openEnumSchema;
export const listPlansFreeTrialSchema = z.object({
durationLength: z.number(),
durationType: listPlansDurationTypeSchema,
cardRequired: z.boolean(),
onEnd: z.union([listPlansOnEndSchema, z.undefined()]).optional().nullable()
durationLength: z.number(),
durationType: listPlansDurationTypeSchema,
cardRequired: z.boolean(),
onEnd: z.union([listPlansOnEndSchema, z.undefined()]).optional().nullable(),
});
export const listPlansEnvSchema = openEnumSchema;
@@ -125,32 +133,34 @@ export const listPlansStatusSchema = openEnumSchema;
export const listPlansAttachActionSchema = openEnumSchema;
export const listPlansCustomerEligibilitySchema = z.object({
trialAvailable: z.union([z.boolean(), z.undefined()]).optional(),
status: z.union([listPlansStatusSchema, z.undefined()]).optional(),
canceling: z.union([z.boolean(), z.undefined()]).optional(),
trialing: z.union([z.boolean(), z.undefined()]).optional(),
attachAction: listPlansAttachActionSchema
trialAvailable: z.union([z.boolean(), z.undefined()]).optional(),
status: z.union([listPlansStatusSchema, z.undefined()]).optional(),
canceling: z.union([z.boolean(), z.undefined()]).optional(),
trialing: z.union([z.boolean(), z.undefined()]).optional(),
attachAction: listPlansAttachActionSchema,
});
export const listPlansListSchema = z.object({
id: z.string(),
name: z.string(),
description: z.string().nullable(),
group: z.string().nullable(),
version: z.number(),
addOn: z.boolean(),
autoEnable: z.boolean(),
price: listPlansPriceSchema.nullable(),
items: z.array(listPlansItemSchema),
freeTrial: z.union([listPlansFreeTrialSchema, z.undefined()]).optional(),
createdAt: z.number(),
env: listPlansEnvSchema,
archived: z.boolean(),
baseVariantId: z.string().nullable(),
config: listPlansConfigSchema,
customerEligibility: z.union([listPlansCustomerEligibilitySchema, z.undefined()]).optional()
id: z.string(),
name: z.string(),
description: z.string().nullable(),
group: z.string().nullable(),
version: z.number(),
addOn: z.boolean(),
autoEnable: z.boolean(),
price: listPlansPriceSchema.nullable(),
items: z.array(listPlansItemSchema),
freeTrial: z.union([listPlansFreeTrialSchema, z.undefined()]).optional(),
createdAt: z.number(),
env: listPlansEnvSchema,
archived: z.boolean(),
baseVariantId: z.string().nullable(),
config: listPlansConfigSchema,
customerEligibility: z
.union([listPlansCustomerEligibilitySchema, z.undefined()])
.optional(),
});
export const listPlansResponseSchema = z.object({
list: z.array(listPlansListSchema)
list: z.array(listPlansListSchema),
});

View File

@@ -2,171 +2,194 @@
import { z } from "zod/v4";
export const multiAttachGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachToSchema = z.union([z.number(), z.string()]);
export const multiAttachTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const multiAttachInvoiceModeSchema = z.object({
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional()
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional(),
});
export const multiAttachAttachDiscountSchema = z.object({
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional()
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachSpendLimitSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
overageLimit: z.union([z.number(), z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
overageLimit: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachOverageAllowedSchema = z.object({
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
});
export const multiAttachInvoiceSchema = z.object({
status: z.string().nullable(),
stripeId: z.string(),
total: z.number(),
currency: z.string(),
hostedInvoiceUrl: z.string().nullable()
status: z.string().nullable(),
stripeId: z.string(),
total: z.number(),
currency: z.string(),
hostedInvoiceUrl: z.string().nullable(),
});
export const multiAttachBasePriceOutboundSchema = z.object({
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachToOutboundSchema = z.union([z.number(), z.string()]);
export const multiAttachTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(multiAttachTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(multiAttachTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const multiAttachRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([multiAttachResetOutboundSchema, z.undefined()]).optional(),
price: z.union([multiAttachPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([multiAttachProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([multiAttachRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([multiAttachResetOutboundSchema, z.undefined()]).optional(),
price: z.union([multiAttachPriceOutboundSchema, z.undefined()]).optional(),
proration: z
.union([multiAttachProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([multiAttachRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const multiAttachCustomizeOutboundSchema = z.object({
price: z.union([multiAttachBasePriceOutboundSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(multiAttachPlanItemOutboundSchema), z.undefined()]).optional()
price: z
.union([multiAttachBasePriceOutboundSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(multiAttachPlanItemOutboundSchema), z.undefined()])
.optional(),
});
export const multiAttachFeatureQuantityOutboundSchema = z.object({
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const multiAttachPlanOutboundSchema = z.object({
plan_id: z.string(),
customize: z.union([multiAttachCustomizeOutboundSchema, z.undefined()]).optional(),
feature_quantities: z.union([z.array(multiAttachFeatureQuantityOutboundSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscription_id: z.union([z.string(), z.undefined()]).optional()
plan_id: z.string(),
customize: z
.union([multiAttachCustomizeOutboundSchema, z.undefined()])
.optional(),
feature_quantities: z
.union([z.array(multiAttachFeatureQuantityOutboundSchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachFreeTrialParamsOutboundSchema = z.object({
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional()
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachInvoiceModeOutboundSchema = z.object({
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean()
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean(),
});
export const multiAttachAttachDiscountOutboundSchema = z.object({
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional()
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachSpendLimitOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
overage_limit: z.union([z.number(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
overage_limit: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachUsageAlertOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
threshold: z.number(),
threshold_type: z.string(),
name: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
threshold: z.number(),
threshold_type: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachOverageAllowedOutboundSchema = z.object({
feature_id: z.string(),
enabled: z.boolean()
feature_id: z.string(),
enabled: z.boolean(),
});
export const multiAttachBillingControlsOutboundSchema = z.object({
spend_limits: z.union([z.array(multiAttachSpendLimitOutboundSchema), z.undefined()]).optional(),
usage_alerts: z.union([z.array(multiAttachUsageAlertOutboundSchema), z.undefined()]).optional(),
overage_allowed: z.union([z.array(multiAttachOverageAllowedOutboundSchema), z.undefined()]).optional()
spend_limits: z
.union([z.array(multiAttachSpendLimitOutboundSchema), z.undefined()])
.optional(),
usage_alerts: z
.union([z.array(multiAttachUsageAlertOutboundSchema), z.undefined()])
.optional(),
overage_allowed: z
.union([z.array(multiAttachOverageAllowedOutboundSchema), z.undefined()])
.optional(),
});
export const multiAttachEntityDataOutboundSchema = z.object({
feature_id: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billing_controls: z.union([multiAttachBillingControlsOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billing_controls: z
.union([multiAttachBillingControlsOutboundSchema, z.undefined()])
.optional(),
});
const closedEnumSchema = z.any();
@@ -180,16 +203,16 @@ const customerDataOutboundSchema = z.any();
export const multiAttachPriceIntervalSchema = closedEnumSchema;
export const multiAttachBasePriceSchema = z.object({
amount: z.number(),
interval: multiAttachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: multiAttachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachResetIntervalSchema = closedEnumSchema;
export const multiAttachResetSchema = z.object({
interval: multiAttachResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: multiAttachResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachTierBehaviorSchema = closedEnumSchema;
@@ -199,14 +222,16 @@ export const multiAttachItemPriceIntervalSchema = closedEnumSchema;
export const multiAttachBillingMethodSchema = closedEnumSchema;
export const multiAttachPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(multiAttachTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([multiAttachTierBehaviorSchema, z.undefined()]).optional(),
interval: multiAttachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: multiAttachBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(multiAttachTierSchema), z.undefined()]).optional(),
tierBehavior: z
.union([multiAttachTierBehaviorSchema, z.undefined()])
.optional(),
interval: multiAttachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: multiAttachBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachOnIncreaseSchema = closedEnumSchema;
@@ -214,40 +239,47 @@ export const multiAttachOnIncreaseSchema = closedEnumSchema;
export const multiAttachOnDecreaseSchema = closedEnumSchema;
export const multiAttachProrationSchema = z.object({
onIncrease: multiAttachOnIncreaseSchema,
onDecrease: multiAttachOnDecreaseSchema
onIncrease: multiAttachOnIncreaseSchema,
onDecrease: multiAttachOnDecreaseSchema,
});
export const multiAttachExpiryDurationTypeSchema = closedEnumSchema;
export const multiAttachRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: multiAttachExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: multiAttachExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const multiAttachPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([multiAttachResetSchema, z.undefined()]).optional(),
price: z.union([multiAttachPriceSchema, z.undefined()]).optional(),
proration: z.union([multiAttachProrationSchema, z.undefined()]).optional(),
rollover: z.union([multiAttachRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([multiAttachResetSchema, z.undefined()]).optional(),
price: z.union([multiAttachPriceSchema, z.undefined()]).optional(),
proration: z.union([multiAttachProrationSchema, z.undefined()]).optional(),
rollover: z.union([multiAttachRolloverSchema, z.undefined()]).optional(),
});
export const multiAttachCustomizeSchema = z.object({
price: z.union([multiAttachBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(multiAttachPlanItemSchema), z.undefined()]).optional()
price: z
.union([multiAttachBasePriceSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(multiAttachPlanItemSchema), z.undefined()])
.optional(),
});
export const multiAttachPlanSchema = z.object({
planId: z.string(),
customize: z.union([multiAttachCustomizeSchema, z.undefined()]).optional(),
featureQuantities: z.union([z.array(multiAttachFeatureQuantitySchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional()
planId: z.string(),
customize: z.union([multiAttachCustomizeSchema, z.undefined()]).optional(),
featureQuantities: z
.union([z.array(multiAttachFeatureQuantitySchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachDurationTypeSchema = closedEnumSchema;
@@ -255,10 +287,12 @@ export const multiAttachDurationTypeSchema = closedEnumSchema;
export const multiAttachOnEndSchema = closedEnumSchema;
export const multiAttachFreeTrialParamsSchema = z.object({
durationLength: z.number(),
durationType: z.union([multiAttachDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([multiAttachOnEndSchema, z.undefined()]).optional()
durationLength: z.number(),
durationType: z
.union([multiAttachDurationTypeSchema, z.undefined()])
.optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([multiAttachOnEndSchema, z.undefined()]).optional(),
});
export const multiAttachRedirectModeSchema = closedEnumSchema;
@@ -266,68 +300,102 @@ export const multiAttachRedirectModeSchema = closedEnumSchema;
export const multiAttachThresholdTypeSchema = closedEnumSchema;
export const multiAttachUsageAlertSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
thresholdType: multiAttachThresholdTypeSchema,
name: z.union([z.string(), z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
thresholdType: multiAttachThresholdTypeSchema,
name: z.union([z.string(), z.undefined()]).optional(),
});
export const multiAttachBillingControlsSchema = z.object({
spendLimits: z.union([z.array(multiAttachSpendLimitSchema), z.undefined()]).optional(),
usageAlerts: z.union([z.array(multiAttachUsageAlertSchema), z.undefined()]).optional(),
overageAllowed: z.union([z.array(multiAttachOverageAllowedSchema), z.undefined()]).optional()
spendLimits: z
.union([z.array(multiAttachSpendLimitSchema), z.undefined()])
.optional(),
usageAlerts: z
.union([z.array(multiAttachUsageAlertSchema), z.undefined()])
.optional(),
overageAllowed: z
.union([z.array(multiAttachOverageAllowedSchema), z.undefined()])
.optional(),
});
export const multiAttachEntityDataSchema = z.object({
featureId: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billingControls: z.union([multiAttachBillingControlsSchema, z.undefined()]).optional()
featureId: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billingControls: z
.union([multiAttachBillingControlsSchema, z.undefined()])
.optional(),
});
export const multiAttachParamsSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(multiAttachPlanSchema),
freeTrial: z.union([multiAttachFreeTrialParamsSchema, z.undefined()]).optional().nullable(),
invoiceMode: z.union([multiAttachInvoiceModeSchema, z.undefined()]).optional(),
discounts: z.union([z.array(multiAttachAttachDiscountSchema), z.undefined()]).optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
checkoutSessionParams: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
redirectMode: z.union([multiAttachRedirectModeSchema, z.undefined()]).optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
customerData: z.union([customerDataSchema, z.undefined()]).optional(),
entityData: z.union([multiAttachEntityDataSchema, z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(multiAttachPlanSchema),
freeTrial: z
.union([multiAttachFreeTrialParamsSchema, z.undefined()])
.optional()
.nullable(),
invoiceMode: z
.union([multiAttachInvoiceModeSchema, z.undefined()])
.optional(),
discounts: z
.union([z.array(multiAttachAttachDiscountSchema), z.undefined()])
.optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
checkoutSessionParams: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
redirectMode: z
.union([multiAttachRedirectModeSchema, z.undefined()])
.optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
customerData: z.union([customerDataSchema, z.undefined()]).optional(),
entityData: z.union([multiAttachEntityDataSchema, z.undefined()]).optional(),
});
export const multiAttachCodeSchema = openEnumSchema;
export const multiAttachRequiredActionSchema = z.object({
code: multiAttachCodeSchema,
reason: z.string()
code: multiAttachCodeSchema,
reason: z.string(),
});
export const multiAttachResponseSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
invoice: z.union([multiAttachInvoiceSchema, z.undefined()]).optional(),
paymentUrl: z.string().nullable(),
requiredAction: z.union([multiAttachRequiredActionSchema, z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
invoice: z.union([multiAttachInvoiceSchema, z.undefined()]).optional(),
paymentUrl: z.string().nullable(),
requiredAction: z
.union([multiAttachRequiredActionSchema, z.undefined()])
.optional(),
});
export const multiAttachParamsOutboundSchema = z.object({
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(multiAttachPlanOutboundSchema),
free_trial: z.union([multiAttachFreeTrialParamsOutboundSchema, z.undefined()]).optional().nullable(),
invoice_mode: z.union([multiAttachInvoiceModeOutboundSchema, z.undefined()]).optional(),
discounts: z.union([z.array(multiAttachAttachDiscountOutboundSchema), z.undefined()]).optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
checkout_session_params: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
redirect_mode: z.string(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
customer_data: z.union([customerDataOutboundSchema, z.undefined()]).optional(),
entity_data: z.union([multiAttachEntityDataOutboundSchema, z.undefined()]).optional()
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(multiAttachPlanOutboundSchema),
free_trial: z
.union([multiAttachFreeTrialParamsOutboundSchema, z.undefined()])
.optional()
.nullable(),
invoice_mode: z
.union([multiAttachInvoiceModeOutboundSchema, z.undefined()])
.optional(),
discounts: z
.union([z.array(multiAttachAttachDiscountOutboundSchema), z.undefined()])
.optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
checkout_session_params: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
redirect_mode: z.string(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
customer_data: z
.union([customerDataOutboundSchema, z.undefined()])
.optional(),
entity_data: z
.union([multiAttachEntityDataOutboundSchema, z.undefined()])
.optional(),
});

View File

@@ -2,22 +2,22 @@
import { z } from "zod/v4";
export const openCustomerPortalGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const openCustomerPortalParamsSchema = z.object({
customerId: z.string(),
configurationId: z.union([z.string(), z.undefined()]).optional(),
returnUrl: z.union([z.string(), z.undefined()]).optional()
customerId: z.string(),
configurationId: z.union([z.string(), z.undefined()]).optional(),
returnUrl: z.union([z.string(), z.undefined()]).optional(),
});
export const openCustomerPortalResponseSchema = z.object({
customerId: z.string(),
url: z.string()
customerId: z.string(),
url: z.string(),
});
export const openCustomerPortalParamsOutboundSchema = z.object({
customer_id: z.string(),
configuration_id: z.union([z.string(), z.undefined()]).optional(),
return_url: z.union([z.string(), z.undefined()]).optional()
customer_id: z.string(),
configuration_id: z.union([z.string(), z.undefined()]).optional(),
return_url: z.union([z.string(), z.undefined()]).optional(),
});

View File

@@ -2,318 +2,387 @@
import { z } from "zod/v4";
export const previewAttachGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachFeatureQuantityRequestSchema = z.object({
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewAttachItemToSchema = z.union([z.number(), z.string()]);
export const previewAttachItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemToSchema = z.union([z.number(), z.string()]);
export const previewAttachAddItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachInvoiceModeSchema = z.object({
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional()
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewAttachAttachDiscountSchema = z.object({
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional()
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachCustomLineItemSchema = z.object({
amount: z.number(),
description: z.string()
amount: z.number(),
description: z.string(),
});
export const previewAttachCarryOverBalancesSchema = z.object({
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const previewAttachCarryOverUsagesSchema = z.object({
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const previewAttachDiscountSchema = z.object({
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional()
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewAttachLineItemSchema = z.object({
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z.union([z.array(previewAttachDiscountSchema), z.undefined()]).optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewAttachLineItemPeriodSchema, z.undefined()]).optional(),
quantity: z.number()
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z
.union([z.array(previewAttachDiscountSchema), z.undefined()])
.optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewAttachLineItemPeriodSchema, z.undefined()])
.optional(),
quantity: z.number(),
});
export const previewAttachNextCycleDiscountSchema = z.object({
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional()
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachNextCycleLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewAttachNextCycleLineItemSchema = z.object({
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z.union([z.array(previewAttachNextCycleDiscountSchema), z.undefined()]).optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewAttachNextCycleLineItemPeriodSchema, z.undefined()]).optional(),
quantity: z.number()
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z
.union([z.array(previewAttachNextCycleDiscountSchema), z.undefined()])
.optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewAttachNextCycleLineItemPeriodSchema, z.undefined()])
.optional(),
quantity: z.number(),
});
export const previewAttachUsageLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewAttachUsageLineItemSchema = z.object({
displayName: z.string(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewAttachUsageLineItemPeriodSchema, z.undefined()]).optional()
displayName: z.string(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewAttachUsageLineItemPeriodSchema, z.undefined()])
.optional(),
});
export const previewAttachNextCycleSchema = z.object({
startsAt: z.number(),
subtotal: z.number(),
total: z.number(),
lineItems: z.array(previewAttachNextCycleLineItemSchema),
usageLineItems: z.array(previewAttachUsageLineItemSchema)
startsAt: z.number(),
subtotal: z.number(),
total: z.number(),
lineItems: z.array(previewAttachNextCycleLineItemSchema),
usageLineItems: z.array(previewAttachUsageLineItemSchema),
});
export const previewAttachIncomingFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.number()
featureId: z.string(),
quantity: z.number(),
});
export const previewAttachOutgoingFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.number()
featureId: z.string(),
quantity: z.number(),
});
export const previewAttachInvoiceCreditsSchema = z.object({
balance: z.number(),
currency: z.string()
balance: z.number(),
currency: z.string(),
});
export const previewAttachFeatureQuantityRequestOutboundSchema = z.object({
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewAttachBasePriceOutboundSchema = z.object({
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemToOutboundSchema = z.union([z.number(), z.string()]);
export const previewAttachItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const previewAttachItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewAttachItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewAttachItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const previewAttachItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewAttachItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([previewAttachItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([previewAttachItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([previewAttachItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([previewAttachItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([previewAttachItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([previewAttachItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([previewAttachItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const previewAttachAddItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemToOutboundSchema = z.union([z.number(), z.string()]);
export const previewAttachAddItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const previewAttachAddItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewAttachAddItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewAttachAddItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const previewAttachAddItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewAttachAddItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([previewAttachAddItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([previewAttachAddItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([previewAttachAddItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([previewAttachAddItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([previewAttachAddItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([previewAttachAddItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([previewAttachAddItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const previewAttachPlanItemFilterOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachFreeTrialParamsOutboundSchema = z.object({
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional()
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachCustomizeOutboundSchema = z.object({
price: z.union([previewAttachBasePriceOutboundSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(previewAttachItemPlanItemOutboundSchema), z.undefined()]).optional(),
add_items: z.union([z.array(previewAttachAddItemPlanItemOutboundSchema), z.undefined()]).optional(),
remove_items: z.union([z.array(previewAttachPlanItemFilterOutboundSchema), z.undefined()]).optional(),
free_trial: z.union([previewAttachFreeTrialParamsOutboundSchema, z.undefined()]).optional().nullable()
price: z
.union([previewAttachBasePriceOutboundSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(previewAttachItemPlanItemOutboundSchema), z.undefined()])
.optional(),
add_items: z
.union([z.array(previewAttachAddItemPlanItemOutboundSchema), z.undefined()])
.optional(),
remove_items: z
.union([z.array(previewAttachPlanItemFilterOutboundSchema), z.undefined()])
.optional(),
free_trial: z
.union([previewAttachFreeTrialParamsOutboundSchema, z.undefined()])
.optional()
.nullable(),
});
export const previewAttachInvoiceModeOutboundSchema = z.object({
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean()
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean(),
});
export const previewAttachAttachDiscountOutboundSchema = z.object({
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional()
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachCustomLineItemOutboundSchema = z.object({
amount: z.number(),
description: z.string()
amount: z.number(),
description: z.string(),
});
export const previewAttachCarryOverBalancesOutboundSchema = z.object({
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const previewAttachCarryOverUsagesOutboundSchema = z.object({
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const previewAttachParamsOutboundSchema = z.object({
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.string(),
feature_quantities: z.union([z.array(previewAttachFeatureQuantityRequestOutboundSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([previewAttachCustomizeOutboundSchema, z.undefined()]).optional(),
invoice_mode: z.union([previewAttachInvoiceModeOutboundSchema, z.undefined()]).optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(previewAttachAttachDiscountOutboundSchema), z.undefined()]).optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
plan_schedule: z.union([z.string(), z.undefined()]).optional(),
starts_at: z.union([z.number(), z.undefined()]).optional(),
ends_at: z.union([z.number(), z.undefined()]).optional(),
checkout_session_params: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
custom_line_items: z.union([z.array(previewAttachCustomLineItemOutboundSchema), z.undefined()]).optional(),
processor_subscription_id: z.union([z.string(), z.undefined()]).optional(),
carry_over_balances: z.union([previewAttachCarryOverBalancesOutboundSchema, z.undefined()]).optional(),
carry_over_usages: z.union([previewAttachCarryOverUsagesOutboundSchema, z.undefined()]).optional(),
metadata: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
tax_rate_id: z.union([z.string(), z.undefined()]).optional()
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.string(),
feature_quantities: z
.union([
z.array(previewAttachFeatureQuantityRequestOutboundSchema),
z.undefined(),
])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z
.union([previewAttachCustomizeOutboundSchema, z.undefined()])
.optional(),
invoice_mode: z
.union([previewAttachInvoiceModeOutboundSchema, z.undefined()])
.optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(previewAttachAttachDiscountOutboundSchema), z.undefined()])
.optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
plan_schedule: z.union([z.string(), z.undefined()]).optional(),
starts_at: z.union([z.number(), z.undefined()]).optional(),
ends_at: z.union([z.number(), z.undefined()]).optional(),
checkout_session_params: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
custom_line_items: z
.union([z.array(previewAttachCustomLineItemOutboundSchema), z.undefined()])
.optional(),
processor_subscription_id: z.union([z.string(), z.undefined()]).optional(),
carry_over_balances: z
.union([previewAttachCarryOverBalancesOutboundSchema, z.undefined()])
.optional(),
carry_over_usages: z
.union([previewAttachCarryOverUsagesOutboundSchema, z.undefined()])
.optional(),
metadata: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
tax_rate_id: z.union([z.string(), z.undefined()]).optional(),
});
const closedEnumSchema = z.any();
@@ -325,16 +394,16 @@ const openEnumSchema = z.any();
export const previewAttachPriceIntervalSchema = closedEnumSchema;
export const previewAttachBasePriceSchema = z.object({
amount: z.number(),
interval: previewAttachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: previewAttachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemResetIntervalSchema = closedEnumSchema;
export const previewAttachItemResetSchema = z.object({
interval: previewAttachItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: previewAttachItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemTierBehaviorSchema = closedEnumSchema;
@@ -344,14 +413,18 @@ export const previewAttachItemPriceIntervalSchema = closedEnumSchema;
export const previewAttachItemBillingMethodSchema = closedEnumSchema;
export const previewAttachItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewAttachItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([previewAttachItemTierBehaviorSchema, z.undefined()]).optional(),
interval: previewAttachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewAttachItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewAttachItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([previewAttachItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: previewAttachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewAttachItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemOnIncreaseSchema = closedEnumSchema;
@@ -359,34 +432,38 @@ export const previewAttachItemOnIncreaseSchema = closedEnumSchema;
export const previewAttachItemOnDecreaseSchema = closedEnumSchema;
export const previewAttachItemProrationSchema = z.object({
onIncrease: previewAttachItemOnIncreaseSchema,
onDecrease: previewAttachItemOnDecreaseSchema
onIncrease: previewAttachItemOnIncreaseSchema,
onDecrease: previewAttachItemOnDecreaseSchema,
});
export const previewAttachItemExpiryDurationTypeSchema = closedEnumSchema;
export const previewAttachItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewAttachItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewAttachItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewAttachItemResetSchema, z.undefined()]).optional(),
price: z.union([previewAttachItemPriceSchema, z.undefined()]).optional(),
proration: z.union([previewAttachItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([previewAttachItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewAttachItemResetSchema, z.undefined()]).optional(),
price: z.union([previewAttachItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([previewAttachItemProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([previewAttachItemRolloverSchema, z.undefined()])
.optional(),
});
export const previewAttachAddItemResetIntervalSchema = closedEnumSchema;
export const previewAttachAddItemResetSchema = z.object({
interval: previewAttachAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: previewAttachAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemTierBehaviorSchema = closedEnumSchema;
@@ -396,14 +473,18 @@ export const previewAttachAddItemPriceIntervalSchema = closedEnumSchema;
export const previewAttachAddItemBillingMethodSchema = closedEnumSchema;
export const previewAttachAddItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewAttachAddItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([previewAttachAddItemTierBehaviorSchema, z.undefined()]).optional(),
interval: previewAttachAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewAttachAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewAttachAddItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([previewAttachAddItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: previewAttachAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewAttachAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemOnIncreaseSchema = closedEnumSchema;
@@ -411,27 +492,31 @@ export const previewAttachAddItemOnIncreaseSchema = closedEnumSchema;
export const previewAttachAddItemOnDecreaseSchema = closedEnumSchema;
export const previewAttachAddItemProrationSchema = z.object({
onIncrease: previewAttachAddItemOnIncreaseSchema,
onDecrease: previewAttachAddItemOnDecreaseSchema
onIncrease: previewAttachAddItemOnIncreaseSchema,
onDecrease: previewAttachAddItemOnDecreaseSchema,
});
export const previewAttachAddItemExpiryDurationTypeSchema = closedEnumSchema;
export const previewAttachAddItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewAttachAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewAttachAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const previewAttachAddItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewAttachAddItemResetSchema, z.undefined()]).optional(),
price: z.union([previewAttachAddItemPriceSchema, z.undefined()]).optional(),
proration: z.union([previewAttachAddItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([previewAttachAddItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewAttachAddItemResetSchema, z.undefined()]).optional(),
price: z.union([previewAttachAddItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([previewAttachAddItemProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([previewAttachAddItemRolloverSchema, z.undefined()])
.optional(),
});
export const previewAttachRemoveItemBillingMethodSchema = closedEnumSchema;
@@ -439,9 +524,13 @@ export const previewAttachRemoveItemBillingMethodSchema = closedEnumSchema;
export const previewAttachRemoveItemIntervalSchema = closedEnumSchema;
export const previewAttachPlanItemFilterSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z.union([previewAttachRemoveItemBillingMethodSchema, z.undefined()]).optional(),
interval: z.union([previewAttachRemoveItemIntervalSchema, z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z
.union([previewAttachRemoveItemBillingMethodSchema, z.undefined()])
.optional(),
interval: z
.union([previewAttachRemoveItemIntervalSchema, z.undefined()])
.optional(),
});
export const previewAttachDurationTypeSchema = closedEnumSchema;
@@ -449,18 +538,32 @@ export const previewAttachDurationTypeSchema = closedEnumSchema;
export const previewAttachOnEndSchema = closedEnumSchema;
export const previewAttachFreeTrialParamsSchema = z.object({
durationLength: z.number(),
durationType: z.union([previewAttachDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([previewAttachOnEndSchema, z.undefined()]).optional()
durationLength: z.number(),
durationType: z
.union([previewAttachDurationTypeSchema, z.undefined()])
.optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([previewAttachOnEndSchema, z.undefined()]).optional(),
});
export const previewAttachCustomizeSchema = z.object({
price: z.union([previewAttachBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(previewAttachItemPlanItemSchema), z.undefined()]).optional(),
addItems: z.union([z.array(previewAttachAddItemPlanItemSchema), z.undefined()]).optional(),
removeItems: z.union([z.array(previewAttachPlanItemFilterSchema), z.undefined()]).optional(),
freeTrial: z.union([previewAttachFreeTrialParamsSchema, z.undefined()]).optional().nullable()
price: z
.union([previewAttachBasePriceSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(previewAttachItemPlanItemSchema), z.undefined()])
.optional(),
addItems: z
.union([z.array(previewAttachAddItemPlanItemSchema), z.undefined()])
.optional(),
removeItems: z
.union([z.array(previewAttachPlanItemFilterSchema), z.undefined()])
.optional(),
freeTrial: z
.union([previewAttachFreeTrialParamsSchema, z.undefined()])
.optional()
.nullable(),
});
export const previewAttachProrationBehaviorSchema = closedEnumSchema;
@@ -470,50 +573,72 @@ export const previewAttachRedirectModeSchema = closedEnumSchema;
export const previewAttachPlanScheduleSchema = closedEnumSchema;
export const previewAttachParamsSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.string(),
featureQuantities: z.union([z.array(previewAttachFeatureQuantityRequestSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([previewAttachCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z.union([previewAttachInvoiceModeSchema, z.undefined()]).optional(),
prorationBehavior: z.union([previewAttachProrationBehaviorSchema, z.undefined()]).optional(),
redirectMode: z.union([previewAttachRedirectModeSchema, z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(previewAttachAttachDiscountSchema), z.undefined()]).optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
planSchedule: z.union([previewAttachPlanScheduleSchema, z.undefined()]).optional(),
startsAt: z.union([z.number(), z.undefined()]).optional(),
endsAt: z.union([z.number(), z.undefined()]).optional(),
checkoutSessionParams: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
customLineItems: z.union([z.array(previewAttachCustomLineItemSchema), z.undefined()]).optional(),
processorSubscriptionId: z.union([z.string(), z.undefined()]).optional(),
carryOverBalances: z.union([previewAttachCarryOverBalancesSchema, z.undefined()]).optional(),
carryOverUsages: z.union([previewAttachCarryOverUsagesSchema, z.undefined()]).optional(),
metadata: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
taxRateId: z.union([z.string(), z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.string(),
featureQuantities: z
.union([z.array(previewAttachFeatureQuantityRequestSchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([previewAttachCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z
.union([previewAttachInvoiceModeSchema, z.undefined()])
.optional(),
prorationBehavior: z
.union([previewAttachProrationBehaviorSchema, z.undefined()])
.optional(),
redirectMode: z
.union([previewAttachRedirectModeSchema, z.undefined()])
.optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(previewAttachAttachDiscountSchema), z.undefined()])
.optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
planSchedule: z
.union([previewAttachPlanScheduleSchema, z.undefined()])
.optional(),
startsAt: z.union([z.number(), z.undefined()]).optional(),
endsAt: z.union([z.number(), z.undefined()]).optional(),
checkoutSessionParams: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
customLineItems: z
.union([z.array(previewAttachCustomLineItemSchema), z.undefined()])
.optional(),
processorSubscriptionId: z.union([z.string(), z.undefined()]).optional(),
carryOverBalances: z
.union([previewAttachCarryOverBalancesSchema, z.undefined()])
.optional(),
carryOverUsages: z
.union([previewAttachCarryOverUsagesSchema, z.undefined()])
.optional(),
metadata: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
taxRateId: z.union([z.string(), z.undefined()]).optional(),
});
export const previewAttachIncomingSchema = z.object({
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewAttachIncomingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable()
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewAttachIncomingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable(),
});
export const previewAttachOutgoingSchema = z.object({
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewAttachOutgoingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable()
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewAttachOutgoingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable(),
});
export const previewAttachCheckoutTypeSchema = openEnumSchema;
@@ -521,25 +646,27 @@ export const previewAttachCheckoutTypeSchema = openEnumSchema;
export const previewAttachStatusSchema = openEnumSchema;
export const previewAttachTaxSchema = z.object({
total: z.number(),
amountInclusive: z.number(),
amountExclusive: z.number(),
currency: z.string(),
status: previewAttachStatusSchema
total: z.number(),
amountInclusive: z.number(),
amountExclusive: z.number(),
currency: z.string(),
status: previewAttachStatusSchema,
});
export const previewAttachResponseSchema = z.object({
customerId: z.string(),
lineItems: z.array(previewAttachLineItemSchema),
subtotal: z.number(),
total: z.number(),
currency: z.string(),
nextCycle: z.union([previewAttachNextCycleSchema, z.undefined()]).optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional(),
incoming: z.array(previewAttachIncomingSchema),
outgoing: z.array(previewAttachOutgoingSchema),
redirectToCheckout: z.boolean(),
checkoutType: previewAttachCheckoutTypeSchema.nullable(),
tax: z.union([previewAttachTaxSchema, z.undefined()]).optional(),
invoiceCredits: z.union([previewAttachInvoiceCreditsSchema, z.undefined()]).optional()
customerId: z.string(),
lineItems: z.array(previewAttachLineItemSchema),
subtotal: z.number(),
total: z.number(),
currency: z.string(),
nextCycle: z.union([previewAttachNextCycleSchema, z.undefined()]).optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional(),
incoming: z.array(previewAttachIncomingSchema),
outgoing: z.array(previewAttachOutgoingSchema),
redirectToCheckout: z.boolean(),
checkoutType: previewAttachCheckoutTypeSchema.nullable(),
tax: z.union([previewAttachTaxSchema, z.undefined()]).optional(),
invoiceCredits: z
.union([previewAttachInvoiceCreditsSchema, z.undefined()])
.optional(),
});

View File

@@ -2,246 +2,292 @@
import { z } from "zod/v4";
export const previewMultiAttachGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachToSchema = z.union([z.number(), z.string()]);
export const previewMultiAttachTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachPlanFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewMultiAttachInvoiceModeSchema = z.object({
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional()
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewMultiAttachAttachDiscountSchema = z.object({
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional()
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachSpendLimitSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
overageLimit: z.union([z.number(), z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
overageLimit: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachOverageAllowedSchema = z.object({
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewMultiAttachDiscountSchema = z.object({
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional()
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewMultiAttachLineItemSchema = z.object({
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z.union([z.array(previewMultiAttachDiscountSchema), z.undefined()]).optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewMultiAttachLineItemPeriodSchema, z.undefined()]).optional(),
quantity: z.number()
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z
.union([z.array(previewMultiAttachDiscountSchema), z.undefined()])
.optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewMultiAttachLineItemPeriodSchema, z.undefined()])
.optional(),
quantity: z.number(),
});
export const previewMultiAttachNextCycleDiscountSchema = z.object({
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional()
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachNextCycleLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewMultiAttachNextCycleLineItemSchema = z.object({
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z.union([z.array(previewMultiAttachNextCycleDiscountSchema), z.undefined()]).optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewMultiAttachNextCycleLineItemPeriodSchema, z.undefined()]).optional(),
quantity: z.number()
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z
.union([z.array(previewMultiAttachNextCycleDiscountSchema), z.undefined()])
.optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewMultiAttachNextCycleLineItemPeriodSchema, z.undefined()])
.optional(),
quantity: z.number(),
});
export const previewMultiAttachUsageLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewMultiAttachUsageLineItemSchema = z.object({
displayName: z.string(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewMultiAttachUsageLineItemPeriodSchema, z.undefined()]).optional()
displayName: z.string(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewMultiAttachUsageLineItemPeriodSchema, z.undefined()])
.optional(),
});
export const previewMultiAttachNextCycleSchema = z.object({
startsAt: z.number(),
subtotal: z.number(),
total: z.number(),
lineItems: z.array(previewMultiAttachNextCycleLineItemSchema),
usageLineItems: z.array(previewMultiAttachUsageLineItemSchema)
startsAt: z.number(),
subtotal: z.number(),
total: z.number(),
lineItems: z.array(previewMultiAttachNextCycleLineItemSchema),
usageLineItems: z.array(previewMultiAttachUsageLineItemSchema),
});
export const previewMultiAttachIncomingFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.number()
featureId: z.string(),
quantity: z.number(),
});
export const previewMultiAttachOutgoingFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.number()
featureId: z.string(),
quantity: z.number(),
});
export const previewMultiAttachInvoiceCreditsSchema = z.object({
balance: z.number(),
currency: z.string()
balance: z.number(),
currency: z.string(),
});
export const previewMultiAttachBasePriceOutboundSchema = z.object({
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachToOutboundSchema = z.union([z.number(), z.string()]);
export const previewMultiAttachToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const previewMultiAttachTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewMultiAttachTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewMultiAttachTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const previewMultiAttachRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewMultiAttachResetOutboundSchema, z.undefined()]).optional(),
price: z.union([previewMultiAttachPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([previewMultiAttachProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([previewMultiAttachRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([previewMultiAttachResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([previewMultiAttachPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([previewMultiAttachProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([previewMultiAttachRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const previewMultiAttachCustomizeOutboundSchema = z.object({
price: z.union([previewMultiAttachBasePriceOutboundSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(previewMultiAttachPlanItemOutboundSchema), z.undefined()]).optional()
price: z
.union([previewMultiAttachBasePriceOutboundSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(previewMultiAttachPlanItemOutboundSchema), z.undefined()])
.optional(),
});
export const previewMultiAttachPlanFeatureQuantityOutboundSchema = z.object({
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewMultiAttachPlanOutboundSchema = z.object({
plan_id: z.string(),
customize: z.union([previewMultiAttachCustomizeOutboundSchema, z.undefined()]).optional(),
feature_quantities: z.union([z.array(previewMultiAttachPlanFeatureQuantityOutboundSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscription_id: z.union([z.string(), z.undefined()]).optional()
plan_id: z.string(),
customize: z
.union([previewMultiAttachCustomizeOutboundSchema, z.undefined()])
.optional(),
feature_quantities: z
.union([
z.array(previewMultiAttachPlanFeatureQuantityOutboundSchema),
z.undefined(),
])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachFreeTrialParamsOutboundSchema = z.object({
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional()
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachInvoiceModeOutboundSchema = z.object({
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean()
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean(),
});
export const previewMultiAttachAttachDiscountOutboundSchema = z.object({
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional()
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachSpendLimitOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
overage_limit: z.union([z.number(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
overage_limit: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachUsageAlertOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
threshold: z.number(),
threshold_type: z.string(),
name: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
enabled: z.boolean(),
threshold: z.number(),
threshold_type: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachOverageAllowedOutboundSchema = z.object({
feature_id: z.string(),
enabled: z.boolean()
feature_id: z.string(),
enabled: z.boolean(),
});
export const previewMultiAttachBillingControlsOutboundSchema = z.object({
spend_limits: z.union([z.array(previewMultiAttachSpendLimitOutboundSchema), z.undefined()]).optional(),
usage_alerts: z.union([z.array(previewMultiAttachUsageAlertOutboundSchema), z.undefined()]).optional(),
overage_allowed: z.union([z.array(previewMultiAttachOverageAllowedOutboundSchema), z.undefined()]).optional()
spend_limits: z
.union([z.array(previewMultiAttachSpendLimitOutboundSchema), z.undefined()])
.optional(),
usage_alerts: z
.union([z.array(previewMultiAttachUsageAlertOutboundSchema), z.undefined()])
.optional(),
overage_allowed: z
.union([
z.array(previewMultiAttachOverageAllowedOutboundSchema),
z.undefined(),
])
.optional(),
});
export const previewMultiAttachEntityDataOutboundSchema = z.object({
feature_id: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billing_controls: z.union([previewMultiAttachBillingControlsOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billing_controls: z
.union([previewMultiAttachBillingControlsOutboundSchema, z.undefined()])
.optional(),
});
const closedEnumSchema = z.any();
@@ -257,16 +303,16 @@ const customerDataOutboundSchema = z.any();
export const previewMultiAttachPriceIntervalSchema = closedEnumSchema;
export const previewMultiAttachBasePriceSchema = z.object({
amount: z.number(),
interval: previewMultiAttachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: previewMultiAttachPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachResetIntervalSchema = closedEnumSchema;
export const previewMultiAttachResetSchema = z.object({
interval: previewMultiAttachResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: previewMultiAttachResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachTierBehaviorSchema = closedEnumSchema;
@@ -276,14 +322,18 @@ export const previewMultiAttachItemPriceIntervalSchema = closedEnumSchema;
export const previewMultiAttachBillingMethodSchema = closedEnumSchema;
export const previewMultiAttachPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewMultiAttachTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([previewMultiAttachTierBehaviorSchema, z.undefined()]).optional(),
interval: previewMultiAttachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewMultiAttachBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewMultiAttachTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([previewMultiAttachTierBehaviorSchema, z.undefined()])
.optional(),
interval: previewMultiAttachItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewMultiAttachBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachOnIncreaseSchema = closedEnumSchema;
@@ -291,40 +341,56 @@ export const previewMultiAttachOnIncreaseSchema = closedEnumSchema;
export const previewMultiAttachOnDecreaseSchema = closedEnumSchema;
export const previewMultiAttachProrationSchema = z.object({
onIncrease: previewMultiAttachOnIncreaseSchema,
onDecrease: previewMultiAttachOnDecreaseSchema
onIncrease: previewMultiAttachOnIncreaseSchema,
onDecrease: previewMultiAttachOnDecreaseSchema,
});
export const previewMultiAttachExpiryDurationTypeSchema = closedEnumSchema;
export const previewMultiAttachRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewMultiAttachExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewMultiAttachExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const previewMultiAttachPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewMultiAttachResetSchema, z.undefined()]).optional(),
price: z.union([previewMultiAttachPriceSchema, z.undefined()]).optional(),
proration: z.union([previewMultiAttachProrationSchema, z.undefined()]).optional(),
rollover: z.union([previewMultiAttachRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewMultiAttachResetSchema, z.undefined()]).optional(),
price: z.union([previewMultiAttachPriceSchema, z.undefined()]).optional(),
proration: z
.union([previewMultiAttachProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([previewMultiAttachRolloverSchema, z.undefined()])
.optional(),
});
export const previewMultiAttachCustomizeSchema = z.object({
price: z.union([previewMultiAttachBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(previewMultiAttachPlanItemSchema), z.undefined()]).optional()
price: z
.union([previewMultiAttachBasePriceSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(previewMultiAttachPlanItemSchema), z.undefined()])
.optional(),
});
export const previewMultiAttachPlanSchema = z.object({
planId: z.string(),
customize: z.union([previewMultiAttachCustomizeSchema, z.undefined()]).optional(),
featureQuantities: z.union([z.array(previewMultiAttachPlanFeatureQuantitySchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional()
planId: z.string(),
customize: z
.union([previewMultiAttachCustomizeSchema, z.undefined()])
.optional(),
featureQuantities: z
.union([
z.array(previewMultiAttachPlanFeatureQuantitySchema),
z.undefined(),
])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachDurationTypeSchema = closedEnumSchema;
@@ -332,10 +398,12 @@ export const previewMultiAttachDurationTypeSchema = closedEnumSchema;
export const previewMultiAttachOnEndSchema = closedEnumSchema;
export const previewMultiAttachFreeTrialParamsSchema = z.object({
durationLength: z.number(),
durationType: z.union([previewMultiAttachDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([previewMultiAttachOnEndSchema, z.undefined()]).optional()
durationLength: z.number(),
durationType: z
.union([previewMultiAttachDurationTypeSchema, z.undefined()])
.optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([previewMultiAttachOnEndSchema, z.undefined()]).optional(),
});
export const previewMultiAttachRedirectModeSchema = closedEnumSchema;
@@ -343,57 +411,78 @@ export const previewMultiAttachRedirectModeSchema = closedEnumSchema;
export const previewMultiAttachThresholdTypeSchema = closedEnumSchema;
export const previewMultiAttachUsageAlertSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
thresholdType: previewMultiAttachThresholdTypeSchema,
name: z.union([z.string(), z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
enabled: z.union([z.boolean(), z.undefined()]).optional(),
threshold: z.number(),
thresholdType: previewMultiAttachThresholdTypeSchema,
name: z.union([z.string(), z.undefined()]).optional(),
});
export const previewMultiAttachBillingControlsSchema = z.object({
spendLimits: z.union([z.array(previewMultiAttachSpendLimitSchema), z.undefined()]).optional(),
usageAlerts: z.union([z.array(previewMultiAttachUsageAlertSchema), z.undefined()]).optional(),
overageAllowed: z.union([z.array(previewMultiAttachOverageAllowedSchema), z.undefined()]).optional()
spendLimits: z
.union([z.array(previewMultiAttachSpendLimitSchema), z.undefined()])
.optional(),
usageAlerts: z
.union([z.array(previewMultiAttachUsageAlertSchema), z.undefined()])
.optional(),
overageAllowed: z
.union([z.array(previewMultiAttachOverageAllowedSchema), z.undefined()])
.optional(),
});
export const previewMultiAttachEntityDataSchema = z.object({
featureId: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billingControls: z.union([previewMultiAttachBillingControlsSchema, z.undefined()]).optional()
featureId: z.string(),
name: z.union([z.string(), z.undefined()]).optional(),
billingControls: z
.union([previewMultiAttachBillingControlsSchema, z.undefined()])
.optional(),
});
export const previewMultiAttachParamsSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(previewMultiAttachPlanSchema),
freeTrial: z.union([previewMultiAttachFreeTrialParamsSchema, z.undefined()]).optional().nullable(),
invoiceMode: z.union([previewMultiAttachInvoiceModeSchema, z.undefined()]).optional(),
discounts: z.union([z.array(previewMultiAttachAttachDiscountSchema), z.undefined()]).optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
checkoutSessionParams: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
redirectMode: z.union([previewMultiAttachRedirectModeSchema, z.undefined()]).optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
customerData: z.union([customerDataSchema, z.undefined()]).optional(),
entityData: z.union([previewMultiAttachEntityDataSchema, z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(previewMultiAttachPlanSchema),
freeTrial: z
.union([previewMultiAttachFreeTrialParamsSchema, z.undefined()])
.optional()
.nullable(),
invoiceMode: z
.union([previewMultiAttachInvoiceModeSchema, z.undefined()])
.optional(),
discounts: z
.union([z.array(previewMultiAttachAttachDiscountSchema), z.undefined()])
.optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
checkoutSessionParams: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
redirectMode: z
.union([previewMultiAttachRedirectModeSchema, z.undefined()])
.optional(),
newBillingSubscription: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
customerData: z.union([customerDataSchema, z.undefined()]).optional(),
entityData: z
.union([previewMultiAttachEntityDataSchema, z.undefined()])
.optional(),
});
export const previewMultiAttachIncomingSchema = z.object({
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewMultiAttachIncomingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable()
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewMultiAttachIncomingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable(),
});
export const previewMultiAttachOutgoingSchema = z.object({
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewMultiAttachOutgoingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable()
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewMultiAttachOutgoingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable(),
});
export const previewMultiAttachCheckoutTypeSchema = openEnumSchema;
@@ -401,41 +490,61 @@ export const previewMultiAttachCheckoutTypeSchema = openEnumSchema;
export const previewMultiAttachStatusSchema = openEnumSchema;
export const previewMultiAttachTaxSchema = z.object({
total: z.number(),
amountInclusive: z.number(),
amountExclusive: z.number(),
currency: z.string(),
status: previewMultiAttachStatusSchema
total: z.number(),
amountInclusive: z.number(),
amountExclusive: z.number(),
currency: z.string(),
status: previewMultiAttachStatusSchema,
});
export const previewMultiAttachResponseSchema = z.object({
customerId: z.string(),
lineItems: z.array(previewMultiAttachLineItemSchema),
subtotal: z.number(),
total: z.number(),
currency: z.string(),
nextCycle: z.union([previewMultiAttachNextCycleSchema, z.undefined()]).optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional(),
incoming: z.array(previewMultiAttachIncomingSchema),
outgoing: z.array(previewMultiAttachOutgoingSchema),
redirectToCheckout: z.boolean(),
checkoutType: previewMultiAttachCheckoutTypeSchema.nullable(),
tax: z.union([previewMultiAttachTaxSchema, z.undefined()]).optional(),
invoiceCredits: z.union([previewMultiAttachInvoiceCreditsSchema, z.undefined()]).optional()
customerId: z.string(),
lineItems: z.array(previewMultiAttachLineItemSchema),
subtotal: z.number(),
total: z.number(),
currency: z.string(),
nextCycle: z
.union([previewMultiAttachNextCycleSchema, z.undefined()])
.optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional(),
incoming: z.array(previewMultiAttachIncomingSchema),
outgoing: z.array(previewMultiAttachOutgoingSchema),
redirectToCheckout: z.boolean(),
checkoutType: previewMultiAttachCheckoutTypeSchema.nullable(),
tax: z.union([previewMultiAttachTaxSchema, z.undefined()]).optional(),
invoiceCredits: z
.union([previewMultiAttachInvoiceCreditsSchema, z.undefined()])
.optional(),
});
export const previewMultiAttachParamsOutboundSchema = z.object({
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(previewMultiAttachPlanOutboundSchema),
free_trial: z.union([previewMultiAttachFreeTrialParamsOutboundSchema, z.undefined()]).optional().nullable(),
invoice_mode: z.union([previewMultiAttachInvoiceModeOutboundSchema, z.undefined()]).optional(),
discounts: z.union([z.array(previewMultiAttachAttachDiscountOutboundSchema), z.undefined()]).optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
checkout_session_params: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
redirect_mode: z.string(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
customer_data: z.union([customerDataOutboundSchema, z.undefined()]).optional(),
entity_data: z.union([previewMultiAttachEntityDataOutboundSchema, z.undefined()]).optional()
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plans: z.array(previewMultiAttachPlanOutboundSchema),
free_trial: z
.union([previewMultiAttachFreeTrialParamsOutboundSchema, z.undefined()])
.optional()
.nullable(),
invoice_mode: z
.union([previewMultiAttachInvoiceModeOutboundSchema, z.undefined()])
.optional(),
discounts: z
.union([
z.array(previewMultiAttachAttachDiscountOutboundSchema),
z.undefined(),
])
.optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
checkout_session_params: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
redirect_mode: z.string(),
new_billing_subscription: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
customer_data: z
.union([customerDataOutboundSchema, z.undefined()])
.optional(),
entity_data: z
.union([previewMultiAttachEntityDataOutboundSchema, z.undefined()])
.optional(),
});

View File

@@ -2,285 +2,346 @@
import { z } from "zod/v4";
export const previewUpdateGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const previewUpdateFeatureQuantityRequestSchema = z.object({
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewUpdateItemToSchema = z.union([z.number(), z.string()]);
export const previewUpdateItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemToSchema = z.union([z.number(), z.string()]);
export const previewUpdateAddItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateInvoiceModeSchema = z.object({
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional()
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewUpdateAttachDiscountSchema = z.object({
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional()
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional(),
});
export const previewUpdateRecalculateBalancesSchema = z.object({
enabled: z.boolean()
enabled: z.boolean(),
});
export const previewUpdateDiscountSchema = z.object({
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional()
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional(),
});
export const previewUpdateLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewUpdateLineItemSchema = z.object({
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z.union([z.array(previewUpdateDiscountSchema), z.undefined()]).optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewUpdateLineItemPeriodSchema, z.undefined()]).optional(),
quantity: z.number()
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z
.union([z.array(previewUpdateDiscountSchema), z.undefined()])
.optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewUpdateLineItemPeriodSchema, z.undefined()])
.optional(),
quantity: z.number(),
});
export const previewUpdateNextCycleDiscountSchema = z.object({
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional()
amountOff: z.number(),
percentOff: z.union([z.number(), z.undefined()]).optional(),
rewardId: z.union([z.string(), z.undefined()]).optional(),
rewardName: z.union([z.string(), z.undefined()]).optional(),
});
export const previewUpdateNextCycleLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewUpdateNextCycleLineItemSchema = z.object({
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z.union([z.array(previewUpdateNextCycleDiscountSchema), z.undefined()]).optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewUpdateNextCycleLineItemPeriodSchema, z.undefined()]).optional(),
quantity: z.number()
displayName: z.string(),
description: z.string(),
subtotal: z.number(),
total: z.number(),
discounts: z
.union([z.array(previewUpdateNextCycleDiscountSchema), z.undefined()])
.optional(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewUpdateNextCycleLineItemPeriodSchema, z.undefined()])
.optional(),
quantity: z.number(),
});
export const previewUpdateUsageLineItemPeriodSchema = z.object({
start: z.number(),
end: z.number()
start: z.number(),
end: z.number(),
});
export const previewUpdateUsageLineItemSchema = z.object({
displayName: z.string(),
planId: z.string(),
featureId: z.string().nullable(),
period: z.union([previewUpdateUsageLineItemPeriodSchema, z.undefined()]).optional()
displayName: z.string(),
planId: z.string(),
featureId: z.string().nullable(),
period: z
.union([previewUpdateUsageLineItemPeriodSchema, z.undefined()])
.optional(),
});
export const previewUpdateNextCycleSchema = z.object({
startsAt: z.number(),
subtotal: z.number(),
total: z.number(),
lineItems: z.array(previewUpdateNextCycleLineItemSchema),
usageLineItems: z.array(previewUpdateUsageLineItemSchema)
startsAt: z.number(),
subtotal: z.number(),
total: z.number(),
lineItems: z.array(previewUpdateNextCycleLineItemSchema),
usageLineItems: z.array(previewUpdateUsageLineItemSchema),
});
export const previewUpdateIncomingFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.number()
featureId: z.string(),
quantity: z.number(),
});
export const previewUpdateOutgoingFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.number()
featureId: z.string(),
quantity: z.number(),
});
export const previewUpdateInvoiceCreditsSchema = z.object({
balance: z.number(),
currency: z.string()
balance: z.number(),
currency: z.string(),
});
export const previewUpdateFeatureQuantityRequestOutboundSchema = z.object({
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const previewUpdateBasePriceOutboundSchema = z.object({
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemToOutboundSchema = z.union([z.number(), z.string()]);
export const previewUpdateItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const previewUpdateItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewUpdateItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewUpdateItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const previewUpdateItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewUpdateItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([previewUpdateItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([previewUpdateItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([previewUpdateItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([previewUpdateItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([previewUpdateItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([previewUpdateItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([previewUpdateItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const previewUpdateAddItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemToOutboundSchema = z.union([z.number(), z.string()]);
export const previewUpdateAddItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const previewUpdateAddItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewUpdateAddItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewUpdateAddItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const previewUpdateAddItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewUpdateAddItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([previewUpdateAddItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([previewUpdateAddItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([previewUpdateAddItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([previewUpdateAddItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([previewUpdateAddItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([previewUpdateAddItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([previewUpdateAddItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const previewUpdatePlanItemFilterOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional(),
});
export const previewUpdateFreeTrialParamsOutboundSchema = z.object({
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional()
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional(),
});
export const previewUpdateCustomizeOutboundSchema = z.object({
price: z.union([previewUpdateBasePriceOutboundSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(previewUpdateItemPlanItemOutboundSchema), z.undefined()]).optional(),
add_items: z.union([z.array(previewUpdateAddItemPlanItemOutboundSchema), z.undefined()]).optional(),
remove_items: z.union([z.array(previewUpdatePlanItemFilterOutboundSchema), z.undefined()]).optional(),
free_trial: z.union([previewUpdateFreeTrialParamsOutboundSchema, z.undefined()]).optional().nullable()
price: z
.union([previewUpdateBasePriceOutboundSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(previewUpdateItemPlanItemOutboundSchema), z.undefined()])
.optional(),
add_items: z
.union([z.array(previewUpdateAddItemPlanItemOutboundSchema), z.undefined()])
.optional(),
remove_items: z
.union([z.array(previewUpdatePlanItemFilterOutboundSchema), z.undefined()])
.optional(),
free_trial: z
.union([previewUpdateFreeTrialParamsOutboundSchema, z.undefined()])
.optional()
.nullable(),
});
export const previewUpdateInvoiceModeOutboundSchema = z.object({
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean()
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean(),
});
export const previewUpdateAttachDiscountOutboundSchema = z.object({
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional()
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional(),
});
export const previewUpdateRecalculateBalancesOutboundSchema = z.object({
enabled: z.boolean()
enabled: z.boolean(),
});
export const previewUpdateParamsOutboundSchema = z.object({
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.union([z.string(), z.undefined()]).optional(),
feature_quantities: z.union([z.array(previewUpdateFeatureQuantityRequestOutboundSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([previewUpdateCustomizeOutboundSchema, z.undefined()]).optional(),
invoice_mode: z.union([previewUpdateInvoiceModeOutboundSchema, z.undefined()]).optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(previewUpdateAttachDiscountOutboundSchema), z.undefined()]).optional(),
cancel_action: z.union([z.string(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
recalculate_balances: z.union([previewUpdateRecalculateBalancesOutboundSchema, z.undefined()]).optional()
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.union([z.string(), z.undefined()]).optional(),
feature_quantities: z
.union([
z.array(previewUpdateFeatureQuantityRequestOutboundSchema),
z.undefined(),
])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z
.union([previewUpdateCustomizeOutboundSchema, z.undefined()])
.optional(),
invoice_mode: z
.union([previewUpdateInvoiceModeOutboundSchema, z.undefined()])
.optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(previewUpdateAttachDiscountOutboundSchema), z.undefined()])
.optional(),
cancel_action: z.union([z.string(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
recalculate_balances: z
.union([previewUpdateRecalculateBalancesOutboundSchema, z.undefined()])
.optional(),
});
const closedEnumSchema = z.any();
@@ -292,16 +353,16 @@ const openEnumSchema = z.any();
export const previewUpdatePriceIntervalSchema = closedEnumSchema;
export const previewUpdateBasePriceSchema = z.object({
amount: z.number(),
interval: previewUpdatePriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: previewUpdatePriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemResetIntervalSchema = closedEnumSchema;
export const previewUpdateItemResetSchema = z.object({
interval: previewUpdateItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: previewUpdateItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemTierBehaviorSchema = closedEnumSchema;
@@ -311,14 +372,18 @@ export const previewUpdateItemPriceIntervalSchema = closedEnumSchema;
export const previewUpdateItemBillingMethodSchema = closedEnumSchema;
export const previewUpdateItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewUpdateItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([previewUpdateItemTierBehaviorSchema, z.undefined()]).optional(),
interval: previewUpdateItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewUpdateItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewUpdateItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([previewUpdateItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: previewUpdateItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewUpdateItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemOnIncreaseSchema = closedEnumSchema;
@@ -326,34 +391,38 @@ export const previewUpdateItemOnIncreaseSchema = closedEnumSchema;
export const previewUpdateItemOnDecreaseSchema = closedEnumSchema;
export const previewUpdateItemProrationSchema = z.object({
onIncrease: previewUpdateItemOnIncreaseSchema,
onDecrease: previewUpdateItemOnDecreaseSchema
onIncrease: previewUpdateItemOnIncreaseSchema,
onDecrease: previewUpdateItemOnDecreaseSchema,
});
export const previewUpdateItemExpiryDurationTypeSchema = closedEnumSchema;
export const previewUpdateItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewUpdateItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewUpdateItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewUpdateItemResetSchema, z.undefined()]).optional(),
price: z.union([previewUpdateItemPriceSchema, z.undefined()]).optional(),
proration: z.union([previewUpdateItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([previewUpdateItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewUpdateItemResetSchema, z.undefined()]).optional(),
price: z.union([previewUpdateItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([previewUpdateItemProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([previewUpdateItemRolloverSchema, z.undefined()])
.optional(),
});
export const previewUpdateAddItemResetIntervalSchema = closedEnumSchema;
export const previewUpdateAddItemResetSchema = z.object({
interval: previewUpdateAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: previewUpdateAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemTierBehaviorSchema = closedEnumSchema;
@@ -363,14 +432,18 @@ export const previewUpdateAddItemPriceIntervalSchema = closedEnumSchema;
export const previewUpdateAddItemBillingMethodSchema = closedEnumSchema;
export const previewUpdateAddItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(previewUpdateAddItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([previewUpdateAddItemTierBehaviorSchema, z.undefined()]).optional(),
interval: previewUpdateAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewUpdateAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(previewUpdateAddItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([previewUpdateAddItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: previewUpdateAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: previewUpdateAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemOnIncreaseSchema = closedEnumSchema;
@@ -378,27 +451,31 @@ export const previewUpdateAddItemOnIncreaseSchema = closedEnumSchema;
export const previewUpdateAddItemOnDecreaseSchema = closedEnumSchema;
export const previewUpdateAddItemProrationSchema = z.object({
onIncrease: previewUpdateAddItemOnIncreaseSchema,
onDecrease: previewUpdateAddItemOnDecreaseSchema
onIncrease: previewUpdateAddItemOnIncreaseSchema,
onDecrease: previewUpdateAddItemOnDecreaseSchema,
});
export const previewUpdateAddItemExpiryDurationTypeSchema = closedEnumSchema;
export const previewUpdateAddItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewUpdateAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: previewUpdateAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const previewUpdateAddItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewUpdateAddItemResetSchema, z.undefined()]).optional(),
price: z.union([previewUpdateAddItemPriceSchema, z.undefined()]).optional(),
proration: z.union([previewUpdateAddItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([previewUpdateAddItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([previewUpdateAddItemResetSchema, z.undefined()]).optional(),
price: z.union([previewUpdateAddItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([previewUpdateAddItemProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([previewUpdateAddItemRolloverSchema, z.undefined()])
.optional(),
});
export const previewUpdateRemoveItemBillingMethodSchema = closedEnumSchema;
@@ -406,9 +483,13 @@ export const previewUpdateRemoveItemBillingMethodSchema = closedEnumSchema;
export const previewUpdateRemoveItemIntervalSchema = closedEnumSchema;
export const previewUpdatePlanItemFilterSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z.union([previewUpdateRemoveItemBillingMethodSchema, z.undefined()]).optional(),
interval: z.union([previewUpdateRemoveItemIntervalSchema, z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z
.union([previewUpdateRemoveItemBillingMethodSchema, z.undefined()])
.optional(),
interval: z
.union([previewUpdateRemoveItemIntervalSchema, z.undefined()])
.optional(),
});
export const previewUpdateDurationTypeSchema = closedEnumSchema;
@@ -416,18 +497,32 @@ export const previewUpdateDurationTypeSchema = closedEnumSchema;
export const previewUpdateOnEndSchema = closedEnumSchema;
export const previewUpdateFreeTrialParamsSchema = z.object({
durationLength: z.number(),
durationType: z.union([previewUpdateDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([previewUpdateOnEndSchema, z.undefined()]).optional()
durationLength: z.number(),
durationType: z
.union([previewUpdateDurationTypeSchema, z.undefined()])
.optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([previewUpdateOnEndSchema, z.undefined()]).optional(),
});
export const previewUpdateCustomizeSchema = z.object({
price: z.union([previewUpdateBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(previewUpdateItemPlanItemSchema), z.undefined()]).optional(),
addItems: z.union([z.array(previewUpdateAddItemPlanItemSchema), z.undefined()]).optional(),
removeItems: z.union([z.array(previewUpdatePlanItemFilterSchema), z.undefined()]).optional(),
freeTrial: z.union([previewUpdateFreeTrialParamsSchema, z.undefined()]).optional().nullable()
price: z
.union([previewUpdateBasePriceSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(previewUpdateItemPlanItemSchema), z.undefined()])
.optional(),
addItems: z
.union([z.array(previewUpdateAddItemPlanItemSchema), z.undefined()])
.optional(),
removeItems: z
.union([z.array(previewUpdatePlanItemFilterSchema), z.undefined()])
.optional(),
freeTrial: z
.union([previewUpdateFreeTrialParamsSchema, z.undefined()])
.optional()
.nullable(),
});
export const previewUpdateProrationBehaviorSchema = closedEnumSchema;
@@ -437,39 +532,53 @@ export const previewUpdateRedirectModeSchema = closedEnumSchema;
export const previewUpdateCancelActionSchema = closedEnumSchema;
export const previewUpdateParamsSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.union([z.string(), z.undefined()]).optional(),
featureQuantities: z.union([z.array(previewUpdateFeatureQuantityRequestSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([previewUpdateCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z.union([previewUpdateInvoiceModeSchema, z.undefined()]).optional(),
prorationBehavior: z.union([previewUpdateProrationBehaviorSchema, z.undefined()]).optional(),
redirectMode: z.union([previewUpdateRedirectModeSchema, z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(previewUpdateAttachDiscountSchema), z.undefined()]).optional(),
cancelAction: z.union([previewUpdateCancelActionSchema, z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
recalculateBalances: z.union([previewUpdateRecalculateBalancesSchema, z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.union([z.string(), z.undefined()]).optional(),
featureQuantities: z
.union([z.array(previewUpdateFeatureQuantityRequestSchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([previewUpdateCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z
.union([previewUpdateInvoiceModeSchema, z.undefined()])
.optional(),
prorationBehavior: z
.union([previewUpdateProrationBehaviorSchema, z.undefined()])
.optional(),
redirectMode: z
.union([previewUpdateRedirectModeSchema, z.undefined()])
.optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(previewUpdateAttachDiscountSchema), z.undefined()])
.optional(),
cancelAction: z
.union([previewUpdateCancelActionSchema, z.undefined()])
.optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
recalculateBalances: z
.union([previewUpdateRecalculateBalancesSchema, z.undefined()])
.optional(),
});
export const previewUpdateIncomingSchema = z.object({
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewUpdateIncomingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable()
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewUpdateIncomingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable(),
});
export const previewUpdateOutgoingSchema = z.object({
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewUpdateOutgoingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable()
planId: z.string(),
plan: z.union([planSchema, z.undefined()]).optional(),
featureQuantities: z.array(previewUpdateOutgoingFeatureQuantitySchema),
effectiveAt: z.number().nullable(),
canceledAt: z.number().nullable(),
expiresAt: z.number().nullable(),
});
export const intentSchema = openEnumSchema;
@@ -477,24 +586,26 @@ export const intentSchema = openEnumSchema;
export const previewUpdateStatusSchema = openEnumSchema;
export const previewUpdateTaxSchema = z.object({
total: z.number(),
amountInclusive: z.number(),
amountExclusive: z.number(),
currency: z.string(),
status: previewUpdateStatusSchema
total: z.number(),
amountInclusive: z.number(),
amountExclusive: z.number(),
currency: z.string(),
status: previewUpdateStatusSchema,
});
export const previewUpdateResponseSchema = z.object({
customerId: z.string(),
lineItems: z.array(previewUpdateLineItemSchema),
subtotal: z.number(),
total: z.number(),
currency: z.string(),
nextCycle: z.union([previewUpdateNextCycleSchema, z.undefined()]).optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional(),
incoming: z.array(previewUpdateIncomingSchema),
outgoing: z.array(previewUpdateOutgoingSchema),
intent: intentSchema,
tax: z.union([previewUpdateTaxSchema, z.undefined()]).optional(),
invoiceCredits: z.union([previewUpdateInvoiceCreditsSchema, z.undefined()]).optional()
customerId: z.string(),
lineItems: z.array(previewUpdateLineItemSchema),
subtotal: z.number(),
total: z.number(),
currency: z.string(),
nextCycle: z.union([previewUpdateNextCycleSchema, z.undefined()]).optional(),
expand: z.union([z.array(z.string()), z.undefined()]).optional(),
incoming: z.array(previewUpdateIncomingSchema),
outgoing: z.array(previewUpdateOutgoingSchema),
intent: intentSchema,
tax: z.union([previewUpdateTaxSchema, z.undefined()]).optional(),
invoiceCredits: z
.union([previewUpdateInvoiceCreditsSchema, z.undefined()])
.optional(),
});

View File

@@ -2,21 +2,21 @@
import { z } from "zod/v4";
export const redeemReferralCodeGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const redeemReferralCodeParamsSchema = z.object({
code: z.string(),
customerId: z.string()
code: z.string(),
customerId: z.string(),
});
export const redeemReferralCodeResponseSchema = z.object({
id: z.string(),
customerId: z.string(),
rewardId: z.string()
id: z.string(),
customerId: z.string(),
rewardId: z.string(),
});
export const redeemReferralCodeParamsOutboundSchema = z.object({
code: z.string(),
customer_id: z.string()
code: z.string(),
customer_id: z.string(),
});

View File

@@ -2,225 +2,279 @@
import { z } from "zod/v4";
export const setupPaymentGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const setupPaymentFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const setupPaymentItemToSchema = z.union([z.number(), z.string()]);
export const setupPaymentItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemToSchema = z.union([z.number(), z.string()]);
export const setupPaymentAddItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAttachDiscountSchema = z.object({
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional()
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional(),
});
export const setupPaymentCustomLineItemSchema = z.object({
amount: z.number(),
description: z.string()
amount: z.number(),
description: z.string(),
});
export const setupPaymentCarryOverBalancesSchema = z.object({
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const setupPaymentCarryOverUsagesSchema = z.object({
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
featureIds: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const setupPaymentResponseSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
url: z.string()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
url: z.string(),
});
export const setupPaymentFeatureQuantityOutboundSchema = z.object({
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const setupPaymentBasePriceOutboundSchema = z.object({
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemToOutboundSchema = z.union([z.number(), z.string()]);
export const setupPaymentItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const setupPaymentItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(setupPaymentItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(setupPaymentItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const setupPaymentItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([setupPaymentItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([setupPaymentItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([setupPaymentItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([setupPaymentItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([setupPaymentItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([setupPaymentItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([setupPaymentItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([setupPaymentItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const setupPaymentAddItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemToOutboundSchema = z.union([z.number(), z.string()]);
export const setupPaymentAddItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const setupPaymentAddItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(setupPaymentAddItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(setupPaymentAddItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const setupPaymentAddItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([setupPaymentAddItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([setupPaymentAddItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([setupPaymentAddItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([setupPaymentAddItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([setupPaymentAddItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([setupPaymentAddItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([setupPaymentAddItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([setupPaymentAddItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const setupPaymentPlanItemFilterOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional(),
});
export const setupPaymentFreeTrialParamsOutboundSchema = z.object({
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional()
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional(),
});
export const setupPaymentCustomizeOutboundSchema = z.object({
price: z.union([setupPaymentBasePriceOutboundSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(setupPaymentItemPlanItemOutboundSchema), z.undefined()]).optional(),
add_items: z.union([z.array(setupPaymentAddItemPlanItemOutboundSchema), z.undefined()]).optional(),
remove_items: z.union([z.array(setupPaymentPlanItemFilterOutboundSchema), z.undefined()]).optional(),
free_trial: z.union([setupPaymentFreeTrialParamsOutboundSchema, z.undefined()]).optional().nullable()
price: z
.union([setupPaymentBasePriceOutboundSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(setupPaymentItemPlanItemOutboundSchema), z.undefined()])
.optional(),
add_items: z
.union([z.array(setupPaymentAddItemPlanItemOutboundSchema), z.undefined()])
.optional(),
remove_items: z
.union([z.array(setupPaymentPlanItemFilterOutboundSchema), z.undefined()])
.optional(),
free_trial: z
.union([setupPaymentFreeTrialParamsOutboundSchema, z.undefined()])
.optional()
.nullable(),
});
export const setupPaymentAttachDiscountOutboundSchema = z.object({
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional()
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional(),
});
export const setupPaymentCustomLineItemOutboundSchema = z.object({
amount: z.number(),
description: z.string()
amount: z.number(),
description: z.string(),
});
export const setupPaymentCarryOverBalancesOutboundSchema = z.object({
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const setupPaymentCarryOverUsagesOutboundSchema = z.object({
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional()
enabled: z.boolean(),
feature_ids: z.union([z.array(z.string()), z.undefined()]).optional(),
});
export const setupPaymentParamsOutboundSchema = z.object({
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.union([z.string(), z.undefined()]).optional(),
feature_quantities: z.union([z.array(setupPaymentFeatureQuantityOutboundSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([setupPaymentCustomizeOutboundSchema, z.undefined()]).optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(setupPaymentAttachDiscountOutboundSchema), z.undefined()]).optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
starts_at: z.union([z.number(), z.undefined()]).optional(),
ends_at: z.union([z.number(), z.undefined()]).optional(),
checkout_session_params: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
custom_line_items: z.union([z.array(setupPaymentCustomLineItemOutboundSchema), z.undefined()]).optional(),
processor_subscription_id: z.union([z.string(), z.undefined()]).optional(),
carry_over_balances: z.union([setupPaymentCarryOverBalancesOutboundSchema, z.undefined()]).optional(),
carry_over_usages: z.union([setupPaymentCarryOverUsagesOutboundSchema, z.undefined()]).optional(),
metadata: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
tax_rate_id: z.union([z.string(), z.undefined()]).optional()
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.union([z.string(), z.undefined()]).optional(),
feature_quantities: z
.union([z.array(setupPaymentFeatureQuantityOutboundSchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z
.union([setupPaymentCustomizeOutboundSchema, z.undefined()])
.optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(setupPaymentAttachDiscountOutboundSchema), z.undefined()])
.optional(),
success_url: z.union([z.string(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
starts_at: z.union([z.number(), z.undefined()]).optional(),
ends_at: z.union([z.number(), z.undefined()]).optional(),
checkout_session_params: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
custom_line_items: z
.union([z.array(setupPaymentCustomLineItemOutboundSchema), z.undefined()])
.optional(),
processor_subscription_id: z.union([z.string(), z.undefined()]).optional(),
carry_over_balances: z
.union([setupPaymentCarryOverBalancesOutboundSchema, z.undefined()])
.optional(),
carry_over_usages: z
.union([setupPaymentCarryOverUsagesOutboundSchema, z.undefined()])
.optional(),
metadata: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
enable_plan_immediately: z.union([z.boolean(), z.undefined()]).optional(),
tax_rate_id: z.union([z.string(), z.undefined()]).optional(),
});
const closedEnumSchema = z.any();
@@ -228,16 +282,16 @@ const closedEnumSchema = z.any();
export const setupPaymentPriceIntervalSchema = closedEnumSchema;
export const setupPaymentBasePriceSchema = z.object({
amount: z.number(),
interval: setupPaymentPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: setupPaymentPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemResetIntervalSchema = closedEnumSchema;
export const setupPaymentItemResetSchema = z.object({
interval: setupPaymentItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: setupPaymentItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemTierBehaviorSchema = closedEnumSchema;
@@ -247,14 +301,18 @@ export const setupPaymentItemPriceIntervalSchema = closedEnumSchema;
export const setupPaymentItemBillingMethodSchema = closedEnumSchema;
export const setupPaymentItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(setupPaymentItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([setupPaymentItemTierBehaviorSchema, z.undefined()]).optional(),
interval: setupPaymentItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: setupPaymentItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(setupPaymentItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([setupPaymentItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: setupPaymentItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: setupPaymentItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemOnIncreaseSchema = closedEnumSchema;
@@ -262,34 +320,36 @@ export const setupPaymentItemOnIncreaseSchema = closedEnumSchema;
export const setupPaymentItemOnDecreaseSchema = closedEnumSchema;
export const setupPaymentItemProrationSchema = z.object({
onIncrease: setupPaymentItemOnIncreaseSchema,
onDecrease: setupPaymentItemOnDecreaseSchema
onIncrease: setupPaymentItemOnIncreaseSchema,
onDecrease: setupPaymentItemOnDecreaseSchema,
});
export const setupPaymentItemExpiryDurationTypeSchema = closedEnumSchema;
export const setupPaymentItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: setupPaymentItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: setupPaymentItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([setupPaymentItemResetSchema, z.undefined()]).optional(),
price: z.union([setupPaymentItemPriceSchema, z.undefined()]).optional(),
proration: z.union([setupPaymentItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([setupPaymentItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([setupPaymentItemResetSchema, z.undefined()]).optional(),
price: z.union([setupPaymentItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([setupPaymentItemProrationSchema, z.undefined()])
.optional(),
rollover: z.union([setupPaymentItemRolloverSchema, z.undefined()]).optional(),
});
export const setupPaymentAddItemResetIntervalSchema = closedEnumSchema;
export const setupPaymentAddItemResetSchema = z.object({
interval: setupPaymentAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: setupPaymentAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemTierBehaviorSchema = closedEnumSchema;
@@ -299,14 +359,18 @@ export const setupPaymentAddItemPriceIntervalSchema = closedEnumSchema;
export const setupPaymentAddItemBillingMethodSchema = closedEnumSchema;
export const setupPaymentAddItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(setupPaymentAddItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([setupPaymentAddItemTierBehaviorSchema, z.undefined()]).optional(),
interval: setupPaymentAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: setupPaymentAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(setupPaymentAddItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([setupPaymentAddItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: setupPaymentAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: setupPaymentAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemOnIncreaseSchema = closedEnumSchema;
@@ -314,27 +378,31 @@ export const setupPaymentAddItemOnIncreaseSchema = closedEnumSchema;
export const setupPaymentAddItemOnDecreaseSchema = closedEnumSchema;
export const setupPaymentAddItemProrationSchema = z.object({
onIncrease: setupPaymentAddItemOnIncreaseSchema,
onDecrease: setupPaymentAddItemOnDecreaseSchema
onIncrease: setupPaymentAddItemOnIncreaseSchema,
onDecrease: setupPaymentAddItemOnDecreaseSchema,
});
export const setupPaymentAddItemExpiryDurationTypeSchema = closedEnumSchema;
export const setupPaymentAddItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: setupPaymentAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: setupPaymentAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const setupPaymentAddItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([setupPaymentAddItemResetSchema, z.undefined()]).optional(),
price: z.union([setupPaymentAddItemPriceSchema, z.undefined()]).optional(),
proration: z.union([setupPaymentAddItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([setupPaymentAddItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([setupPaymentAddItemResetSchema, z.undefined()]).optional(),
price: z.union([setupPaymentAddItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([setupPaymentAddItemProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([setupPaymentAddItemRolloverSchema, z.undefined()])
.optional(),
});
export const setupPaymentRemoveItemBillingMethodSchema = closedEnumSchema;
@@ -342,9 +410,13 @@ export const setupPaymentRemoveItemBillingMethodSchema = closedEnumSchema;
export const setupPaymentRemoveItemIntervalSchema = closedEnumSchema;
export const setupPaymentPlanItemFilterSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z.union([setupPaymentRemoveItemBillingMethodSchema, z.undefined()]).optional(),
interval: z.union([setupPaymentRemoveItemIntervalSchema, z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z
.union([setupPaymentRemoveItemBillingMethodSchema, z.undefined()])
.optional(),
interval: z
.union([setupPaymentRemoveItemIntervalSchema, z.undefined()])
.optional(),
});
export const setupPaymentDurationTypeSchema = closedEnumSchema;
@@ -352,43 +424,73 @@ export const setupPaymentDurationTypeSchema = closedEnumSchema;
export const setupPaymentOnEndSchema = closedEnumSchema;
export const setupPaymentFreeTrialParamsSchema = z.object({
durationLength: z.number(),
durationType: z.union([setupPaymentDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([setupPaymentOnEndSchema, z.undefined()]).optional()
durationLength: z.number(),
durationType: z
.union([setupPaymentDurationTypeSchema, z.undefined()])
.optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([setupPaymentOnEndSchema, z.undefined()]).optional(),
});
export const setupPaymentCustomizeSchema = z.object({
price: z.union([setupPaymentBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(setupPaymentItemPlanItemSchema), z.undefined()]).optional(),
addItems: z.union([z.array(setupPaymentAddItemPlanItemSchema), z.undefined()]).optional(),
removeItems: z.union([z.array(setupPaymentPlanItemFilterSchema), z.undefined()]).optional(),
freeTrial: z.union([setupPaymentFreeTrialParamsSchema, z.undefined()]).optional().nullable()
price: z
.union([setupPaymentBasePriceSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(setupPaymentItemPlanItemSchema), z.undefined()])
.optional(),
addItems: z
.union([z.array(setupPaymentAddItemPlanItemSchema), z.undefined()])
.optional(),
removeItems: z
.union([z.array(setupPaymentPlanItemFilterSchema), z.undefined()])
.optional(),
freeTrial: z
.union([setupPaymentFreeTrialParamsSchema, z.undefined()])
.optional()
.nullable(),
});
export const setupPaymentProrationBehaviorSchema = closedEnumSchema;
export const setupPaymentParamsSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.union([z.string(), z.undefined()]).optional(),
featureQuantities: z.union([z.array(setupPaymentFeatureQuantitySchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([setupPaymentCustomizeSchema, z.undefined()]).optional(),
prorationBehavior: z.union([setupPaymentProrationBehaviorSchema, z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(setupPaymentAttachDiscountSchema), z.undefined()]).optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
startsAt: z.union([z.number(), z.undefined()]).optional(),
endsAt: z.union([z.number(), z.undefined()]).optional(),
checkoutSessionParams: z.union([z.record(z.string(), z.any()), z.undefined()]).optional(),
customLineItems: z.union([z.array(setupPaymentCustomLineItemSchema), z.undefined()]).optional(),
processorSubscriptionId: z.union([z.string(), z.undefined()]).optional(),
carryOverBalances: z.union([setupPaymentCarryOverBalancesSchema, z.undefined()]).optional(),
carryOverUsages: z.union([setupPaymentCarryOverUsagesSchema, z.undefined()]).optional(),
metadata: z.union([z.record(z.string(), z.string()), z.undefined()]).optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
taxRateId: z.union([z.string(), z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.union([z.string(), z.undefined()]).optional(),
featureQuantities: z
.union([z.array(setupPaymentFeatureQuantitySchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([setupPaymentCustomizeSchema, z.undefined()]).optional(),
prorationBehavior: z
.union([setupPaymentProrationBehaviorSchema, z.undefined()])
.optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(setupPaymentAttachDiscountSchema), z.undefined()])
.optional(),
successUrl: z.union([z.string(), z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
startsAt: z.union([z.number(), z.undefined()]).optional(),
endsAt: z.union([z.number(), z.undefined()]).optional(),
checkoutSessionParams: z
.union([z.record(z.string(), z.any()), z.undefined()])
.optional(),
customLineItems: z
.union([z.array(setupPaymentCustomLineItemSchema), z.undefined()])
.optional(),
processorSubscriptionId: z.union([z.string(), z.undefined()]).optional(),
carryOverBalances: z
.union([setupPaymentCarryOverBalancesSchema, z.undefined()])
.optional(),
carryOverUsages: z
.union([setupPaymentCarryOverUsagesSchema, z.undefined()])
.optional(),
metadata: z
.union([z.record(z.string(), z.string()), z.undefined()])
.optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
taxRateId: z.union([z.string(), z.undefined()]).optional(),
});

View File

@@ -2,210 +2,258 @@
import { z } from "zod/v4";
export const billingUpdateGlobalsSchema = z.object({
xApiVersion: z.union([z.string(), z.undefined()]).optional()
xApiVersion: z.union([z.string(), z.undefined()]).optional(),
});
export const billingUpdateFeatureQuantitySchema = z.object({
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
featureId: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const billingUpdateItemToSchema = z.union([z.number(), z.string()]);
export const billingUpdateItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemToSchema = z.union([z.number(), z.string()]);
export const billingUpdateAddItemTierSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flatAmount: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateInvoiceModeSchema = z.object({
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional()
enabled: z.boolean(),
enablePlanImmediately: z.union([z.boolean(), z.undefined()]).optional(),
finalize: z.union([z.boolean(), z.undefined()]).optional(),
});
export const billingUpdateAttachDiscountSchema = z.object({
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional()
rewardId: z.union([z.string(), z.undefined()]).optional(),
promotionCode: z.union([z.string(), z.undefined()]).optional(),
});
export const billingUpdateRecalculateBalancesSchema = z.object({
enabled: z.boolean()
enabled: z.boolean(),
});
export const billingUpdateInvoiceSchema = z.object({
status: z.string().nullable(),
stripeId: z.string(),
total: z.number(),
currency: z.string(),
hostedInvoiceUrl: z.string().nullable()
status: z.string().nullable(),
stripeId: z.string(),
total: z.number(),
currency: z.string(),
hostedInvoiceUrl: z.string().nullable(),
});
export const billingUpdateFeatureQuantityOutboundSchema = z.object({
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional()
feature_id: z.string(),
quantity: z.union([z.number(), z.undefined()]).optional(),
adjustable: z.union([z.boolean(), z.undefined()]).optional(),
});
export const billingUpdateBasePriceOutboundSchema = z.object({
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemToOutboundSchema = z.union([z.number(), z.string()]);
export const billingUpdateItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const billingUpdateItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(billingUpdateItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(billingUpdateItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const billingUpdateItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([billingUpdateItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([billingUpdateItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([billingUpdateItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([billingUpdateItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([billingUpdateItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([billingUpdateItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([billingUpdateItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([billingUpdateItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const billingUpdateAddItemResetOutboundSchema = z.object({
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional()
interval: z.string(),
interval_count: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemToOutboundSchema = z.union([z.number(), z.string()]);
export const billingUpdateAddItemToOutboundSchema = z.union([
z.number(),
z.string(),
]);
export const billingUpdateAddItemTierOutboundSchema = z.object({
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional()
to: z.union([z.number(), z.string()]),
amount: z.union([z.number(), z.undefined()]).optional(),
flat_amount: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemPriceOutboundSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(billingUpdateAddItemTierOutboundSchema), z.undefined()]).optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(billingUpdateAddItemTierOutboundSchema), z.undefined()])
.optional(),
tier_behavior: z.union([z.string(), z.undefined()]).optional(),
interval: z.string(),
interval_count: z.number(),
billing_units: z.number(),
billing_method: z.string(),
max_purchase: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemProrationOutboundSchema = z.object({
on_increase: z.string(),
on_decrease: z.string()
on_increase: z.string(),
on_decrease: z.string(),
});
export const billingUpdateAddItemRolloverOutboundSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
max_percentage: z.union([z.number(), z.undefined()]).optional(),
expiry_duration_type: z.string(),
expiry_duration_length: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemPlanItemOutboundSchema = z.object({
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([billingUpdateAddItemResetOutboundSchema, z.undefined()]).optional(),
price: z.union([billingUpdateAddItemPriceOutboundSchema, z.undefined()]).optional(),
proration: z.union([billingUpdateAddItemProrationOutboundSchema, z.undefined()]).optional(),
rollover: z.union([billingUpdateAddItemRolloverOutboundSchema, z.undefined()]).optional()
feature_id: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z
.union([billingUpdateAddItemResetOutboundSchema, z.undefined()])
.optional(),
price: z
.union([billingUpdateAddItemPriceOutboundSchema, z.undefined()])
.optional(),
proration: z
.union([billingUpdateAddItemProrationOutboundSchema, z.undefined()])
.optional(),
rollover: z
.union([billingUpdateAddItemRolloverOutboundSchema, z.undefined()])
.optional(),
});
export const billingUpdatePlanItemFilterOutboundSchema = z.object({
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional()
feature_id: z.union([z.string(), z.undefined()]).optional(),
billing_method: z.union([z.string(), z.undefined()]).optional(),
interval: z.union([z.string(), z.undefined()]).optional(),
});
export const billingUpdateFreeTrialParamsOutboundSchema = z.object({
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional()
duration_length: z.number(),
duration_type: z.string(),
card_required: z.boolean(),
on_end: z.union([z.string(), z.undefined()]).optional(),
});
export const billingUpdateCustomizeOutboundSchema = z.object({
price: z.union([billingUpdateBasePriceOutboundSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(billingUpdateItemPlanItemOutboundSchema), z.undefined()]).optional(),
add_items: z.union([z.array(billingUpdateAddItemPlanItemOutboundSchema), z.undefined()]).optional(),
remove_items: z.union([z.array(billingUpdatePlanItemFilterOutboundSchema), z.undefined()]).optional(),
free_trial: z.union([billingUpdateFreeTrialParamsOutboundSchema, z.undefined()]).optional().nullable()
price: z
.union([billingUpdateBasePriceOutboundSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(billingUpdateItemPlanItemOutboundSchema), z.undefined()])
.optional(),
add_items: z
.union([z.array(billingUpdateAddItemPlanItemOutboundSchema), z.undefined()])
.optional(),
remove_items: z
.union([z.array(billingUpdatePlanItemFilterOutboundSchema), z.undefined()])
.optional(),
free_trial: z
.union([billingUpdateFreeTrialParamsOutboundSchema, z.undefined()])
.optional()
.nullable(),
});
export const billingUpdateInvoiceModeOutboundSchema = z.object({
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean()
enabled: z.boolean(),
enable_plan_immediately: z.boolean(),
finalize: z.boolean(),
});
export const billingUpdateAttachDiscountOutboundSchema = z.object({
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional()
reward_id: z.union([z.string(), z.undefined()]).optional(),
promotion_code: z.union([z.string(), z.undefined()]).optional(),
});
export const billingUpdateRecalculateBalancesOutboundSchema = z.object({
enabled: z.boolean()
enabled: z.boolean(),
});
export const updateSubscriptionParamsOutboundSchema = z.object({
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.union([z.string(), z.undefined()]).optional(),
feature_quantities: z.union([z.array(billingUpdateFeatureQuantityOutboundSchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([billingUpdateCustomizeOutboundSchema, z.undefined()]).optional(),
invoice_mode: z.union([billingUpdateInvoiceModeOutboundSchema, z.undefined()]).optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(billingUpdateAttachDiscountOutboundSchema), z.undefined()]).optional(),
cancel_action: z.union([z.string(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
recalculate_balances: z.union([billingUpdateRecalculateBalancesOutboundSchema, z.undefined()]).optional()
customer_id: z.string(),
entity_id: z.union([z.string(), z.undefined()]).optional(),
plan_id: z.union([z.string(), z.undefined()]).optional(),
feature_quantities: z
.union([z.array(billingUpdateFeatureQuantityOutboundSchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z
.union([billingUpdateCustomizeOutboundSchema, z.undefined()])
.optional(),
invoice_mode: z
.union([billingUpdateInvoiceModeOutboundSchema, z.undefined()])
.optional(),
proration_behavior: z.union([z.string(), z.undefined()]).optional(),
redirect_mode: z.string(),
subscription_id: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(billingUpdateAttachDiscountOutboundSchema), z.undefined()])
.optional(),
cancel_action: z.union([z.string(), z.undefined()]).optional(),
billing_cycle_anchor: z.union([z.literal("now"), z.undefined()]).optional(),
no_billing_changes: z.union([z.boolean(), z.undefined()]).optional(),
recalculate_balances: z
.union([billingUpdateRecalculateBalancesOutboundSchema, z.undefined()])
.optional(),
});
const closedEnumSchema = z.any();
@@ -215,16 +263,16 @@ const openEnumSchema = z.any();
export const billingUpdatePriceIntervalSchema = closedEnumSchema;
export const billingUpdateBasePriceSchema = z.object({
amount: z.number(),
interval: billingUpdatePriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
amount: z.number(),
interval: billingUpdatePriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemResetIntervalSchema = closedEnumSchema;
export const billingUpdateItemResetSchema = z.object({
interval: billingUpdateItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: billingUpdateItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemTierBehaviorSchema = closedEnumSchema;
@@ -234,14 +282,18 @@ export const billingUpdateItemPriceIntervalSchema = closedEnumSchema;
export const billingUpdateItemBillingMethodSchema = closedEnumSchema;
export const billingUpdateItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(billingUpdateItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([billingUpdateItemTierBehaviorSchema, z.undefined()]).optional(),
interval: billingUpdateItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: billingUpdateItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(billingUpdateItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([billingUpdateItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: billingUpdateItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: billingUpdateItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemOnIncreaseSchema = closedEnumSchema;
@@ -249,34 +301,38 @@ export const billingUpdateItemOnIncreaseSchema = closedEnumSchema;
export const billingUpdateItemOnDecreaseSchema = closedEnumSchema;
export const billingUpdateItemProrationSchema = z.object({
onIncrease: billingUpdateItemOnIncreaseSchema,
onDecrease: billingUpdateItemOnDecreaseSchema
onIncrease: billingUpdateItemOnIncreaseSchema,
onDecrease: billingUpdateItemOnDecreaseSchema,
});
export const billingUpdateItemExpiryDurationTypeSchema = closedEnumSchema;
export const billingUpdateItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: billingUpdateItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: billingUpdateItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([billingUpdateItemResetSchema, z.undefined()]).optional(),
price: z.union([billingUpdateItemPriceSchema, z.undefined()]).optional(),
proration: z.union([billingUpdateItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([billingUpdateItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([billingUpdateItemResetSchema, z.undefined()]).optional(),
price: z.union([billingUpdateItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([billingUpdateItemProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([billingUpdateItemRolloverSchema, z.undefined()])
.optional(),
});
export const billingUpdateAddItemResetIntervalSchema = closedEnumSchema;
export const billingUpdateAddItemResetSchema = z.object({
interval: billingUpdateAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional()
interval: billingUpdateAddItemResetIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemTierBehaviorSchema = closedEnumSchema;
@@ -286,14 +342,18 @@ export const billingUpdateAddItemPriceIntervalSchema = closedEnumSchema;
export const billingUpdateAddItemBillingMethodSchema = closedEnumSchema;
export const billingUpdateAddItemPriceSchema = z.object({
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z.union([z.array(billingUpdateAddItemTierSchema), z.undefined()]).optional(),
tierBehavior: z.union([billingUpdateAddItemTierBehaviorSchema, z.undefined()]).optional(),
interval: billingUpdateAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: billingUpdateAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional()
amount: z.union([z.number(), z.undefined()]).optional(),
tiers: z
.union([z.array(billingUpdateAddItemTierSchema), z.undefined()])
.optional(),
tierBehavior: z
.union([billingUpdateAddItemTierBehaviorSchema, z.undefined()])
.optional(),
interval: billingUpdateAddItemPriceIntervalSchema,
intervalCount: z.union([z.number(), z.undefined()]).optional(),
billingUnits: z.union([z.number(), z.undefined()]).optional(),
billingMethod: billingUpdateAddItemBillingMethodSchema,
maxPurchase: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemOnIncreaseSchema = closedEnumSchema;
@@ -301,27 +361,31 @@ export const billingUpdateAddItemOnIncreaseSchema = closedEnumSchema;
export const billingUpdateAddItemOnDecreaseSchema = closedEnumSchema;
export const billingUpdateAddItemProrationSchema = z.object({
onIncrease: billingUpdateAddItemOnIncreaseSchema,
onDecrease: billingUpdateAddItemOnDecreaseSchema
onIncrease: billingUpdateAddItemOnIncreaseSchema,
onDecrease: billingUpdateAddItemOnDecreaseSchema,
});
export const billingUpdateAddItemExpiryDurationTypeSchema = closedEnumSchema;
export const billingUpdateAddItemRolloverSchema = z.object({
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: billingUpdateAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional()
max: z.union([z.number(), z.undefined()]).optional(),
maxPercentage: z.union([z.number(), z.undefined()]).optional(),
expiryDurationType: billingUpdateAddItemExpiryDurationTypeSchema,
expiryDurationLength: z.union([z.number(), z.undefined()]).optional(),
});
export const billingUpdateAddItemPlanItemSchema = z.object({
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([billingUpdateAddItemResetSchema, z.undefined()]).optional(),
price: z.union([billingUpdateAddItemPriceSchema, z.undefined()]).optional(),
proration: z.union([billingUpdateAddItemProrationSchema, z.undefined()]).optional(),
rollover: z.union([billingUpdateAddItemRolloverSchema, z.undefined()]).optional()
featureId: z.string(),
included: z.union([z.number(), z.undefined()]).optional(),
unlimited: z.union([z.boolean(), z.undefined()]).optional(),
reset: z.union([billingUpdateAddItemResetSchema, z.undefined()]).optional(),
price: z.union([billingUpdateAddItemPriceSchema, z.undefined()]).optional(),
proration: z
.union([billingUpdateAddItemProrationSchema, z.undefined()])
.optional(),
rollover: z
.union([billingUpdateAddItemRolloverSchema, z.undefined()])
.optional(),
});
export const billingUpdateRemoveItemBillingMethodSchema = closedEnumSchema;
@@ -329,9 +393,13 @@ export const billingUpdateRemoveItemBillingMethodSchema = closedEnumSchema;
export const billingUpdateRemoveItemIntervalSchema = closedEnumSchema;
export const billingUpdatePlanItemFilterSchema = z.object({
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z.union([billingUpdateRemoveItemBillingMethodSchema, z.undefined()]).optional(),
interval: z.union([billingUpdateRemoveItemIntervalSchema, z.undefined()]).optional()
featureId: z.union([z.string(), z.undefined()]).optional(),
billingMethod: z
.union([billingUpdateRemoveItemBillingMethodSchema, z.undefined()])
.optional(),
interval: z
.union([billingUpdateRemoveItemIntervalSchema, z.undefined()])
.optional(),
});
export const billingUpdateDurationTypeSchema = closedEnumSchema;
@@ -339,18 +407,32 @@ export const billingUpdateDurationTypeSchema = closedEnumSchema;
export const billingUpdateOnEndSchema = closedEnumSchema;
export const billingUpdateFreeTrialParamsSchema = z.object({
durationLength: z.number(),
durationType: z.union([billingUpdateDurationTypeSchema, z.undefined()]).optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([billingUpdateOnEndSchema, z.undefined()]).optional()
durationLength: z.number(),
durationType: z
.union([billingUpdateDurationTypeSchema, z.undefined()])
.optional(),
cardRequired: z.union([z.boolean(), z.undefined()]).optional(),
onEnd: z.union([billingUpdateOnEndSchema, z.undefined()]).optional(),
});
export const billingUpdateCustomizeSchema = z.object({
price: z.union([billingUpdateBasePriceSchema, z.undefined()]).optional().nullable(),
items: z.union([z.array(billingUpdateItemPlanItemSchema), z.undefined()]).optional(),
addItems: z.union([z.array(billingUpdateAddItemPlanItemSchema), z.undefined()]).optional(),
removeItems: z.union([z.array(billingUpdatePlanItemFilterSchema), z.undefined()]).optional(),
freeTrial: z.union([billingUpdateFreeTrialParamsSchema, z.undefined()]).optional().nullable()
price: z
.union([billingUpdateBasePriceSchema, z.undefined()])
.optional()
.nullable(),
items: z
.union([z.array(billingUpdateItemPlanItemSchema), z.undefined()])
.optional(),
addItems: z
.union([z.array(billingUpdateAddItemPlanItemSchema), z.undefined()])
.optional(),
removeItems: z
.union([z.array(billingUpdatePlanItemFilterSchema), z.undefined()])
.optional(),
freeTrial: z
.union([billingUpdateFreeTrialParamsSchema, z.undefined()])
.optional()
.nullable(),
});
export const billingUpdateProrationBehaviorSchema = closedEnumSchema;
@@ -360,34 +442,50 @@ export const billingUpdateRedirectModeSchema = closedEnumSchema;
export const billingUpdateCancelActionSchema = closedEnumSchema;
export const updateSubscriptionParamsSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.union([z.string(), z.undefined()]).optional(),
featureQuantities: z.union([z.array(billingUpdateFeatureQuantitySchema), z.undefined()]).optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([billingUpdateCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z.union([billingUpdateInvoiceModeSchema, z.undefined()]).optional(),
prorationBehavior: z.union([billingUpdateProrationBehaviorSchema, z.undefined()]).optional(),
redirectMode: z.union([billingUpdateRedirectModeSchema, z.undefined()]).optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z.union([z.array(billingUpdateAttachDiscountSchema), z.undefined()]).optional(),
cancelAction: z.union([billingUpdateCancelActionSchema, z.undefined()]).optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
recalculateBalances: z.union([billingUpdateRecalculateBalancesSchema, z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
planId: z.union([z.string(), z.undefined()]).optional(),
featureQuantities: z
.union([z.array(billingUpdateFeatureQuantitySchema), z.undefined()])
.optional(),
version: z.union([z.number(), z.undefined()]).optional(),
customize: z.union([billingUpdateCustomizeSchema, z.undefined()]).optional(),
invoiceMode: z
.union([billingUpdateInvoiceModeSchema, z.undefined()])
.optional(),
prorationBehavior: z
.union([billingUpdateProrationBehaviorSchema, z.undefined()])
.optional(),
redirectMode: z
.union([billingUpdateRedirectModeSchema, z.undefined()])
.optional(),
subscriptionId: z.union([z.string(), z.undefined()]).optional(),
discounts: z
.union([z.array(billingUpdateAttachDiscountSchema), z.undefined()])
.optional(),
cancelAction: z
.union([billingUpdateCancelActionSchema, z.undefined()])
.optional(),
billingCycleAnchor: z.union([z.literal("now"), z.undefined()]).optional(),
noBillingChanges: z.union([z.boolean(), z.undefined()]).optional(),
recalculateBalances: z
.union([billingUpdateRecalculateBalancesSchema, z.undefined()])
.optional(),
});
export const billingUpdateCodeSchema = openEnumSchema;
export const billingUpdateRequiredActionSchema = z.object({
code: billingUpdateCodeSchema,
reason: z.string()
code: billingUpdateCodeSchema,
reason: z.string(),
});
export const billingUpdateResponseSchema = z.object({
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
invoice: z.union([billingUpdateInvoiceSchema, z.undefined()]).optional(),
paymentUrl: z.string().nullable(),
requiredAction: z.union([billingUpdateRequiredActionSchema, z.undefined()]).optional()
customerId: z.string(),
entityId: z.union([z.string(), z.undefined()]).optional(),
invoice: z.union([billingUpdateInvoiceSchema, z.undefined()]).optional(),
paymentUrl: z.string().nullable(),
requiredAction: z
.union([billingUpdateRequiredActionSchema, z.undefined()])
.optional(),
});

13
packages/mcp/.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
**/.speakeasy/logs/
**/.speakeasy/reports/
**/.speakeasy/temp/
/.eslintcache
/.tsbuildinfo
/bin
/esm
/node_modules
bun.lock
.DS_Store
.env
.env.local
*.mcpb

70
packages/mcp/README.md Normal file
View File

@@ -0,0 +1,70 @@
# Autumn MCP
Mastra-backed MCP library for Autumn operations.
The hosted runtime lives in `apps/mcp-server` and exposes two Streamable HTTP
MCP routes:
- `/mcp` - public, API-shaped operational tools.
- `/internal/mcp` - internal Autumn agent tool.
## `/mcp`
Use this for external MCP clients that should call Autumn operations directly.
Tools:
- `listCustomers`
- `getCustomer`
- `listPlans`
- `getPlan`
- `previewAttach`
- `attach`
- `previewUpdateSubscription`
- `updateSubscription`
The write tools are marked destructive. Clients should call the matching preview
tool first and only call a write tool after explicit user confirmation.
## `/internal/mcp`
Use this for Autumn-controlled agent flows.
Tools:
- `ask_autumn({ message, context? })`
`ask_autumn` can look up customers/plans, inspect scoped Axiom logs when
available, preview billing changes, and apply confirmed billing writes. Billing
writes are preview-first: the server stores the pending action internally and
executes it only after a follow-up confirmation.
## Local
From the repo root:
```sh
bun run mcp
```
This starts both MCP routes:
- `http://localhost:2718/mcp`
- `http://localhost:2718/internal/mcp`
OAuth metadata is route-aware:
- `http://localhost:2718/.well-known/oauth-protected-resource/mcp`
- `http://localhost:2718/.well-known/oauth-protected-resource/internal/mcp`
OAuth uses the Autumn Better Auth issuer from `--server-url`:
OAuth uses the Autumn Better Auth issuer from `MCP_SERVER_URL`:
- local default: `http://localhost:8080/api/auth`
- production default: `https://api.useautumn.com/api/auth`
For production-like local testing:
```sh
MCP_SERVER_URL=https://api.useautumn.com bun -F @autumn/mcp-server start
```

35
packages/mcp/package.json Normal file
View File

@@ -0,0 +1,35 @@
{
"name": "@autumn/mcp",
"version": "0.0.1",
"author": "Autumn",
"type": "module",
"sideEffects": false,
"exports": {
".": "./src/index.ts"
},
"files": [
"README.md",
"src"
],
"scripts": {
"build": "tsc",
"ts": "tsc --noEmit",
"test": "bun test src",
"prepack": "bun run build",
"prepublishOnly": "bun run build"
},
"dependencies": {
"@autumn/shared": "workspace:*",
"@axiomhq/js": "^1.6.1",
"@mastra/core": "^1.36.0",
"@mastra/mcp": "^1.8.0",
"date-fns": "^4.1.0",
"ioredis": "^5.5.0",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/bun": "^1.2.13",
"@types/node": "^18.19.3",
"typescript": "~5.8.3"
}
}

19
packages/mcp/src/index.ts Normal file
View File

@@ -0,0 +1,19 @@
export {
consoleLoggerLevels,
createConsoleLogger,
type ConsoleLogger,
type ConsoleLoggerLevel,
} from "./mcp-server/console-logger.js";
export {
createAskAutumnMCPServer,
createAutumnOperationsMCPServer,
createMCPServer,
} from "./mcp-server/agent/server.js";
export type { MCPServerFlags } from "./mcp-server/flags.js";
export {
buildAuthForRequest,
getAuthorizationServerMetadata,
getProtectedResourceMetadata,
OAuthHttpError,
type OAuthEnvironment,
} from "./mcp-server/oauth.js";

View File

@@ -0,0 +1,242 @@
import { describe, expect, mock, test } from "bun:test";
import type { AutumnMcpAuth } from "./auth.js";
import { setPendingActionsRedis } from "./pending-actions.js";
import { createTestRedis } from "./test-redis.js";
const systemPrompts: string[] = [];
let agentConfirms = true;
let agentCalls = 0;
mock.module("@mastra/core/agent", () => ({
Agent: class {
private readonly tools: Record<string, { execute?: Function }>;
constructor(config: { tools: Record<string, { execute?: Function }> }) {
this.tools = config.tools;
}
async generate(
message: string,
options: {
requestContext: unknown;
context: { content: string }[];
},
) {
agentCalls += 1;
const systemPrompt = options.context[0]?.content ?? "";
systemPrompts.push(systemPrompt);
const context = { requestContext: options.requestContext };
if (message.toLowerCase().includes("customers")) {
const result = await this.tools.listCustomers.execute?.(
{ request: {} },
context,
);
return { text: JSON.stringify(result) };
}
if (agentConfirms && systemPrompt.includes("Pending billing action")) {
const result = await this.tools.confirmBillingAction.execute?.(
{},
context,
);
return { text: JSON.stringify(result) };
}
if (systemPrompt.includes("Pending billing action")) {
return { text: "There is no pending billing action to confirm." };
}
const result = await this.tools.previewAttach.execute?.(
{ request: { customer_id: "cus_1", plan_id: "pro" } },
context,
);
return { text: JSON.stringify(result) };
}
},
}));
const { createAskAutumnTool } = await import("./ask-autumn.js");
const auth: AutumnMcpAuth = {
apiKey: "sk_test",
env: "sandbox",
principalId: "user_1",
resource: "http://localhost:2718/mcp",
scopes: ["billing:read", "billing:write"],
serverURL: "http://localhost:8080",
};
const mockFetch = (calls: { url: string; body: unknown }[]) => {
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (url, init) => {
const body = JSON.parse(init?.body as string);
calls.push({ url: String(url), body });
if (String(url).endsWith("/v1/billing.preview_attach")) {
return Response.json({ total: 50 });
}
if (String(url).endsWith("/v1/billing.attach")) {
return Response.json({ applied: true });
}
if (String(url).endsWith("/v1/customers.list")) {
return Response.json({ customers: [] });
}
return Response.json({ error: "unexpected" }, { status: 500 });
}) as typeof fetch;
return () => {
globalThis.fetch = originalFetch;
};
};
describe("ask_autumn billing confirmation flow", () => {
test("confirms a pending attach across separate ask_autumn calls", async () => {
setPendingActionsRedis(createTestRedis());
systemPrompts.length = 0;
agentConfirms = true;
agentCalls = 0;
const calls: { url: string; body: unknown }[] = [];
const restoreFetch = mockFetch(calls);
try {
const tool = createAskAutumnTool();
if (!tool.execute) throw new Error("ask_autumn is not executable");
const context = { mcp: { extra: { authInfo: auth } } } as never;
const preview = await tool.execute(
{ message: "attach pro to cus_1" },
context,
);
expect(String(preview)).toContain("Preview ready");
expect(systemPrompts.at(-1)).not.toContain("Pending billing action");
expect(calls.map((call) => call.url)).toEqual([
"http://localhost:8080/v1/billing.preview_attach",
]);
const confirm = await tool.execute({ message: "confirm" }, context);
expect(String(confirm)).toContain("Confirmed and applied attach.");
expect(calls).toEqual([
{
url: "http://localhost:8080/v1/billing.preview_attach",
body: {
customer_id: "cus_1",
plan_id: "pro",
redirect_mode: "if_required",
},
},
{
url: "http://localhost:8080/v1/billing.attach",
body: {
customer_id: "cus_1",
plan_id: "pro",
redirect_mode: "if_required",
},
},
]);
} finally {
restoreFetch();
}
});
test("semantic confirmation gets the pending preview context", async () => {
setPendingActionsRedis(createTestRedis());
systemPrompts.length = 0;
agentConfirms = true;
agentCalls = 0;
const calls: { url: string; body: unknown }[] = [];
const restoreFetch = mockFetch(calls);
try {
const tool = createAskAutumnTool();
if (!tool.execute) throw new Error("ask_autumn is not executable");
const context = { mcp: { extra: { authInfo: auth } } } as never;
await tool.execute({ message: "attach pro to cus_1" }, context);
expect(agentCalls).toBe(1);
const confirm = await tool.execute(
{ message: "that looks good, go ahead" },
context,
);
expect(String(confirm)).toContain("Confirmed and applied attach.");
expect(agentCalls).toBe(2);
expect(systemPrompts.at(-1)).toContain("Pending billing action:");
expect(systemPrompts.at(-1)).toContain("Preview:");
expect(systemPrompts.at(-1)).toContain('"total":50');
expect(calls.map((call) => call.url)).toEqual([
"http://localhost:8080/v1/billing.preview_attach",
"http://localhost:8080/v1/billing.attach",
]);
} finally {
restoreFetch();
}
});
test("question-like confirmation text does not bypass the agent", async () => {
setPendingActionsRedis(createTestRedis());
systemPrompts.length = 0;
agentConfirms = false;
agentCalls = 0;
const calls: { url: string; body: unknown }[] = [];
const restoreFetch = mockFetch(calls);
try {
const tool = createAskAutumnTool();
if (!tool.execute) throw new Error("ask_autumn is not executable");
const context = { mcp: { extra: { authInfo: auth } } } as never;
await tool.execute({ message: "attach pro to cus_1" }, context);
const response = await tool.execute(
{ message: "can you confirm what this changes?" },
context,
);
expect(String(response)).toContain("no pending billing action");
expect(agentCalls).toBe(2);
expect(systemPrompts.at(-1)).toContain("Pending billing action:");
expect(calls.map((call) => call.url)).toEqual([
"http://localhost:8080/v1/billing.preview_attach",
]);
} finally {
restoreFetch();
}
});
test("read requests continue when pending lookup fails", async () => {
setPendingActionsRedis({
multi: () => {
throw new Error("unavailable");
},
get: async () => {
throw new Error("unavailable");
},
getdel: async () => {
throw new Error("unavailable");
},
del: async () => undefined,
keys: async () => [],
});
systemPrompts.length = 0;
agentConfirms = true;
agentCalls = 0;
const calls: { url: string; body: unknown }[] = [];
const restoreFetch = mockFetch(calls);
try {
const tool = createAskAutumnTool();
if (!tool.execute) throw new Error("ask_autumn is not executable");
const context = { mcp: { extra: { authInfo: auth } } } as never;
const response = await tool.execute({ message: "list customers" }, context);
expect(String(response)).toContain("customers");
expect(agentCalls).toBe(1);
expect(calls.map((call) => call.url)).toEqual([
"http://localhost:8080/v1/customers.list",
]);
} finally {
restoreFetch();
}
});
});

View File

@@ -0,0 +1,111 @@
import { Agent } from "@mastra/core/agent";
import { createTool } from "@mastra/core/tools";
import * as z from "zod/v4";
import {
type AutumnMcpAuth,
createRequestContext,
getAutumnAuth,
} from "./auth.js";
import { getLatestPendingAction } from "./pending-actions.js";
import { createAgentAutumnOperationTools } from "./tools.js";
const model = "anthropic/claude-sonnet-4-6";
const instructions = `You are Autumn's operational billing assistant.
Use Autumn tools for customer, plan, and billing work.
Use Axiom tools only for read-only investigation of Autumn logs.
Rules:
- Read requests can be answered directly.
- For customer lookup, use listCustomers first when the id/email/name is ambiguous.
- For plan lookup, use listPlans first when the plan is ambiguous.
- For billing changes, call previewAttach or previewUpdateSubscription first. These preview tools automatically create the pending billing action.
- Never expose internal ids or server bookkeeping details.
- After a billing preview, tell the user to explicitly apply or approve the exact previewed change.
- If the user semantically confirms, applies, or approves a billing preview, call confirmBillingAction even if the preview is not visible in the current message. The tool validates whether a pending action exists.
- Never claim a billing write has been applied unless confirmBillingAction succeeds.
- If customer, plan, entity, subscription, or environment is ambiguous, ask a short clarifying question.
- Keep responses concise. Use JSON only when it materially helps debugging.`;
// To be added when we add axiom:
// - For log investigations, start with narrow structured fields such as context.customer_id, context.org_slug, req.url, req.id, stripe_event.id, stripe_event.type, workflow.id, or workflow.name.
// - For wide log windows, use a cheap aggregate query first, then focused <= 1 hour queries. Prefer ERROR/WARN levels first.
// - Axiom queries are already scoped to the authenticated org and environment; do not add or mention separate org filters unless useful to explain the investigation.
// - Axiom tools are read-only and must never be used as part of a billing confirmation or write flow.
const createAgent = () =>
new Agent({
id: "autumn-ops",
name: "Autumn Ops",
description:
"Answers Autumn customer, plan, and billing questions using controlled Autumn operations.",
instructions,
model,
tools: createAgentAutumnOperationTools(),
});
const getAuth = (
toolContext: Parameters<
NonNullable<ReturnType<typeof createTool>["execute"]>
>[1],
defaultAuth?: AutumnMcpAuth,
) => {
try {
return getAutumnAuth(toolContext);
} catch (error) {
if (defaultAuth) return defaultAuth;
throw error;
}
};
const getPendingAction = async (auth: AutumnMcpAuth) => {
try {
return await getLatestPendingAction(auth);
} catch {
return null;
}
};
export const createAskAutumnTool = (defaultAuth?: AutumnMcpAuth) =>
createTool({
id: "ask_autumn",
description:
"Ask Autumn to look up customers/plans or safely preview and confirm billing changes.",
inputSchema: z.object({
message: z.string().min(1),
context: z.record(z.string(), z.unknown()).optional(),
}),
mcp: {
annotations: {
title: "Ask Autumn",
readOnlyHint: false,
destructiveHint: true,
idempotentHint: false,
openWorldHint: false,
},
},
execute: async ({ message, context }, toolContext) => {
const auth = getAuth(toolContext, defaultAuth);
const pendingAction = await getPendingAction(auth);
const contextText = context
? `\n\nCaller context:\n${JSON.stringify(context, null, 2)}`
: "";
const pendingText = pendingAction
? `\n\nPending billing action:\nTool: ${pendingAction.toolName}\nPreview: ${pendingAction.preview}\nIf the user confirms this preview, call confirmBillingAction.`
: "";
const output = await createAgent().generate(message, {
maxSteps: 8,
requestContext: createRequestContext(auth),
context: [
{
role: "system",
content: `Current Autumn environment: ${auth.env}.${pendingText}${contextText}`,
},
],
});
return output.text;
},
});
export const askAutumnTool = createAskAutumnTool();

View File

@@ -0,0 +1,53 @@
import { createHash } from "node:crypto";
import { RequestContext } from "@mastra/core/request-context";
import type { ToolExecutionContext } from "@mastra/core/tools";
import type { OAuthEnvironment } from "../oauth.js";
export type AutumnMcpAuth = {
apiKey: string;
env: OAuthEnvironment;
principalId: string;
resource: string;
scopes: string[];
orgId?: string | undefined;
serverURL?: string | undefined;
xApiVersion?: string | undefined;
failOpen?: boolean | undefined;
};
type MaybeToolContext = Pick<ToolExecutionContext, "mcp" | "requestContext">;
const hash = (value: string) =>
createHash("sha256").update(value).digest("hex").slice(0, 32);
export const principalFromSecret = (kind: string, value: string) =>
`${kind}:${hash(value)}`;
export const createAutumnClient = (auth: AutumnMcpAuth) => ({
baseUrl: auth.serverURL ?? "https://api.useautumn.com",
headers: {
Authorization: `Bearer ${auth.apiKey}`,
"Content-Type": "application/json",
Accept: "application/json",
"x-api-version": auth.xApiVersion ?? "2.3.0",
...(auth.failOpen === undefined
? {}
: { "fail-open": String(auth.failOpen) }),
},
});
export const getAutumnAuth = (context?: MaybeToolContext): AutumnMcpAuth => {
const direct = context?.mcp?.extra?.authInfo as AutumnMcpAuth | undefined;
const nested = context?.requestContext?.get?.("mcp.extra") as
| { authInfo?: AutumnMcpAuth }
| undefined;
const auth = direct ?? nested?.authInfo;
if (!auth?.apiKey) throw new Error("Autumn MCP authentication is required.");
return auth;
};
export const createRequestContext = (auth: AutumnMcpAuth) => {
const requestContext = new RequestContext();
requestContext.set("mcp.extra", { authInfo: auth });
return requestContext;
};

View File

@@ -0,0 +1,100 @@
import { describe, expect, test } from "bun:test";
import { Scopes } from "@autumn/shared/scopeDefinitions";
import type { AutumnMcpAuth } from "./auth.js";
import { prepareAxiomQuery, resolveAutumnOrgId } from "./axiom.js";
const auth: AutumnMcpAuth & { orgId: string } = {
apiKey: "sk_test",
env: "sandbox",
principalId: "test",
resource: "http://localhost:2718/mcp",
scopes: [Scopes.Analytics.Read],
orgId: "org_123",
};
describe("Axiom MCP tools", () => {
test("injects authenticated org and env filters after the express source", () => {
const query = prepareAxiomQuery({
auth,
apl: "['express'] | where ['level'] == 'ERROR' | limit 10",
startTime: "now-30m",
endTime: "now",
});
expect(query.apl).toBe(
[
"['express']",
"| where ['context.org_id'] == 'org_123'",
"| where ['context.env'] == 'sandbox'",
"| where ['level'] == 'ERROR' | limit 10",
].join("\n"),
);
});
test("rejects unsafe APL shapes", () => {
expect(() =>
prepareAxiomQuery({
auth,
apl: "['express'] | union ['other']",
}),
).toThrow("query shape is not allowed");
expect(() =>
prepareAxiomQuery({
auth,
apl: "['other'] | limit 10",
}),
).toThrow("must start from ['express']");
expect(() =>
prepareAxiomQuery({
auth,
apl: "['express'] | ['other'] | limit 10",
}),
).toThrow("only use the express dataset source once");
});
test("rejects malformed time ranges that produce invalid dates", () => {
expect(() =>
prepareAxiomQuery({
auth,
apl: "['express'] | limit 10",
startTime: "now-999999999999999999999999999999999999999999999999d",
endTime: "now",
}),
).toThrow("bounded time range");
});
test("rejects Axiom access without analytics read scope", () => {
expect(() =>
prepareAxiomQuery({
auth: { ...auth, scopes: [] },
apl: "['express'] | limit 10",
}),
).toThrow("analytics:read scope is required");
});
test("resolves static API-key auth to an Autumn org", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (url, init) => {
expect(String(url)).toBe("http://localhost:8080/v1/organization");
expect(init?.headers).toMatchObject({
Authorization: "Bearer sk_static",
});
return Response.json({ id: "org_static", slug: "static-org" });
}) as typeof fetch;
try {
await expect(
resolveAutumnOrgId({
...auth,
apiKey: "sk_static",
orgId: undefined,
serverURL: "http://localhost:8080",
}),
).resolves.toBe("org_static");
} finally {
globalThis.fetch = originalFetch;
}
});
});

View File

@@ -0,0 +1,222 @@
import { createHash } from "node:crypto";
import { Axiom } from "@axiomhq/js";
import { createTool } from "@mastra/core/tools";
import {
add,
addMilliseconds,
differenceInMilliseconds,
isFuture,
isValid,
parseISO,
} from "date-fns";
import {
makeScopeChecker,
Scopes,
type ScopeString,
} from "@autumn/shared/scopeDefinitions";
import { ms } from "@autumn/shared/unixUtils";
import * as z from "zod/v4";
import {
createAutumnClient,
getAutumnAuth,
type AutumnMcpAuth,
} from "./auth.js";
const axiomDataset = "express";
const defaultStartTime = "now-30m";
const defaultEndTime = "now";
const maxRangeMs = ms.days(7);
const searchMaxRangeMs = ms.hours(1);
let axiomClient: Axiom | null = null;
const orgCache = new Map<string, { orgId: string; expiresAt: Date }>();
const getAxiomClient = () => {
if (!process.env.AXIOM_ADMIN_TOKEN) {
throw new Error("Axiom is not configured (AXIOM_ADMIN_TOKEN missing).");
}
axiomClient ??= new Axiom({
token: process.env.AXIOM_ADMIN_TOKEN,
orgId: process.env.AXIOM_ORG_ID,
});
return axiomClient;
};
const escapeAplString = (value: string) =>
value.replaceAll("\\", "\\\\").replaceAll("'", "\\'");
const hash = (value: string) =>
createHash("sha256").update(value).digest("hex").slice(0, 32);
const parseAxiomTime = (value: string, now = new Date()) => {
if (value === "now") return now;
const relative = value.match(/^now-(\d+)([mhd])$/);
if (relative) {
const count = Number(relative[1]);
if (!Number.isFinite(count)) return null;
const unit = relative[2];
const date = add(now, {
minutes: unit === "m" ? -count : 0,
hours: unit === "h" ? -count : 0,
days: unit === "d" ? -count : 0,
});
return isValid(date) ? date : null;
}
const absolute = parseISO(value);
return isValid(absolute) ? absolute : null;
};
const getRangeMs = (startTime: string, endTime: string) => {
const start = parseAxiomTime(startTime);
const end = parseAxiomTime(endTime);
if (start === null || end === null) return null;
const rangeMs = differenceInMilliseconds(end, start);
return Number.isFinite(rangeMs) ? rangeMs : null;
};
const assertCanUseAxiom = (auth: AutumnMcpAuth) => {
if (!makeScopeChecker(auth.scopes).has(Scopes.Analytics.Read as ScopeString)) {
throw new Error("analytics:read scope is required to query Axiom logs.");
}
};
export const resolveAutumnOrgId = async (auth: AutumnMcpAuth) => {
if (auth.orgId) return auth.orgId;
const cacheKey = [
auth.serverURL ?? "https://api.useautumn.com",
auth.env,
hash(auth.apiKey),
auth.xApiVersion ?? "2.3.0",
String(auth.failOpen),
].join(":");
const cached = orgCache.get(cacheKey);
if (cached && isFuture(cached.expiresAt)) return cached.orgId;
const client = createAutumnClient(auth);
const response = await fetch(new URL("/v1/organization", client.baseUrl), {
method: "GET",
headers: client.headers,
});
if (!response.ok) {
throw new Error("Could not resolve Autumn organization for MCP request.");
}
const body = (await response.json()) as { id?: unknown };
if (typeof body.id !== "string" || !body.id) {
throw new Error("Autumn organization response did not include an id.");
}
orgCache.set(cacheKey, {
orgId: body.id,
expiresAt: addMilliseconds(new Date(), ms.minutes(5)),
});
return body.id;
};
export const prepareAxiomQuery = ({
auth,
apl,
startTime = defaultStartTime,
endTime = defaultEndTime,
}: {
auth: AutumnMcpAuth & { orgId: string };
apl: string;
startTime?: string | undefined;
endTime?: string | undefined;
}) => {
assertCanUseAxiom(auth);
const rangeMs = getRangeMs(startTime, endTime);
if (rangeMs === null || rangeMs <= 0 || rangeMs > maxRangeMs) {
throw new Error("Axiom queries must use a bounded time range of at most 7 days.");
}
const trimmed = apl.trim();
const source = trimmed.match(/^\[\s*(['"])express\1\s*\](.*)$/is);
if (!source) {
throw new Error("Axiom queries must start from ['express'].");
}
const rest = source[2].trim();
if (rest && !rest.startsWith("|")) {
throw new Error("Axiom queries must pipe from the express dataset source.");
}
if (/\b(union|join|fork|lookup)\b/i.test(rest)) {
throw new Error("Axiom query shape is not allowed.");
}
if (/\|\s*\[\s*['"][^'"]+['"]\s*\](?=\s*(?:\||$))/i.test(rest)) {
throw new Error("Axiom queries may only use the express dataset source once.");
}
if (/\bsearch\b/i.test(rest) && rangeMs > searchMaxRangeMs) {
throw new Error("Search queries must use a time range of at most 1 hour.");
}
return {
apl: [
"['express']",
`| where ['context.org_id'] == '${escapeAplString(auth.orgId)}'`,
`| where ['context.env'] == '${escapeAplString(auth.env)}'`,
rest,
].filter(Boolean).join("\n"),
startTime,
endTime,
};
};
const withAxiomOrg = async (auth: AutumnMcpAuth) => {
return { ...auth, orgId: await resolveAutumnOrgId(auth) };
};
export const createAxiomTools = () => ({
queryAxiomLogs: createTool({
id: "queryAxiomLogs",
description:
"Run a read-only Axiom APL query against Autumn logs. The query is always constrained to the authenticated Autumn org and environment.",
inputSchema: z.object({
apl: z.string().min(1),
startTime: z.string().optional(),
endTime: z.string().optional(),
}).strict(),
execute: async ({ apl, startTime, endTime }, context) => {
const auth = await withAxiomOrg(getAutumnAuth(context));
const query = prepareAxiomQuery({ auth, apl, startTime, endTime });
return getAxiomClient().query(query.apl, {
startTime: query.startTime,
endTime: query.endTime,
});
},
}),
getAxiomDatasetFields: createTool({
id: "getAxiomDatasetFields",
description:
"List available Axiom field metadata for the express dataset, scoped to the authenticated Autumn org and environment.",
inputSchema: z.object({
dataset: z.literal(axiomDataset),
}).strict(),
execute: async ({ dataset }, context) => {
const auth = await withAxiomOrg(getAutumnAuth(context));
const query = prepareAxiomQuery({
auth,
apl: `['${dataset}'] | limit 1`,
});
const result = await getAxiomClient().query(query.apl, {
startTime: query.startTime,
endTime: query.endTime,
format: "tabular",
});
return {
dataset,
fields: result.fieldsMetaMap?.[dataset] ?? [],
};
},
}),
});

View File

@@ -0,0 +1,85 @@
import { describe, expect, test } from "bun:test";
import type { AutumnMcpAuth } from "./auth.js";
import {
claimLatestPendingAction,
clearPendingActions,
createPendingAction,
setPendingActionsRedis,
} from "./pending-actions.js";
import { createTestRedis } from "./test-redis.js";
setPendingActionsRedis(createTestRedis());
const auth = (overrides: Partial<AutumnMcpAuth> = {}): AutumnMcpAuth => ({
apiKey: "sk_test",
env: "sandbox",
principalId: "user_1",
resource: "http://localhost:2718/mcp",
scopes: ["customers:read", "plans:read", "billing:read", "billing:write"],
...overrides,
});
describe("pending billing actions", () => {
test("claims the latest action only for the matching auth context", async () => {
await clearPendingActions();
await createPendingAction({
auth: auth(),
toolName: "attach",
request: { customer_id: "cus_1", plan_id: "pro" },
preview: "Attach pro to cus_1",
});
await expect(
claimLatestPendingAction(auth({ principalId: "user_2" })),
).rejects.toThrow("No pending");
await expect(claimLatestPendingAction(auth())).resolves.toMatchObject({
request: {
customer_id: "cus_1",
plan_id: "pro",
},
});
await expect(claimLatestPendingAction(auth())).rejects.toThrow("No pending");
});
test("claims the latest matching action without exposing tokens", async () => {
await clearPendingActions();
await createPendingAction({
auth: auth(),
toolName: "attach",
request: { customer_id: "cus_1", plan_id: "starter" },
preview: "Attach starter",
});
const latest = await createPendingAction({
auth: auth(),
toolName: "attach",
request: { customer_id: "cus_1", plan_id: "pro" },
preview: "Attach pro",
});
await expect(claimLatestPendingAction(auth())).resolves.toMatchObject({
request: latest.request,
});
});
test("only one concurrent confirmation can claim an action", async () => {
await clearPendingActions();
await createPendingAction({
auth: auth(),
toolName: "attach",
request: { customer_id: "cus_1", plan_id: "pro" },
preview: "Attach pro",
});
const results = await Promise.allSettled([
claimLatestPendingAction(auth()),
claimLatestPendingAction(auth()),
]);
expect(results.filter((result) => result.status === "fulfilled")).toHaveLength(
1,
);
expect(results.filter((result) => result.status === "rejected")).toHaveLength(
1,
);
});
});

View File

@@ -0,0 +1,178 @@
import { createHash } from "node:crypto";
import { ms } from "@autumn/shared/unixUtils";
import { addMilliseconds, isPast } from "date-fns";
import { Redis } from "ioredis";
import type { AutumnMcpAuth } from "./auth.js";
export type BillingToolName = "attach" | "updateSubscription";
export type PendingBillingAction = {
token: string;
principalId: string;
resource: string;
env: string;
toolName: BillingToolName;
request: unknown;
preview: string;
createdAt: number;
expiresAt: string;
};
const ttlMs = ms.minutes(15);
const namespace = "autumn:mcp:pending-action";
let redis: Redis | undefined;
export type PendingActionRedisMulti = {
set: (
key: string,
value: string,
expiryMode: "EX",
ttlSeconds: number,
) => PendingActionRedisMulti;
exec: () => Promise<unknown>;
};
export type PendingActionRedis = {
multi: () => PendingActionRedisMulti;
get: (key: string) => Promise<string | null>;
getdel: (key: string) => Promise<string | null>;
del: (...keys: string[]) => Promise<unknown>;
keys: (pattern: string) => Promise<string[]>;
};
const createToken = () => `act_${crypto.randomUUID()}`;
const isExpired = (action: PendingBillingAction) =>
isPast(new Date(action.expiresAt));
const hash = (value: string) =>
createHash("sha256").update(value).digest("hex").slice(0, 32);
const shortHash = (value: string) => hash(value).slice(0, 8);
const redisUrl = () => process.env.REDIS_URL || "";
const actionScope = (auth: AutumnMcpAuth) =>
hash([auth.principalId, auth.resource, auth.env].join(":"));
const latestKey = (auth: AutumnMcpAuth) =>
`${namespace}:${actionScope(auth)}:latest`;
const actionKey = (auth: AutumnMcpAuth, token: string) =>
`${namespace}:${actionScope(auth)}:action:${token}`;
const actionDebug = (auth: AutumnMcpAuth) => ({
env: auth.env,
principal: shortHash(auth.principalId),
resource: shortHash(auth.resource),
scope: actionScope(auth),
});
const logPendingAction = (event: string, data: Record<string, unknown>) => {
if (process.env.MCP_DEBUG_PENDING_ACTIONS !== "1") return;
console.log(`[mcp:pending-actions] ${event} ${JSON.stringify(data)}`);
};
export const setPendingActionsRedis = (client: PendingActionRedis) => {
redis = client as unknown as Redis;
};
const getRedis = (): PendingActionRedis => {
if (redis) return redis;
const url = redisUrl().trim();
if (!url) {
throw new Error("REDIS_URL is required for MCP pending billing actions.");
}
redis = new Redis(url, {
maxRetriesPerRequest: 1,
commandTimeout: 5_000,
});
redis.on("error", () => undefined);
logPendingAction("store", { backend: "redis", redisUrl: true });
return redis;
};
const parseStoredAction = (value: string | null) =>
(value ? (JSON.parse(value) as PendingBillingAction) : null);
const createAction = ({
auth,
toolName,
request,
preview,
}: {
auth: AutumnMcpAuth;
toolName: BillingToolName;
request: unknown;
preview: string;
}) =>
({
token: createToken(),
principalId: auth.principalId,
resource: auth.resource,
env: auth.env,
toolName,
request,
preview,
createdAt: Date.now(),
expiresAt: addMilliseconds(new Date(), ttlMs).toISOString(),
}) satisfies PendingBillingAction;
export const createPendingAction = async (input: {
auth: AutumnMcpAuth;
toolName: BillingToolName;
request: unknown;
preview: string;
}) => {
const action = createAction(input);
const client = getRedis();
const ttlSeconds = Math.ceil(ttlMs / 1000);
await client
.multi()
.set(
actionKey(input.auth, action.token),
JSON.stringify(action),
"EX",
ttlSeconds,
)
.set(latestKey(input.auth), action.token, "EX", ttlSeconds)
.exec();
logPendingAction("created", {
backend: "redis",
toolName: action.toolName,
token: shortHash(action.token),
...actionDebug(input.auth),
});
return action;
};
export const claimLatestPendingAction = async (auth: AutumnMcpAuth) => {
const client = getRedis();
const token = await client.getdel(latestKey(auth));
const key = token ? actionKey(auth, token) : null;
const action = key ? parseStoredAction(await client.get(key)) : null;
if (!token || !action || isExpired(action)) {
logPendingAction("claim-miss", {
backend: "redis",
reason: !token ? "missing_latest" : !action ? "missing_action" : "expired",
token: token ? shortHash(token) : null,
...actionDebug(auth),
});
throw new Error("No pending billing action to confirm.");
}
await client.del(actionKey(auth, token));
logPendingAction("claimed", {
backend: "redis",
toolName: action.toolName,
token: shortHash(token),
...actionDebug(auth),
});
return action;
};
export const getLatestPendingAction = async (auth: AutumnMcpAuth) => {
const client = getRedis();
const token = await client.get(latestKey(auth));
const action = token
? parseStoredAction(await client.get(actionKey(auth, token)))
: null;
if (!action || isExpired(action)) return null;
return action;
};
export const clearPendingActions = async () => {
const client = getRedis();
const keys = await client.keys(`${namespace}:*`);
if (keys.length) await client.del(...keys);
};

View File

@@ -0,0 +1,34 @@
import { describe, expect, test } from "bun:test";
import {
createAskAutumnMCPServer,
createAutumnOperationsMCPServer,
} from "./server.js";
describe("Autumn MCP server", () => {
test("public server advertises raw operation tools", async () => {
const tools = await createAutumnOperationsMCPServer().getToolListInfo();
expect(tools.tools.map((tool) => tool.name)).toEqual([
"listCustomers",
"getCustomer",
"listPlans",
"getPlan",
"previewAttach",
"previewUpdateSubscription",
"attach",
"updateSubscription",
]);
expect(tools.tools.map((tool) => tool.name)).not.toContain("ask_autumn");
expect(tools.tools.map((tool) => tool.name)).not.toContain(
"confirmBillingAction",
);
});
test("internal server advertises only ask_autumn", async () => {
const tools = await createAskAutumnMCPServer().getToolListInfo();
expect(tools.tools.map((tool) => tool.name)).toEqual(["ask_autumn"]);
expect(tools.tools.map((tool) => tool.name)).not.toContain("attach");
expect(tools.tools.map((tool) => tool.name)).not.toContain("listCustomers");
});
});

View File

@@ -0,0 +1,32 @@
import { MCPServer } from "@mastra/mcp";
import { createAskAutumnTool } from "./ask-autumn.js";
import type { AutumnMcpAuth } from "./auth.js";
import { createRawAutumnOperationTools } from "./tools.js";
export const createAskAutumnMCPServer = (_opts?: {
defaultAuth?: AutumnMcpAuth;
}) =>
new MCPServer({
id: "autumn-internal-mcp",
name: "Autumn Internal MCP",
version: "0.0.1",
description: "Ask Autumn to safely operate on customers, plans, and billing.",
instructions:
"Use ask_autumn for all Autumn work. Billing writes require preview and explicit user confirmation.",
tools: {
ask_autumn: createAskAutumnTool(_opts?.defaultAuth),
},
});
export const createAutumnOperationsMCPServer = () =>
new MCPServer({
id: "autumn-mcp",
name: "Autumn MCP",
version: "0.0.1",
description: "Operate on Autumn customers, plans, and billing.",
instructions:
"Use preview tools before billing writes. Write tools are destructive and should only be called after explicit user confirmation.",
tools: createRawAutumnOperationTools(),
});
export const createMCPServer = createAskAutumnMCPServer;

View File

@@ -0,0 +1,37 @@
import type {
PendingActionRedis,
PendingActionRedisMulti,
} from "./pending-actions.js";
export const createTestRedis = (): PendingActionRedis => {
const store = new Map<string, string>();
return {
multi: () => {
const ops: (() => void)[] = [];
const multi: PendingActionRedisMulti = {
set: (key, value) => {
ops.push(() => store.set(key, value));
return multi;
},
exec: async () => {
ops.forEach((op) => op());
},
};
return multi;
},
get: async (key) => store.get(key) ?? null,
getdel: async (key) => {
const value = store.get(key) ?? null;
store.delete(key);
return value;
},
del: async (...keys) => {
keys.forEach((key) => store.delete(key));
},
keys: async (pattern) => {
const prefix = pattern.replace(/\*$/, "");
return [...store.keys()].filter((key) => key.startsWith(prefix));
},
};
};

View File

@@ -0,0 +1,185 @@
import { describe, expect, test } from "bun:test";
import type { AutumnMcpAuth } from "./auth.js";
import {
clearPendingActions,
claimLatestPendingAction,
createPendingAction,
setPendingActionsRedis,
} from "./pending-actions.js";
import { createTestRedis } from "./test-redis.js";
import {
createAgentAutumnOperationTools,
createRawAutumnOperationTools,
} from "./tools.js";
setPendingActionsRedis(createTestRedis());
const auth: AutumnMcpAuth = {
apiKey: "sk_test",
env: "sandbox",
principalId: "user_1",
resource: "http://localhost:2718/mcp",
scopes: ["billing:read", "billing:write"],
serverURL: "http://localhost:8080",
};
describe("Autumn operation tools", () => {
test("raw listCustomers calls the list endpoint", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (url, init) => {
expect(String(url)).toBe("http://localhost:8080/v1/customers.list");
expect(JSON.parse(init?.body as string)).toMatchObject({
search: "charlie",
});
return Response.json({ customers: [] });
}) as typeof fetch;
try {
const tool = createRawAutumnOperationTools().listCustomers;
if (!tool.execute) throw new Error("listCustomers is not executable");
await expect(
tool.execute(
{ request: { search: "charlie" } },
{ mcp: { extra: { authInfo: auth } } } as never,
),
).resolves.toEqual({ customers: [] });
} finally {
globalThis.fetch = originalFetch;
}
});
test("raw previewAttach does not create a pending action", async () => {
await clearPendingActions();
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (url, init) => {
expect(String(url)).toBe("http://localhost:8080/v1/billing.preview_attach");
expect(JSON.parse(init?.body as string)).toEqual({
customer_id: "cus_1",
plan_id: "pro",
redirect_mode: "if_required",
});
return Response.json({ total: 50 });
}) as typeof fetch;
try {
const tool = createRawAutumnOperationTools().previewAttach;
if (!tool.execute) throw new Error("previewAttach is not executable");
await expect(
tool.execute(
{ request: { customer_id: "cus_1", plan_id: "pro" } },
{ mcp: { extra: { authInfo: auth } } } as never,
),
).resolves.toEqual({ total: 50 });
await expect(claimLatestPendingAction(auth)).rejects.toThrow("No pending");
} finally {
globalThis.fetch = originalFetch;
}
});
test("raw attach calls the write endpoint directly", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (url, init) => {
expect(String(url)).toBe("http://localhost:8080/v1/billing.attach");
expect(JSON.parse(init?.body as string)).toEqual({
customer_id: "cus_1",
plan_id: "pro",
redirect_mode: "if_required",
});
return Response.json({ ok: true });
}) as typeof fetch;
try {
const tool = createRawAutumnOperationTools().attach;
if (!tool.execute) throw new Error("attach is not executable");
await expect(
tool.execute(
{ request: { customer_id: "cus_1", plan_id: "pro" } },
{ mcp: { extra: { authInfo: auth } } } as never,
),
).resolves.toEqual({ ok: true });
} finally {
globalThis.fetch = originalFetch;
}
});
test("previewAttach stores the exact pending attach action", async () => {
await clearPendingActions();
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (url, init) => {
expect(String(url)).toBe("http://localhost:8080/v1/billing.preview_attach");
expect(JSON.parse(init?.body as string)).toEqual({
customer_id: "cus_1",
plan_id: "pro",
redirect_mode: "if_required",
});
return Response.json({ total: 50 });
}) as typeof fetch;
try {
const tool = (
createAgentAutumnOperationTools() as unknown as {
previewAttach: {
execute?: (input: unknown, context: unknown) => Promise<unknown>;
};
}
).previewAttach;
if (!tool.execute) throw new Error("previewAttach is not executable");
await expect(
tool.execute(
{ request: { customer_id: "cus_1", plan_id: "pro" } },
{ mcp: { extra: { authInfo: auth } } } as never,
),
).resolves.toMatchObject({ pending: true, preview: { total: 50 } });
await expect(claimLatestPendingAction(auth)).resolves.toMatchObject({
toolName: "attach",
request: {
customer_id: "cus_1",
plan_id: "pro",
redirect_mode: "if_required",
},
});
} finally {
globalThis.fetch = originalFetch;
}
});
test("confirmBillingAction executes only the stored pending billing action", async () => {
await clearPendingActions();
await createPendingAction({
auth,
toolName: "attach",
request: { customer_id: "cus_1", plan_id: "pro" },
preview: "Attach pro",
});
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (url, init) => {
expect(String(url)).toBe("http://localhost:8080/v1/billing.attach");
expect(JSON.parse(init?.body as string)).toEqual({
customer_id: "cus_1",
plan_id: "pro",
redirect_mode: "if_required",
});
return Response.json({ ok: true });
}) as typeof fetch;
try {
const tool = createAgentAutumnOperationTools().confirmBillingAction;
if (!tool.execute) throw new Error("confirmBillingAction is not executable");
await expect(
tool.execute({}, { mcp: { extra: { authInfo: auth } } } as never),
).resolves.toMatchObject({
message: "Confirmed and applied attach.",
result: { ok: true },
});
await expect(claimLatestPendingAction(auth)).rejects.toThrow("No pending");
} finally {
globalThis.fetch = originalFetch;
}
});
});

View File

@@ -0,0 +1,281 @@
import {
AttachParamsV1Schema,
GetCustomerParamsV1Schema,
GetPlanParamsV0Schema,
ListCustomersV2_3ParamsSchema,
ListPlanParamsSchema,
UpdateSubscriptionV1ParamsSchema,
} from "@autumn/shared/publicApiSchemas";
import { createTool } from "@mastra/core/tools";
import * as z from "zod/v4";
import { createAutumnClient, getAutumnAuth } from "./auth.js";
import {
claimLatestPendingAction,
createPendingAction,
} from "./pending-actions.js";
type ToolContext = Parameters<
NonNullable<ReturnType<typeof createTool>["execute"]>
>[1];
type BillingWriteToolName = "attach" | "updateSubscription";
type OperationToolConfig = {
id: string;
description: string;
schema: z.ZodType;
endpoint: string;
destructive?: boolean;
};
type BillingPreviewToolConfig = {
id: string;
description: string;
schema: z.ZodType;
previewEndpoint: string;
writeToolName: BillingWriteToolName;
};
const endpointByTool = {
listCustomers: "/v1/customers.list",
getCustomer: "/v1/customers.get",
listPlans: "/v1/plans.list",
getPlan: "/v1/plans.get",
previewAttach: "/v1/billing.preview_attach",
attach: "/v1/billing.attach",
previewUpdateSubscription: "/v1/billing.preview_update",
updateSubscription: "/v1/billing.update",
} as const;
const billingWriteSchemaByTool = {
attach: AttachParamsV1Schema,
updateSubscription: UpdateSubscriptionV1ParamsSchema,
} as const satisfies Record<BillingWriteToolName, z.ZodType>;
const toolConfigs: OperationToolConfig[] = [
{
id: "listCustomers",
description:
"List Autumn customers. Use search to find a customer by id, name, or email.",
schema: ListCustomersV2_3ParamsSchema,
endpoint: endpointByTool.listCustomers,
},
{
id: "getCustomer",
description: "Fetch one Autumn customer by id.",
schema: GetCustomerParamsV1Schema,
endpoint: endpointByTool.getCustomer,
},
{
id: "listPlans",
description: "List Autumn plans.",
schema: ListPlanParamsSchema,
endpoint: endpointByTool.listPlans,
},
{
id: "getPlan",
description: "Fetch one Autumn plan by id and optional version.",
schema: GetPlanParamsV0Schema,
endpoint: endpointByTool.getPlan,
},
];
const billingPreviewConfigs: BillingPreviewToolConfig[] = [
{
id: "previewAttach",
description:
"Preview attaching a plan to a customer.",
schema: AttachParamsV1Schema,
previewEndpoint: endpointByTool.previewAttach,
writeToolName: "attach",
},
{
id: "previewUpdateSubscription",
description: "Preview updating a subscription.",
schema: UpdateSubscriptionV1ParamsSchema,
previewEndpoint: endpointByTool.previewUpdateSubscription,
writeToolName: "updateSubscription",
},
];
const billingWriteConfigs: OperationToolConfig[] = [
{
id: "attach",
description: "Attach a plan to a customer.",
schema: AttachParamsV1Schema,
endpoint: endpointByTool.attach,
destructive: true,
},
{
id: "updateSubscription",
description: "Update a customer subscription.",
schema: UpdateSubscriptionV1ParamsSchema,
endpoint: endpointByTool.updateSubscription,
destructive: true,
},
];
const callAutumn = async ({
context,
endpoint,
request,
}: {
context?: ToolContext;
endpoint: string;
request: unknown;
}) => {
const auth = getAutumnAuth(context);
const client = createAutumnClient(auth);
const init: RequestInit = {
method: "POST",
headers: client.headers,
body: JSON.stringify(request),
};
if (context?.mcp?.extra?.signal) init.signal = context.mcp.extra.signal;
const response = await fetch(new URL(endpoint, client.baseUrl), init);
const text = await response.text();
const body = text ? parseBody(text) : null;
if (!response.ok) {
throw new Error(
`Autumn API request failed (${response.status}): ${typeof body === "string" ? body : JSON.stringify(body)}`,
);
}
return body;
};
const parseBody = (text: string): unknown => {
try {
return JSON.parse(text);
} catch {
return text;
}
};
const logTool = (event: string, data: Record<string, unknown>) => {
if (process.env.MCP_DEBUG_PENDING_ACTIONS !== "1") return;
console.log(`[mcp:agent-tools] ${event} ${JSON.stringify(data)}`);
};
const mcpAnnotations = (destructive = false) => ({
readOnlyHint: !destructive,
destructiveHint: destructive,
idempotentHint: false,
openWorldHint: false,
});
const toTools = <Config extends { id: string }>(
configs: Config[],
create: (config: Config) => ReturnType<typeof createTool>,
) => Object.fromEntries(configs.map((config) => [config.id, create(config)]));
const operationTool = ({
id,
description,
schema,
endpoint,
destructive = false,
}: OperationToolConfig) =>
createTool({
id,
description,
inputSchema: z.object({ request: schema }).strict(),
mcp: {
annotations: mcpAnnotations(destructive),
},
execute: (input, context) =>
callAutumn({
context,
endpoint,
request: (input as { request: unknown }).request,
}),
});
const agentBillingPreviewTool = ({
id,
description,
schema,
previewEndpoint,
writeToolName,
}: {
id: string;
description: string;
schema: z.ZodType;
previewEndpoint: string;
writeToolName: BillingWriteToolName;
}) =>
createTool({
id,
description: `${description} Store the exact pending billing action for later confirmation.`,
inputSchema: z.object({ request: schema }).strict(),
mcp: {
annotations: mcpAnnotations(),
},
execute: async (input, context) => {
const request = (input as { request: unknown }).request;
const auth = getAutumnAuth(context);
logTool("preview-start", { previewTool: id, writeToolName });
const preview = await callAutumn({
context,
endpoint: previewEndpoint,
request,
});
await createPendingAction({
auth,
toolName: writeToolName,
request,
preview: JSON.stringify(preview),
});
logTool("preview-stored", { previewTool: id, writeToolName });
return {
preview,
pending: true,
message:
"Preview ready. Ask the user to explicitly apply or approve this exact change.",
};
},
});
export const createRawAutumnOperationTools = () => ({
...toTools(toolConfigs, operationTool),
...toTools(billingPreviewConfigs, (config) =>
operationTool({ ...config, endpoint: config.previewEndpoint }),
),
...toTools(billingWriteConfigs, operationTool),
});
export const createAgentAutumnOperationTools = () => ({
...toTools(toolConfigs, operationTool),
...toTools(billingPreviewConfigs, agentBillingPreviewTool),
confirmBillingAction: createTool({
id: "confirmBillingAction",
description:
"Apply the latest pending billing action after the user semantically confirms the preview.",
inputSchema: z.object({}).strict(),
execute: async (_input, context) => {
const auth = getAutumnAuth(context);
logTool("confirm-start", { env: auth.env });
const action = await claimLatestPendingAction(auth);
logTool("confirm-claimed", { toolName: action.toolName });
const result = await executeConfirmedBillingAction({
auth,
toolName: action.toolName,
request: action.request,
});
return {
message: `Confirmed and applied ${action.toolName}.`,
result,
};
},
}),
});
export const executeConfirmedBillingAction = async ({
auth,
toolName,
request,
}: {
auth: ReturnType<typeof getAutumnAuth>;
toolName: BillingWriteToolName;
request: unknown;
}) =>
callAutumn({
context: { mcp: { extra: { authInfo: auth } } } as never,
endpoint: endpointByTool[toolName],
request: billingWriteSchemaByTool[toolName].parse(request),
});

View File

@@ -0,0 +1,32 @@
export const consoleLoggerLevels = [
"debug",
"info",
"warning",
"error",
] as const;
export type ConsoleLoggerLevel = (typeof consoleLoggerLevels)[number];
type LogMethod = (message: string, data?: Record<string, unknown>) => void;
export type ConsoleLogger = Record<ConsoleLoggerLevel, LogMethod> & {
level: ConsoleLoggerLevel;
};
export function createConsoleLogger(level: ConsoleLoggerLevel): ConsoleLogger {
const min = consoleLoggerLevels.indexOf(level);
const noop = () => {};
const log = (method: "debug" | "info" | "warn" | "error"): LogMethod =>
(message, data) => {
if (data) console[method](message, data);
else console[method](message);
};
return {
level,
debug: min <= 0 ? log("debug") : noop,
info: min <= 1 ? log("info") : noop,
warning: min <= 2 ? log("warn") : noop,
error: min <= 3 ? log("error") : noop,
};
}

View File

@@ -0,0 +1,6 @@
export interface MCPServerFlags {
readonly "secret-key"?: string | undefined;
readonly "x-api-version"?: string | undefined;
readonly "fail-open"?: boolean | undefined;
readonly "server-url"?: string | undefined;
}

View File

@@ -0,0 +1,146 @@
import { describe, expect, test } from "bun:test";
import {
buildAuthForRequest,
getProtectedResourceMetadata,
MCP_OAUTH_SCOPES,
OAuthHttpError,
type MCPOAuthFlags,
} from "./oauth.js";
const flags = {
"oauth-enabled": true,
"oauth-environment": "sandbox",
"server-url": "http://localhost:8080",
} satisfies Partial<MCPOAuthFlags>;
const logger = {
warning: () => {},
} as never;
describe("MCP OAuth auth resolution", () => {
test("returns a WWW-Authenticate challenge without a bearer token", async () => {
await expect(
buildAuthForRequest(
new Headers({ host: "localhost:2718" }),
flags as MCPOAuthFlags,
logger,
),
).rejects.toMatchObject({
status: 401,
error: "invalid_token",
wwwAuthenticate:
'Bearer resource_metadata="http://localhost:2718/.well-known/oauth-protected-resource/mcp"',
} satisfies Partial<OAuthHttpError>);
});
test("returns an internal MCP resource challenge", async () => {
await expect(
buildAuthForRequest(
new Headers({ host: "localhost:2718" }),
flags as MCPOAuthFlags,
logger,
"/internal/mcp",
),
).rejects.toMatchObject({
status: 401,
error: "invalid_token",
wwwAuthenticate:
'Bearer resource_metadata="http://localhost:2718/.well-known/oauth-protected-resource/internal/mcp"',
} satisfies Partial<OAuthHttpError>);
});
test("exchanges a bearer token for Autumn API credentials", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (_url, init) => {
expect(init?.headers).toEqual({
Authorization: "Bearer oauth_token",
"Content-Type": "application/json",
});
expect(JSON.parse(init?.body as string)).toEqual({
resource: "http://localhost:2718/mcp",
scopes: MCP_OAUTH_SCOPES,
});
return Response.json({
sandbox_key: "sk_sandbox",
prod_key: "sk_live",
org_id: "org_123",
user_id: "user_123",
client_id: "client_123",
scopes: MCP_OAUTH_SCOPES,
});
}) as typeof fetch;
try {
const auth = await buildAuthForRequest(
new Headers({
authorization: "Bearer oauth_token",
host: "localhost:2718",
}),
flags as MCPOAuthFlags,
logger,
);
expect(auth.apiKey).toBe("sk_sandbox");
expect(auth.env).toBe("sandbox");
expect(auth.resource).toBe("http://localhost:2718/mcp");
expect(auth.principalId).toBe("oauth:org_123:user_123:client_123");
expect(auth.scopes).toEqual([...MCP_OAUTH_SCOPES]);
expect(auth.orgId).toBe("org_123");
} finally {
globalThis.fetch = originalFetch;
}
});
test("uses route-specific resource URLs", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = (async (_url, init) => {
expect(JSON.parse(init?.body as string)).toMatchObject({
resource: "http://localhost:2718/internal/mcp",
});
return Response.json({
sandbox_key: "sk_sandbox",
org_id: "org_123",
scopes: MCP_OAUTH_SCOPES,
});
}) as typeof fetch;
try {
const auth = await buildAuthForRequest(
new Headers({
authorization: "Bearer internal_oauth_token",
host: "localhost:2718",
}),
flags as MCPOAuthFlags,
logger,
"/internal/mcp",
);
expect(auth.resource).toBe("http://localhost:2718/internal/mcp");
expect(
getProtectedResourceMetadata(
new Headers({ host: "localhost:2718" }),
flags as MCPOAuthFlags,
"/internal/mcp",
).resource,
).toBe("http://localhost:2718/internal/mcp");
} finally {
globalThis.fetch = originalFetch;
}
});
test("missing static secret-key returns the auth error path", async () => {
await expect(
buildAuthForRequest(
new Headers({ host: "localhost:2718" }),
{
...flags,
"oauth-enabled": false,
} as MCPOAuthFlags,
logger,
),
).rejects.toMatchObject({
status: 401,
error: "invalid_token",
} satisfies Partial<OAuthHttpError>);
});
});

View File

@@ -0,0 +1,314 @@
import { type ScopeString, Scopes } from "@autumn/shared/scopeDefinitions";
import { ms } from "@autumn/shared/unixUtils";
import { addMilliseconds, isFuture } from "date-fns";
import * as z from "zod/v4";
import type { AutumnMcpAuth } from "./agent/auth.js";
import { principalFromSecret } from "./agent/auth.js";
import type { ConsoleLogger } from "./console-logger.js";
import type { MCPServerFlags } from "./flags.js";
export const MCP_OAUTH_SCOPES = [
Scopes.Customers.Read,
Scopes.Plans.Read,
Scopes.Billing.Read,
Scopes.Billing.Write,
Scopes.Analytics.Read,
] as const satisfies readonly ScopeString[];
const environmentSchema = z.enum(["sandbox", "live"]);
const xApiVersionSchema = z.string().default("2.3.0");
const failOpenSchema = z
.union([z.boolean(), z.enum(["true", "false"]).transform((v) => v === "true")])
.default(true);
const secretKeySchema = z.string().min(1).optional();
const tokenExchangeSchema = z.object({
sandbox_key: z.string().optional(),
prod_key: z.string().optional(),
org_id: z.string().optional(),
user_id: z.string().optional(),
client_id: z.string().optional(),
scopes: z.array(z.string()).optional(),
});
export type OAuthEnvironment = z.infer<typeof environmentSchema>;
export interface MCPOAuthFlags extends MCPServerFlags {
readonly "oauth-enabled"?: boolean | undefined;
readonly "oauth-environment"?: OAuthEnvironment | undefined;
}
export class OAuthHttpError extends Error {
constructor(
readonly status: number,
message: string,
readonly error = "invalid_token",
readonly wwwAuthenticate?: string,
) {
super(message);
}
}
const apiKeyCache = new Map<
string,
{
key: string;
orgId?: string | undefined;
userId?: string | undefined;
clientId?: string | undefined;
scopes?: string[] | undefined;
expiresAt: Date;
}
>();
function trimTrailingSlash(url: string): string {
return url.endsWith("/") ? url.slice(0, -1) : url;
}
export function getResourceUrl(
headers: Headers,
_flags: MCPOAuthFlags,
resourcePath = "/mcp",
): string {
const host =
headers.get("x-autumn-forwarded-host") ??
headers.get("x-forwarded-host") ??
headers.get("host");
if (!host) {
throw new OAuthHttpError(400, "Missing Host header", "invalid_request");
}
const proto =
headers.get("x-autumn-forwarded-proto") ??
headers.get("x-forwarded-proto") ??
"http";
return new URL(resourcePath, `${proto}://${host}`).href;
}
export function getProtectedResourceMetadataUrl(resourceUrl: string): string {
const url = new URL(resourceUrl);
const path = url.pathname === "/" ? "" : url.pathname;
return new URL(`/.well-known/oauth-protected-resource${path}`, url).href;
}
function getIssuerUrl(flags: MCPOAuthFlags): string {
return trimTrailingSlash(
new URL("/api/auth", flags["server-url"] ?? "https://api.useautumn.com")
.href,
);
}
function getApiKeyUrl(flags: MCPOAuthFlags): string {
return new URL("/cli/api-keys", getIssuerUrl(flags)).href;
}
function getWWWAuthenticate(resourceUrl: string, error?: string): string {
const params = [
`resource_metadata="${getProtectedResourceMetadataUrl(resourceUrl)}"`,
];
if (error) params.push(`error="${error}"`);
return `Bearer ${params.join(", ")}`;
}
export function getProtectedResourceMetadata(
headers: Headers,
flags: MCPOAuthFlags,
resourcePath = "/mcp",
) {
const resource = getResourceUrl(headers, flags, resourcePath);
return {
resource,
authorization_servers: [getIssuerUrl(flags)],
scopes_supported: [...MCP_OAUTH_SCOPES],
bearer_methods_supported: ["header"],
resource_name: "Autumn MCP",
};
}
export function getAuthorizationServerMetadata(flags: MCPOAuthFlags) {
const issuer = getIssuerUrl(flags);
return {
issuer,
authorization_endpoint: `${issuer}/oauth2/authorize`,
token_endpoint: `${issuer}/oauth2/token`,
registration_endpoint: `${issuer}/oauth2/register`,
revocation_endpoint: `${issuer}/oauth2/revoke`,
introspection_endpoint: `${issuer}/oauth2/introspect`,
response_types_supported: ["code"],
grant_types_supported: ["authorization_code", "refresh_token"],
token_endpoint_auth_methods_supported: [
"client_secret_post",
"client_secret_basic",
"none",
],
code_challenge_methods_supported: ["S256"],
scopes_supported: [...MCP_OAUTH_SCOPES],
};
}
function getEnvironment(
headers: Headers,
flags: MCPOAuthFlags,
): OAuthEnvironment {
const value =
headers.get("x-autumn-environment") ??
flags["oauth-environment"] ??
"sandbox";
const parsed = environmentSchema.safeParse(value);
if (parsed.success) return parsed.data;
throw new OAuthHttpError(
400,
"Invalid x-autumn-environment",
"invalid_request",
);
}
function parseRequestOption<T>(
value: unknown,
schema: z.ZodType<T>,
message: string,
): T {
const parsed = schema.safeParse(value);
if (parsed.success) return parsed.data;
throw new OAuthHttpError(400, message, "invalid_request");
}
async function exchangeOAuthToken(
headers: Headers,
flags: MCPOAuthFlags,
resource: string,
token: string,
): Promise<{
key: string;
orgId?: string | undefined;
userId?: string | undefined;
clientId?: string | undefined;
scopes?: string[];
}> {
const env = getEnvironment(headers, flags);
const cacheKey = `${token}:${resource}:${env}`;
const cached = apiKeyCache.get(cacheKey);
if (cached && isFuture(cached.expiresAt)) return cached;
const response = await fetch(getApiKeyUrl(flags), {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ resource, scopes: MCP_OAUTH_SCOPES }),
});
if (!response.ok) {
throw new OAuthHttpError(
response.status === 403 ? 403 : 401,
await response.text(),
response.status === 403 ? "insufficient_scope" : "invalid_token",
response.status === 403
? undefined
: getWWWAuthenticate(resource, "invalid_token"),
);
}
const data = tokenExchangeSchema.parse(await response.json());
const key = env === "live" ? data.prod_key : data.sandbox_key;
if (!key) {
throw new OAuthHttpError(
502,
"OAuth key exchange did not return an API key",
);
}
const exchanged = {
key,
orgId: data.org_id,
userId: data.user_id,
clientId: data.client_id,
scopes: data.scopes,
expiresAt: addMilliseconds(new Date(), ms.minutes(1)),
};
apiKeyCache.set(cacheKey, exchanged);
return exchanged;
}
function getOAuthPrincipalId(
token: string,
exchanged: Awaited<ReturnType<typeof exchangeOAuthToken>>,
) {
if (!exchanged.orgId) return principalFromSecret("oauth", token);
return [
"oauth",
exchanged.orgId,
exchanged.userId ?? "unknown-user",
exchanged.clientId ?? "unknown-client",
].join(":");
}
export async function buildAuthForRequest(
headers: Headers,
flags: MCPOAuthFlags,
logger: ConsoleLogger,
resourcePath = "/mcp",
): Promise<AutumnMcpAuth> {
const env = getEnvironment(headers, flags);
const resource = getResourceUrl(headers, flags, resourcePath);
const xApiVersion = parseRequestOption(
headers.get("x-api-version") ?? flags["x-api-version"],
xApiVersionSchema,
"Invalid x-api-version",
);
const failOpen = parseRequestOption(
headers.get("fail-open") ?? flags["fail-open"],
failOpenSchema,
"Invalid fail-open",
);
if (flags["oauth-enabled"]) {
const authHeader = headers.get("authorization");
if (!authHeader?.startsWith("Bearer ")) {
throw new OAuthHttpError(
401,
"Missing Authorization bearer token",
"invalid_token",
getWWWAuthenticate(resource),
);
}
const token = authHeader.slice("Bearer ".length);
const exchanged = await exchangeOAuthToken(headers, flags, resource, token);
return {
apiKey: exchanged.key,
env,
resource,
principalId: getOAuthPrincipalId(token, exchanged),
scopes: exchanged.scopes ?? [...MCP_OAUTH_SCOPES],
orgId: exchanged.orgId,
serverURL: flags["server-url"],
xApiVersion,
failOpen,
};
}
const apiKey = parseRequestOption(
headers.get("secret-key") ?? flags["secret-key"],
secretKeySchema,
"Invalid secret-key",
);
if (!apiKey) {
logger.warning("Missing secret-key for MCP request");
throw new OAuthHttpError(401, "Missing secret-key", "invalid_token");
}
return {
apiKey,
env,
resource,
principalId: principalFromSecret("secret-key", apiKey),
scopes: [...MCP_OAUTH_SCOPES],
serverURL: flags["server-url"],
xApiVersion,
failOpen,
};
}

View File

@@ -0,0 +1,41 @@
{
"compilerOptions": {
"allowJs": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"checkJs": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": true,
"exactOptionalPropertyTypes": false,
"forceConsistentCasingInFileNames": true,
"incremental": true,
"isolatedModules": true,
"lib": ["dom", "dom.iterable", "es2024"],
"module": "Preserve",
"moduleResolution": "bundler",
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": false,
"noImplicitReturns": false,
"noPropertyAccessFromIndexSignature": false,
"noUncheckedIndexedAccess": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"outDir": "esm",
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "es2022",
"paths": {
"@api/*": ["../../shared/api/*"],
"@models/*": ["../../shared/models/*"],
"@utils/*": ["../../shared/utils/*"],
"@autumn/ksuid": ["../ksuid/src/index.ts"]
},
"useUnknownInCatchVariables": true,
},
"exclude": ["node_modules"],
"include": ["src/**/*.ts"]
}

File diff suppressed because it is too large Load Diff

View File

@@ -8184,8 +8184,8 @@ paths:
description: Configuration for a feature item in a plan, including usage limits,
pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing
items). Mutually exclusive with add_items /
remove_items.
items). Mutually exclusive with add_items / remove_items
/ update_items.
add_items:
type: array
items:
@@ -8678,7 +8678,7 @@ paths:
@example
```typescript
// Schedule a transition from a trial plan to a paid plan
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779292757190,"plans":[{"planId":"trial_plan"}]},{"startsAt":1780502357190,"plans":[{"planId":"pro_plan"}]}] });
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779977746466,"plans":[{"planId":"trial_plan"}]},{"startsAt":1781187346466,"plans":[{"planId":"pro_plan"}]}] });
```
@param customerId - The ID of the customer to create the schedule for.
@@ -10297,8 +10297,8 @@ paths:
description: Configuration for a feature item in a plan, including usage limits,
pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing
items). Mutually exclusive with add_items /
remove_items.
items). Mutually exclusive with add_items / remove_items
/ update_items.
add_items:
type: array
items:
@@ -12323,8 +12323,8 @@ paths:
description: Configuration for a feature item in a plan, including usage limits,
pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing
items). Mutually exclusive with add_items /
remove_items.
items). Mutually exclusive with add_items / remove_items
/ update_items.
add_items:
type: array
items:
@@ -13038,8 +13038,8 @@ paths:
description: Configuration for a feature item in a plan, including usage limits,
pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing
items). Mutually exclusive with add_items /
remove_items.
items). Mutually exclusive with add_items / remove_items
/ update_items.
add_items:
type: array
items:
@@ -14053,8 +14053,8 @@ paths:
description: Configuration for a feature item in a plan, including usage limits,
pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing
items). Mutually exclusive with add_items /
remove_items.
items). Mutually exclusive with add_items / remove_items
/ update_items.
add_items:
type: array
items:
@@ -16062,6 +16062,10 @@ paths:
@param properties - Additional properties to attach to this usage event.
(optional)
@param async - If true, enqueue the event for asynchronous processing
and return 202 immediately. The response will not include balance
information. (optional)
@returns The usage value recorded, with either a single updated balance
or a map of updated balances. If Autumn is experiencing degraded service
@@ -16101,6 +16105,11 @@ paths:
type: string
additionalProperties: {}
description: Additional properties to attach to this usage event.
async:
type: boolean
description: If true, enqueue the event for asynchronous processing and return
202 immediately. The response will not include balance
information.
lock:
type: object
properties:
@@ -16416,6 +16425,109 @@ paths:
x-speakeasy-name-override: track
parameters:
- *a1
/v1/balances.batch_track:
post:
operationId: batchTrack
description: Enqueue up to 1000 usage events for asynchronous processing. Items
are validated synchronously up front; validated items are then enqueued
via SQS for background deduction by workers. The response returns 202
immediately and does not include balance information. On partial enqueue
failure (some items fail to enqueue, others succeed), the endpoint still
returns 202 and logs the failures server-side; clients should NOT retry,
because retrying re-enqueues the already-succeeded items. A 503 is
returned only when zero items were successfully enqueued (queue entirely
unavailable) — that case is safe to retry.
requestBody:
required: true
content:
application/json:
schema:
type: array
minItems: 1
maxItems: 1000
items:
type: object
properties:
customer_id:
type: string
description: The ID of the customer.
feature_id:
type: string
description: The ID of the feature to track usage for. Required if event_name is
not provided.
entity_id:
type: string
description: The ID of the entity for entity-scoped balances (e.g., per-seat
limits).
event_name:
type: string
minLength: 1
description: Event name to track usage for. Use instead of feature_id when
multiple features should be tracked from a single event.
value:
type: number
description: The amount of usage to record. Defaults to 1. Use negative values
to credit balance (e.g., when removing a seat).
properties:
type: object
propertyNames:
type: string
additionalProperties: {}
description: Additional properties to attach to this usage event.
async:
type: boolean
description: If true, enqueue the event for asynchronous processing and return
202 immediately. The response will not include balance
information.
lock:
type: object
properties:
lock_id:
type: string
maxLength: 256
description: A unique identifier for this lock. Used to finalize the lock later
via balances.finalize.
enabled:
const: true
description: Must be true to enable locking.
expires_at:
type: number
description: Unix timestamp (ms) when the lock automatically expires and
releases the held balance.
required:
- lock_id
- enabled
required:
- customer_id
title: BatchTrackParams
examples:
- - customer_id: cus_123
feature_id: messages
value: 1
- customer_id: cus_123
event_name: message.sent
value: 1
responses:
"202":
description: "Batch accepted. All items passed synchronous validation. Enqueue
is best-effort: partial failures (some items enqueued, some not) are
logged server-side and are NOT surfaced in the response body;
clients must not retry on 202. See the endpoint description for full
partial-failure semantics."
content:
application/json:
schema:
type: object
properties:
success:
const: true
required:
- success
examples:
- success: true
x-speakeasy-name-override: batchTrack
parameters:
- *a1
/v1/events.list:
post:
operationId: listEvents
@@ -17964,6 +18076,10 @@ paths:
@param processors - Filter by parent customer processor type (stripe,
revenuecat, vercel). (optional)
@param customerId - Restrict the response to entities owned by this
customer id. Use to bulk-fetch all entities for one customer in a single
paginated call instead of iterating entities.get. (optional)
@returns A paginated list of entity objects including their current
subscriptions, purchases, balances, and flags.
@@ -18024,6 +18140,12 @@ paths:
type: string
description: Filter by parent customer processor type (stripe, revenuecat,
vercel).
customer_id:
type: string
minLength: 1
description: Restrict the response to entities owned by this customer id. Use to
bulk-fetch all entities for one customer in a single
paginated call instead of iterating entities.get.
title: ListEntitiesParams
examples:
- start_cursor: ""

View File

@@ -1,6 +1,7 @@
import { SuccessResponseSchema } from "@api/common/commonResponses.js";
import {
API_BALANCE_V1_EXAMPLE,
BatchTrackParamsSchema,
CheckResponseV3Schema,
CreateBalanceParamsV0Schema,
DeleteBalanceParamsV0Schema,
@@ -11,6 +12,7 @@ import {
UpdateBalanceParamsV0Schema,
} from "@autumn/shared";
import { oc } from "@orpc/contract";
import { z } from "zod/v4";
import {
balancesCheckJsDoc,
balancesTrackJsDoc,
@@ -36,6 +38,32 @@ const withAcceptedResponse = <TSpec extends SpecWithResponses>(
},
});
const withOnlyAcceptedResponse = <TSpec extends SpecWithResponses>(
spec: TSpec,
nameOverride: string,
description: string,
) => {
const responses = { ...spec.responses };
const successResponse = responses["200"];
delete responses["200"];
return {
...spec,
"x-speakeasy-name-override": nameOverride,
responses: {
...responses,
202: {
...successResponse,
description,
},
},
};
};
const BatchTrackResponseSchema = z.object({
success: z.literal(true),
});
export const balancesCheckContract = oc
.route({
method: "POST",
@@ -129,6 +157,45 @@ export const balancesTrackContract = oc
}),
);
export const balancesBatchTrackContract = oc
.route({
method: "POST",
path: "/v1/balances.batch_track",
operationId: "batchTrack",
description:
"Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.",
spec: (spec) =>
withOnlyAcceptedResponse(
spec,
"batchTrack",
"Batch accepted. All items passed synchronous validation. Enqueue is best-effort: partial failures (some items enqueued, some not) are logged server-side and are NOT surfaced in the response body; clients must not retry on 202. See the endpoint description for full partial-failure semantics.",
),
})
.input(
BatchTrackParamsSchema.meta({
title: "BatchTrackParams",
examples: [
[
{
customer_id: "cus_123",
feature_id: "messages",
value: 1,
},
{
customer_id: "cus_123",
event_name: "message.sent",
value: 1,
},
],
],
}),
)
.output(
BatchTrackResponseSchema.meta({
examples: [{ success: true }],
}),
);
export const balancesCreateContract = oc
.route({
method: "POST",

View File

@@ -1,5 +1,6 @@
import { oc } from "@orpc/contract";
import {
balancesBatchTrackContract,
balancesCheckContract,
balancesCreateContract,
balancesDeleteContract,
@@ -96,6 +97,7 @@ export const v2_3ContractRouter = oc.router({
balancesFinalize: balancesFinalizeContract,
balancesCheck: balancesCheckContract,
balancesTrack: balancesTrackContract,
balancesBatchTrack: balancesBatchTrackContract,
// Events
eventsList: eventsListContract,

View File

@@ -3,6 +3,37 @@ info:
title: CodeSamples overlay for typescript target
version: 0.0.0
actions:
- target: $["paths"]["/v1/balances.batch_track"]["post"]
update:
x-codeSamples:
- lang: typescript
label: Typescript (SDK)
source: |-
import { Autumn } from "@useautumn/sdk";
const autumn = new Autumn({
xApiVersion: "2.3.0",
secretKey: process.env["AUTUMN_SECRET_KEY"] ?? "",
});
async function run() {
const result = await autumn.batchTrack([
{
customerId: "cus_123",
featureId: "messages",
value: 1,
},
{
customerId: "cus_123",
eventName: "message.sent",
value: 1,
},
]);
console.log(result);
}
run();
- target: $["paths"]["/v1/balances.check"]["post"]
update:
x-codeSamples:

View File

@@ -1,16 +1,16 @@
lockVersion: 2.0.0
id: 7b300647-cd76-49e9-bf77-7d1bf5446d66
management:
docChecksum: fd622c742a283a0f30afad7727090fdb
docChecksum: 364fa19149970fee6fcb163993e0f41f
docVersion: 2.3.0
speakeasyVersion: 1.762.0
generationVersion: 2.882.0
releaseVersion: 0.10.17
configChecksum: bae45df54c836a79d656f78f967da99b
configChecksum: 4722f16a8dee67ebd4038caf3c345296
persistentEdits:
generation_id: aff5214d-31ba-4dad-bf8a-38b4e7690511
pristine_commit_hash: b6687d7a88f141b20692b73b34f7b23cd833f3c6
pristine_tree_hash: f20144f70008461f2a74d1d4b7731300ca6ee0e8
generation_id: 415422dc-a18e-4c5c-8688-24da80f6f2cb
pristine_commit_hash: aa99b58acd07c9871e8d62228e9440f86ed6baaa
pristine_tree_hash: 1fdf2cd6e37e1756e79a53d2833301f14da44293
features:
typescript:
additionalDependencies: 0.1.0
@@ -176,8 +176,8 @@ trackedFiles:
pristine_git_object: a039746ccb81d1bb2109b96dc7da522da9897353
docs/models/attach-customize.md:
id: a13da55a0eec
last_write_checksum: sha1:6c4cfba2bfa1c91ac981d7f028e061fb1e620bdd
pristine_git_object: 74ef0e39e2987e8b5698c26fffc6c2eb94e716ef
last_write_checksum: sha1:5ecb869dd633aa1e2e7476c9c951959eff30b2c5
pristine_git_object: 9853f164aeea684bf8aed691314bb94ff144fc0b
docs/models/attach-duration-type.md:
id: 2b7e68923781
last_write_checksum: sha1:f447c936a788f2f8a2aa160edff651f58e4e2b54
@@ -350,6 +350,18 @@ trackedFiles:
id: 9de59403580f
last_write_checksum: sha1:8d5433ac6435693a81086e91ba42d7ae173e2a45
pristine_git_object: 038a6883854d90582b9758ec49195d01f38d6dc1
docs/models/batch-track-globals.md:
id: 699dbe458957
last_write_checksum: sha1:b3f406e5e1b9ab5aa3958d3bfaabb7368a984867
pristine_git_object: a913f5697278a688222cf2b1d5aa0568b2898f8e
docs/models/batch-track-lock.md:
id: 88803d0a6a4d
last_write_checksum: sha1:743da3c668b9185627f8b98e3d48565be5212c64
pristine_git_object: 5f55d931c8529c327611ee71591aca50e6bbe0b1
docs/models/batch-track-response.md:
id: b2261111546c
last_write_checksum: sha1:8e95f5d7e418325f0b65746e5ef5c36254689219
pristine_git_object: b713fe163c80ce5fe148c68fcf038b2ca718e573
docs/models/billing-behavior.md:
id: 59f3b5602fbf
last_write_checksum: sha1:d77753a35a9487bef9f1ab3e0a9176a06dce432d
@@ -428,8 +440,8 @@ trackedFiles:
pristine_git_object: 7c5c0d332961e51e90e875930bc57fc5769f66dc
docs/models/billing-update-customize.md:
id: 533e2ca5e4bd
last_write_checksum: sha1:b4d050253435fb402fbf235fbda8099130957ea9
pristine_git_object: 57fb318450124f1f3c90720406298f8dcd194045
last_write_checksum: sha1:40c4d4c0cce5253fabbfe923d56af4fe97547037
pristine_git_object: 496080990229cdac916c5eb218996f62b68545b6
docs/models/billing-update-duration-type.md:
id: f711ec227260
last_write_checksum: sha1:98a5be59f2473d00d1b58725a918223ab19fa8dc
@@ -2068,8 +2080,8 @@ trackedFiles:
pristine_git_object: 19202b44796241442484db1fee13164091c3497c
docs/models/list-entities-params.md:
id: 92aba00d96aa
last_write_checksum: sha1:63f6d8d5c87aa3e9f30afa967d02c9d7f460bda0
pristine_git_object: 096d712b4791c84909b9f465f36f777c0d44b03f
last_write_checksum: sha1:eb00e7d04db7bcf5cc96669538c531c48bbd2946
pristine_git_object: 409eede145afb691774fdde8ea90ae2c2183a65e
docs/models/list-entities-plan.md:
id: 46b5b6920b73
last_write_checksum: sha1:0a15106cb1bdb2cd03c181351dfd44dbe36a2643
@@ -2632,8 +2644,8 @@ trackedFiles:
pristine_git_object: 64b48d4b9d52595ee992034610b5a04f2d11115d
docs/models/preview-attach-customize.md:
id: 56b1da317d34
last_write_checksum: sha1:78f32e49b79bd3c625aee7c9f5ed53dce732290f
pristine_git_object: 61249bae698d84509f82bd618269dc090e853612
last_write_checksum: sha1:a11a7ddbc4c1049968ae281ce83c6d4c0e4f965c
pristine_git_object: 32340f6a26d8d0e0e82a06b9f6ba906d7f8eb106
docs/models/preview-attach-discount.md:
id: 61e779cf6cd4
last_write_checksum: sha1:53a0ff16124f132a097dc2feffcbded47b54a620
@@ -3088,8 +3100,8 @@ trackedFiles:
pristine_git_object: 0bb67d6c2ccae89db38e76b9f6e7ec2116dc8d6e
docs/models/preview-update-customize.md:
id: 96ff2b01f7eb
last_write_checksum: sha1:004ef4debebb1422f38bc892170c7e6dcb2c7b53
pristine_git_object: d99c2263c30243ef627cfcd36288e033e4d5ced5
last_write_checksum: sha1:863399d07538515de925b9924bbbd14e1288b9f1
pristine_git_object: cf71b0d9ce6e8f4183d53b7330a0aa6522a2004d
docs/models/preview-update-discount.md:
id: 4b698ca5724f
last_write_checksum: sha1:6f978223349f2643cd7dd7bbaf828252d608f86b
@@ -3366,6 +3378,10 @@ trackedFiles:
id: b58def2d8bbe
last_write_checksum: sha1:6147d00b05240ea19ab4a012e37012501462790e
pristine_git_object: 6133ec7c2af5271b41ce09dddfb0eb8cbeb14418
docs/models/request-body.md:
id: c8db17c466f9
last_write_checksum: sha1:2d2515519b8dc6b4ce1b5d663e73307c775732c3
pristine_git_object: 4f54fb31462275086e474968960b97b1f2ad877d
docs/models/revenuecat.md:
id: 5418b6373a80
last_write_checksum: sha1:70e79f733d444a07f8d4e770469e87bdf4a3d946
@@ -3464,8 +3480,8 @@ trackedFiles:
pristine_git_object: da0bd393c71af8a6a36d1a17f0dbc16fc083c32b
docs/models/setup-payment-customize.md:
id: d99db9e22611
last_write_checksum: sha1:00d456e57b3d831daa8c42edfb09d119eb47a5b3
pristine_git_object: 32a7622c20c663f06b5363c6d794d92c02e048e3
last_write_checksum: sha1:9c1a2c24003fbee54a376405f018c37ad585ae60
pristine_git_object: e1019dca645e603a18ed1de3e110f165834a1c6d
docs/models/setup-payment-duration-type.md:
id: b318c12dbec9
last_write_checksum: sha1:641175152a85bb66d26c7226f4227cc8bddb00fb
@@ -3608,8 +3624,8 @@ trackedFiles:
pristine_git_object: c412e4254b5532fbecbb139b1ae5e0c57c9058dd
docs/models/track-params.md:
id: 68e025b0826f
last_write_checksum: sha1:2fa060bc795efd2a0ae9847a6cea279e939428a3
pristine_git_object: 55fa006ced11395c51d165a41989961f9e4fb50d
last_write_checksum: sha1:2c0b153d0c4f16ae9c83abac2365e1b5703ba68a
pristine_git_object: 85e79672de66ec1e155242b48f21bf1cd341d755
docs/models/track-reset1.md:
id: 6dc3e77e544b
last_write_checksum: sha1:402713fa21b63221ed9ac1ba3d2124554d9a206e
@@ -4140,24 +4156,24 @@ trackedFiles:
pristine_git_object: a844f92b2baa6185834718690d34643de01d62b2
docs/sdks/autumn/README.md:
id: d27c9292a1a3
last_write_checksum: sha1:4d49d2ee442e2d7ed8dede34951633a48546545b
pristine_git_object: c0965c3dba149c79dc016aab6adee2e1e4d32b2c
last_write_checksum: sha1:c615e04981de1c8f017bccc3c48a3549fdacf9f1
pristine_git_object: ff3a9aaa764436d0f5fe83a700248d88b3895804
docs/sdks/balances/README.md:
id: 6ca85866f00d
last_write_checksum: sha1:bd1e814fa0fa46eb24beefce2e585d9c8e4cb14a
pristine_git_object: 0ebe5146cd24c153cb9b7655e4f502c09f7d4abd
docs/sdks/billing/README.md:
id: dc915331dd9d
last_write_checksum: sha1:9a4fc3e15e59ee4c9e67940c8f018c51a26b4b20
pristine_git_object: 78602549ff88ec966759e008c36bd0ba217358f7
last_write_checksum: sha1:5423d957ca1402f6a9d9f0097c6e3f3eb0b23259
pristine_git_object: acafdb77810207e5d9ba9f8d1df82014e4c42435
docs/sdks/customers/README.md:
id: 9332759cffc2
last_write_checksum: sha1:74cd5f6cf800e1d86b2c332fed3c3cd53f3eeb6b
pristine_git_object: 94228c7448e58f0dd1d53e5ae3be57b0aaae8ade
docs/sdks/entities/README.md:
id: a140ac5181b9
last_write_checksum: sha1:9218d9c57b0f880056012a0058b6fcf22266809b
pristine_git_object: 660ee5a5ae602d5a59262df8be417b158b483b57
last_write_checksum: sha1:5574bc92c257f788670c4703173f1cd2f1ca78ce
pristine_git_object: f683b63897d2cd18e55cb3d207f1f1f353027f03
docs/sdks/events/README.md:
id: cf45a4390b9b
last_write_checksum: sha1:45cecb8b22ef4a343e770296553fb77fa91f6a24
@@ -4226,14 +4242,18 @@ trackedFiles:
id: a4d3bafe74f2
last_write_checksum: sha1:21a4dd56b45ce43d7fd007299538bec7f6b70a18
pristine_git_object: 79895a8f24a90c48cebf63e6f225160b91c2fc3e
src/funcs/batch-track.ts:
id: f959b325db84
last_write_checksum: sha1:f3619d42daa0999a0855f7a3cc4c1b1fda675aff
pristine_git_object: 0d0effc4820a44a283cd2fb7b6d4e81c03c6cdb5
src/funcs/billing-attach.ts:
id: c23b3cd15f32
last_write_checksum: sha1:6a90b6221d278158444ddb033ae881c4975b1d9c
pristine_git_object: d1d2c39eb61de5da6dc66da31605995ee35edd8b
src/funcs/billing-create-schedule.ts:
id: fd662bfcdc10
last_write_checksum: sha1:c33eafe7ebb47759d83e9ed220ee3c5ddeee921b
pristine_git_object: 1f5c0e795bc20f267bc9831e865adbf4aac9b903
last_write_checksum: sha1:3d7f3310fcb097be88ffcffd6fd665a03de020eb
pristine_git_object: 2be231df771eeeda8cd81e80be7c08800ec8cc1b
src/funcs/billing-multi-attach.ts:
id: 67491e2d8249
last_write_checksum: sha1:00ba80c1f98e7a8be29db0cf5a6957433f687861
@@ -4300,8 +4320,8 @@ trackedFiles:
pristine_git_object: ac3e07687390946e85825e6711f1b9f02f3195fd
src/funcs/entities-list.ts:
id: 589baf7729a5
last_write_checksum: sha1:96b615462da46c38d0d9f8160798733c11074a62
pristine_git_object: ec78a585695d94482aafe01de6f554e391c94365
last_write_checksum: sha1:6df35894c500b5b5e6263b01693542ae5ffc20ad
pristine_git_object: 91d6b8831f0bf0069cbe1cabce713bd4a6def288
src/funcs/entities-update.ts:
id: 45a3fa3d37e9
last_write_checksum: sha1:9d094430bd69e5393225a4b16144ffdab3634f13
@@ -4368,8 +4388,8 @@ trackedFiles:
pristine_git_object: 1555c8a918edb10c18af2a74bddc1e1e96711bb0
src/funcs/track.ts:
id: eb7e0b123329
last_write_checksum: sha1:d5ad71682c2787f22f2f4323d4230764abf369c6
pristine_git_object: 6002326bf87c62c1499e1edfe3e6b09f548e8c61
last_write_checksum: sha1:0495a4e4969e206b0d58747b9dbf3acc6beafc07
pristine_git_object: 935846ae41c2be0c4542723571499504e461ed12
src/hooks/hooks.ts:
id: a2463fc6f69b
last_write_checksum: sha1:3a90d88b4c6c07247db8e5f6441a79538232394e
@@ -4456,8 +4476,8 @@ trackedFiles:
pristine_git_object: 56dab308d7f8e1694b20a8e0509ecfa0b4149743
src/models/attach-op.ts:
id: 83ed65c26ab4
last_write_checksum: sha1:9c6168708877f6e1a469bc5aa2113bba89dc3fe0
pristine_git_object: ae86d7465e0762877601d1152dcd8fb3dfa64030
last_write_checksum: sha1:2cea09fc75a985eb5b7b5cf01bf81b3587e7aa7e
pristine_git_object: 81daebe594e6391be3bc16cc3d87f0ae909a8adb
src/models/autumn-default-error.ts:
id: 2528aa7886eb
last_write_checksum: sha1:4cce18f91be3262ada7d11dcd6326544e2341b58
@@ -4470,10 +4490,14 @@ trackedFiles:
id: d7bbe0a7b446
last_write_checksum: sha1:1283f88044007ac767ab7d1eebbf3480575113e8
pristine_git_object: 4b4ccd5b5a62412ae6d02baa88fecb8fbb89fe12
src/models/batch-track-op.ts:
id: 4d4addc42536
last_write_checksum: sha1:65242a83ff54ee30784cf3b590c3adcf209c7a7b
pristine_git_object: e3fa7ed778c7829d115c8a51f03df4618c9bf8f5
src/models/billing-update-op.ts:
id: e7371769c7ca
last_write_checksum: sha1:9d5c4fb1155d26791f2758adc7f1cb355a580d81
pristine_git_object: c8fbabc3150fec759e373472034b19ff82788e7e
last_write_checksum: sha1:c441192ab14334dacdaade3f77dc20f1c4482241
pristine_git_object: ff2ea202928d3208ad6c18d911b0d794b60a58af
src/models/check-op.ts:
id: 42085bda016a
last_write_checksum: sha1:dc22bb11dc8320f6196490df90a7ec600279ae18
@@ -4564,16 +4588,16 @@ trackedFiles:
pristine_git_object: b34f612124c797c2a1106b9735708f679a90b74f
src/models/index.ts:
id: f93644b0f37e
last_write_checksum: sha1:11568091061cb5af55f32fbaf0aea7e1666ac103
pristine_git_object: f2fb121e8394795763999ae153353a61a1ff07d9
last_write_checksum: sha1:99b491a94a7a8810c6916539ef699036680e132c
pristine_git_object: e63734a484c768b68cce9cc70f4886c577840340
src/models/list-customers-op.ts:
id: b391692c8429
last_write_checksum: sha1:0b5806bf37d88bbad002d82bf404d5f3b8762593
pristine_git_object: 49c50334b82a7d58677307d3791be2ced19c8a06
src/models/list-entities-op.ts:
id: 4cbb69f4a0cd
last_write_checksum: sha1:18424f0889282c5c4e62efabaac1a703c2a5dab0
pristine_git_object: 681ba8b7d889f2d04a7bba6f3f9bd1a16aa6ba27
last_write_checksum: sha1:a48ac579bc008f7a3100664b4dfe0a4803a5650e
pristine_git_object: 298ba3d842c166c29339394e9b8173cefc500431
src/models/list-events-op.ts:
id: 82a9f364bb21
last_write_checksum: sha1:32c875df2a181a5aa651f4350a2a7114a8c92bd1
@@ -4600,16 +4624,16 @@ trackedFiles:
pristine_git_object: edba9d825d88c26f3322be98e78d37ffd2699f99
src/models/preview-attach-op.ts:
id: 3efc6e3443a7
last_write_checksum: sha1:67003cd3b95e13677ec06087d85d38c2d4622725
pristine_git_object: da50b22ad5e5146bf440ff8b9f5369fe63fd4dd2
last_write_checksum: sha1:082165441c5b9cab621986bf421c2a3d896eec96
pristine_git_object: 322a2a97e447cb996821f8460633c6ec73ceb8bd
src/models/preview-multi-attach-op.ts:
id: e4847dc281a6
last_write_checksum: sha1:9ed03201b7c46f70fcb595c034ca9c2fa572a948
pristine_git_object: 14d6547dde8246cfe212177717cd91af13b8570b
src/models/preview-update-op.ts:
id: fcbbbf3b22ac
last_write_checksum: sha1:eedeb1fdeb6c9dab9de48f6ef8ccd0a2fa89cb28
pristine_git_object: 51e60f7f2348ca49cbab1f4712db586d29e88885
last_write_checksum: sha1:7b587a2c1fd03bd76dbc3e15b13d642894cc1d73
pristine_git_object: d9157676429d2b3cc19a15a8ec8b7c8c0c3b8c83
src/models/redeem-referral-code-op.ts:
id: 511bf73dc4c6
last_write_checksum: sha1:9ab6622018c82175ea98d2b26eadb4abf08f441a
@@ -4632,12 +4656,12 @@ trackedFiles:
pristine_git_object: 3774cc1e9bbb80ac592990aa86f8d4a38ee51f29
src/models/setup-payment-op.ts:
id: 0e97e999ff3c
last_write_checksum: sha1:d4d9bfb7975fac87b20760b7f788f21cc48cfe7d
pristine_git_object: e7a0f9e89212ba2c7e8dac653f568b7990e41f11
last_write_checksum: sha1:c09cf100a8eaedfc307aa7037081eece0db24d82
pristine_git_object: 888b6921e5d7f7526d33f3dfc3a5c4eceb93e55b
src/models/track-op.ts:
id: 5e6a750e8fec
last_write_checksum: sha1:d79666567155fbb299cd6de94e0cea78b0df8e2f
pristine_git_object: 5df05b2457932a7f274afd3ed2276d5c9b28014d
last_write_checksum: sha1:b4ccb3514075bcb1b67df61bdbe52154c46e21b2
pristine_git_object: 8efd488c024591ba05edff0229dd2070a885be9b
src/models/update-balance-op.ts:
id: 69282313a00e
last_write_checksum: sha1:d8a5f711a56c32c9dd9fb71b611df33684a3c260
@@ -4664,16 +4688,16 @@ trackedFiles:
pristine_git_object: 571de419ea3321d79acec4bddbb46b1580007115
src/sdk/billing.ts:
id: 10905058c4ad
last_write_checksum: sha1:3c7183849465b82416816faecf440b4ac29ae17d
pristine_git_object: 298f33f82706d9b36ba1c65b0806ab2d66bfc083
last_write_checksum: sha1:e688a0ee91f993a4e34f714ce6cd983194c94ee6
pristine_git_object: 060ff391aa40a75d4c2f19b24ca4645d6e6fe140
src/sdk/customers.ts:
id: d33e193e0c00
last_write_checksum: sha1:8d64f03efa17b4ef45a6d67a44d23e2943f1cd8b
pristine_git_object: 307ba52467887f429aac029db75944b5812fc502
src/sdk/entities.ts:
id: 71997b5f9b62
last_write_checksum: sha1:2b2f2ccb94c4a1799990766605cc381af00c6a44
pristine_git_object: 9f30b7a762a7771dc31428c9ea6d1c7ff8215fcc
last_write_checksum: sha1:74312ff6c6c810294596acd86cbe59644623441d
pristine_git_object: d322b70d571d5aa9d3bde9b08c6c012fcd20e0a0
src/sdk/events.ts:
id: c7d130088b17
last_write_checksum: sha1:1dd099274cb75cb4ae46d01fa68ea13b53a79e1a
@@ -4700,8 +4724,8 @@ trackedFiles:
pristine_git_object: f6a3928ecbf5b6a9907bc7d405808d0839848a04
src/sdk/sdk.ts:
id: 784571af2f69
last_write_checksum: sha1:5ad3c2299a5a7ca4a92312b9297ed3ba9f451e15
pristine_git_object: ce58bc0c231566e8b26f79bdbdd9609f72d4882b
last_write_checksum: sha1:91b52ea99e9a7b641d6c66d525961a174bd258ed
pristine_git_object: 2b0197cb19c31124a3b1cad3a38dec70d3856159
src/types/async.ts:
id: fac8da972f86
last_write_checksum: sha1:3ff07b3feaf390ec1aeb18ff938e139c6c4a9585
@@ -5604,4 +5628,14 @@ examples:
responses:
"200":
application/json: {"reward_id": "reward_789", "entitlements_granted": [{"feature_id": "messages", "balance": 100}]}
batchTrack:
speakeasy-default-batch-track:
parameters:
header:
x-api-version: "2.3.0"
requestBody:
application/json: [{"customer_id": "cus_123", "feature_id": "messages", "value": 1}, {"customer_id": "cus_123", "event_name": "message.sent", "value": 1}]
responses:
"202":
application/json: {"success": true}
examplesVersion: 1.0.2

View File

@@ -113,6 +113,7 @@ typescript:
packageName: '@useautumn/sdk'
preApplyUnionDiscriminators: true
preserveModelFieldNames: false
privateIdentifierPrefix: '#'
responseFormat: flat
sseFlatResponse: false
templateVersion: v2

View File

@@ -7580,7 +7580,7 @@ paths:
- feature_id
title: PlanItem
description: Configuration for a feature item in a plan, including usage limits, pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
add_items:
type: array
items:
@@ -8017,7 +8017,7 @@ paths:
@example
```typescript
// Schedule a transition from a trial plan to a paid plan
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779292757190,"plans":[{"planId":"trial_plan"}]},{"startsAt":1780502357190,"plans":[{"planId":"pro_plan"}]}] });
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779977746466,"plans":[{"planId":"trial_plan"}]},{"startsAt":1781187346466,"plans":[{"planId":"pro_plan"}]}] });
```
@param customerId - The ID of the customer to create the schedule for.
@@ -9479,7 +9479,7 @@ paths:
- feature_id
title: PlanItem
description: Configuration for a feature item in a plan, including usage limits, pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
add_items:
type: array
items:
@@ -11318,7 +11318,7 @@ paths:
- feature_id
title: PlanItem
description: Configuration for a feature item in a plan, including usage limits, pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
add_items:
type: array
items:
@@ -11948,7 +11948,7 @@ paths:
- feature_id
title: PlanItem
description: Configuration for a feature item in a plan, including usage limits, pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
add_items:
type: array
items:
@@ -12881,7 +12881,7 @@ paths:
- feature_id
title: PlanItem
description: Configuration for a feature item in a plan, including usage limits, pricing, and rollover settings.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
description: Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
add_items:
type: array
items:
@@ -14704,6 +14704,8 @@ paths:
@param properties - Additional properties to attach to this usage event. (optional)
@param async - If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information. (optional)
@returns The usage value recorded, with either a single updated balance or a map of updated balances. If Autumn is experiencing degraded service from a downstream provider, the API may return 202 after accepting the event for replay so it can be tracked as soon as the service is restored.
requestBody:
@@ -14735,6 +14737,9 @@ paths:
type: string
additionalProperties: {}
description: Additional properties to attach to this usage event.
async:
type: boolean
description: If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information.
lock:
type: object
properties:
@@ -15018,6 +15023,89 @@ paths:
x-speakeasy-name-override: track
parameters:
- *a1
/v1/balances.batch_track:
post:
operationId: batchTrack
description: Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.
requestBody:
required: true
content:
application/json:
schema:
type: array
minItems: 1
maxItems: 1000
items:
type: object
properties:
customer_id:
type: string
description: The ID of the customer.
feature_id:
type: string
description: The ID of the feature to track usage for. Required if event_name is not provided.
entity_id:
type: string
description: The ID of the entity for entity-scoped balances (e.g., per-seat limits).
event_name:
type: string
minLength: 1
description: Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event.
value:
type: number
description: The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat).
properties:
type: object
propertyNames:
type: string
additionalProperties: {}
description: Additional properties to attach to this usage event.
async:
type: boolean
description: If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information.
lock:
type: object
properties:
lock_id:
type: string
maxLength: 256
description: A unique identifier for this lock. Used to finalize the lock later via balances.finalize.
enabled:
const: true
description: Must be true to enable locking.
expires_at:
type: number
description: Unix timestamp (ms) when the lock automatically expires and releases the held balance.
required:
- lock_id
- enabled
required:
- customer_id
title: BatchTrackParams
examples:
- - customer_id: cus_123
feature_id: messages
value: 1
- customer_id: cus_123
event_name: message.sent
value: 1
responses:
"202":
description: "Batch accepted. All items passed synchronous validation. Enqueue is best-effort: partial failures (some items enqueued, some not) are logged server-side and are NOT surfaced in the response body; clients must not retry on 202. See the endpoint description for full partial-failure semantics."
content:
application/json:
schema:
type: object
properties:
success:
const: true
required:
- success
examples:
- success: true
x-speakeasy-name-override: batchTrack
parameters:
- *a1
/v1/events.list:
post:
operationId: listEvents
@@ -16478,6 +16566,8 @@ paths:
@param processors - Filter by parent customer processor type (stripe, revenuecat, vercel). (optional)
@param customerId - Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get. (optional)
@returns A paginated list of entity objects including their current subscriptions, purchases, balances, and flags.
tags:
@@ -16531,6 +16621,10 @@ paths:
- vercel
type: string
description: Filter by parent customer processor type (stripe, revenuecat, vercel).
customer_id:
type: string
minLength: 1
description: Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get.
title: ListEntitiesParams
examples:
- start_cursor: ""

View File

@@ -2,8 +2,8 @@ speakeasyVersion: 1.762.0
sources:
Autumn API:
sourceNamespace: autumn-api
sourceRevisionDigest: sha256:60582eaf2873eef162c828bee020b951379aefacd15d15f8b92a2c5b947b1802
sourceBlobDigest: sha256:4f214e215cb673be15a2ae97b12b6f85bf3e9f7092b1d77e5811cdfca548e113
sourceRevisionDigest: sha256:547dd234014ff5ad38782138c19b3d1da53613c9161dad092bf14a8c84132020
sourceBlobDigest: sha256:c7017b9c4d86350a4183e14f7d26175e3f1481a0ed4c8f8b7224cd55177b39f5
tags:
- latest
- 2.3.0
@@ -18,10 +18,10 @@ targets:
autumn:
source: Autumn API
sourceNamespace: autumn-api
sourceRevisionDigest: sha256:60582eaf2873eef162c828bee020b951379aefacd15d15f8b92a2c5b947b1802
sourceBlobDigest: sha256:4f214e215cb673be15a2ae97b12b6f85bf3e9f7092b1d77e5811cdfca548e113
sourceRevisionDigest: sha256:547dd234014ff5ad38782138c19b3d1da53613c9161dad092bf14a8c84132020
sourceBlobDigest: sha256:c7017b9c4d86350a4183e14f7d26175e3f1481a0ed4c8f8b7224cd55177b39f5
codeSamplesNamespace: autumn-api-typescript-code-samples
codeSamplesRevisionDigest: sha256:50d8d0200f9c5b6576e88bfbd9419b90203c445bb380005cb5c98ed290d494d3
codeSamplesRevisionDigest: sha256:390a84592b93615e744ea5718a1e1b2558bdcd7de01261a10be301c224edddc2
autumn-python:
source: Autumn API Stripped
sourceNamespace: autumn-api-stripped

View File

@@ -203,8 +203,10 @@ const response = await client.track({ customerId: "cus_123", eventName: "ai_chat
@param eventName - Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event. (optional)
@param value - The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat). (optional)
@param properties - Additional properties to attach to this usage event. (optional)
@param async - If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information. (optional)
@returns The usage value recorded, with either a single updated balance or a map of updated balances. If Autumn is experiencing degraded service from a downstream provider, the API may return 202 after accepting the event for replay so it can be tracked as soon as the service is restored.
* [batchTrack](docs/sdks/autumn/README.md#batchtrack) - Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.
### [Balances](docs/sdks/balances/README.md)
@@ -272,7 +274,7 @@ Use this endpoint to schedule future plan changes (e.g. switch from a trial plan
@example
```typescript
// Schedule a transition from a trial plan to a paid plan
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779292757190,"plans":[{"planId":"trial_plan"}]},{"startsAt":1780502357190,"plans":[{"planId":"pro_plan"}]}] });
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779977746466,"plans":[{"planId":"trial_plan"}]},{"startsAt":1781187346466,"plans":[{"planId":"pro_plan"}]}] });
```
@param customerId - The ID of the customer to create the schedule for.
@@ -566,6 +568,7 @@ const response = await client.entities.list({ search: "workspace" });
@param subscriptionStatus - Filter customer products used for entity hydration and plan matching. Defaults to active and scheduled. (optional)
@param search - Search entities by id or name. (optional)
@param processors - Filter by parent customer processor type (stripe, revenuecat, vercel). (optional)
@param customerId - Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get. (optional)
@returns A paginated list of entity objects including their current subscriptions, purchases, balances, and flags.
* [update](docs/sdks/entities/README.md#update) - Updates an existing entity and returns the refreshed entity object.
@@ -732,6 +735,7 @@ To read more about standalone functions, check [FUNCTIONS.md](./FUNCTIONS.md).
- [`balancesDelete`](docs/sdks/balances/README.md#delete) - Delete a balance for a customer feature. Can only delete a balance that is not attached to a price (eg. you cannot delete messages that have an overage price).
- [`balancesFinalize`](docs/sdks/balances/README.md#finalize) - Finalize a previously locked balance. Use 'confirm' to commit the deduction, or 'release' to return the held balance.
- [`balancesUpdate`](docs/sdks/balances/README.md#update) - Update a customer balance.
- [`batchTrack`](docs/sdks/autumn/README.md#batchtrack) - Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.
- [`billingAttach`](docs/sdks/billing/README.md#attach) - Attaches a plan to a customer. Handles new subscriptions, upgrades and downgrades.
Use this endpoint to subscribe a customer to a plan, upgrade/downgrade between plans, or add an add-on product.
@@ -789,7 +793,7 @@ Use this endpoint to schedule future plan changes (e.g. switch from a trial plan
@example
```typescript
// Schedule a transition from a trial plan to a paid plan
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779292757190,"plans":[{"planId":"trial_plan"}]},{"startsAt":1780502357190,"plans":[{"planId":"pro_plan"}]}] });
const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779977746466,"plans":[{"planId":"trial_plan"}]},{"startsAt":1781187346466,"plans":[{"planId":"pro_plan"}]}] });
```
@param customerId - The ID of the customer to create the schedule for.
@@ -1123,6 +1127,7 @@ const response = await client.entities.list({ search: "workspace" });
@param subscriptionStatus - Filter customer products used for entity hydration and plan matching. Defaults to active and scheduled. (optional)
@param search - Search entities by id or name. (optional)
@param processors - Filter by parent customer processor type (stripe, revenuecat, vercel). (optional)
@param customerId - Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get. (optional)
@returns A paginated list of entity objects including their current subscriptions, purchases, balances, and flags.
- [`entitiesUpdate`](docs/sdks/entities/README.md#update) - Updates an existing entity and returns the refreshed entity object.
@@ -1259,6 +1264,7 @@ const response = await client.track({ customerId: "cus_123", eventName: "ai_chat
@param eventName - Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event. (optional)
@param value - The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat). (optional)
@param properties - Additional properties to attach to this usage event. (optional)
@param async - If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information. (optional)
@returns The usage value recorded, with either a single updated balance or a map of updated balances. If Autumn is experiencing degraded service from a downstream provider, the API may return 202 after accepting the event for replay so it can be tracked as soon as the service is restored.

View File

@@ -0,0 +1,165 @@
/*
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
*/
import * as z from "zod/v4-mini";
import { AutumnCore } from "../core.js";
import { encodeJSON, encodeSimple } from "../lib/encodings.js";
import { matchStatusCode } from "../lib/http.js";
import * as M from "../lib/matchers.js";
import { compactMap } from "../lib/primitives.js";
import { safeParse } from "../lib/schemas.js";
import { RequestOptions } from "../lib/sdks.js";
import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js";
import { pathToFunc } from "../lib/url.js";
import { AutumnError } from "../models/autumn-error.js";
import {
ConnectionError,
InvalidRequestError,
RequestAbortedError,
RequestTimeoutError,
UnexpectedClientError,
} from "../models/http-client-errors.js";
import * as models from "../models/index.js";
import { ResponseValidationError } from "../models/response-validation-error.js";
import { SDKValidationError } from "../models/sdk-validation-error.js";
import { APICall, APIPromise } from "../types/async.js";
import { Result } from "../types/fp.js";
/**
* Enqueue up to 1000 usage events for asynchronous processing. Items are validated synchronously up front; validated items are then enqueued via SQS for background deduction by workers. The response returns 202 immediately and does not include balance information. On partial enqueue failure (some items fail to enqueue, others succeed), the endpoint still returns 202 and logs the failures server-side; clients should NOT retry, because retrying re-enqueues the already-succeeded items. A 503 is returned only when zero items were successfully enqueued (queue entirely unavailable) — that case is safe to retry.
*/
export function batchTrack(
client: AutumnCore,
request: Array<models.RequestBody>,
options?: RequestOptions,
): APIPromise<
Result<
models.BatchTrackResponse,
| AutumnError
| ResponseValidationError
| ConnectionError
| RequestAbortedError
| RequestTimeoutError
| InvalidRequestError
| UnexpectedClientError
| SDKValidationError
>
> {
return new APIPromise($do(
client,
request,
options,
));
}
async function $do(
client: AutumnCore,
request: Array<models.RequestBody>,
options?: RequestOptions,
): Promise<
[
Result<
models.BatchTrackResponse,
| AutumnError
| ResponseValidationError
| ConnectionError
| RequestAbortedError
| RequestTimeoutError
| InvalidRequestError
| UnexpectedClientError
| SDKValidationError
>,
APICall,
]
> {
const parsed = safeParse(
request,
(value) => z.parse(z.array(models.RequestBody$outboundSchema), value),
"Input validation failed",
);
if (!parsed.ok) {
return [parsed, { status: "invalid" }];
}
const payload = parsed.value;
const body = encodeJSON("body", payload, { explode: true });
const path = pathToFunc("/v1/balances.batch_track")();
const headers = new Headers(compactMap({
"Content-Type": "application/json",
Accept: "application/json",
"x-api-version": encodeSimple(
"x-api-version",
client._options.xApiVersion,
{ explode: false, charEncoding: "none" },
),
}));
const secConfig = await extractSecurity(client._options.secretKey);
const securityInput = secConfig == null ? {} : { secretKey: secConfig };
const requestSecurity = resolveGlobalSecurity(securityInput);
const context = {
options: client._options,
baseURL: options?.serverURL ?? client._baseURL ?? "",
operationID: "batchTrack",
oAuth2Scopes: null,
resolvedSecurity: requestSecurity,
securitySource: client._options.secretKey,
retryConfig: options?.retries
|| client._options.retryConfig
|| { strategy: "none" },
retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"],
};
const requestRes = client._createRequest(context, {
security: requestSecurity,
method: "POST",
baseURL: options?.serverURL,
path: path,
headers: headers,
body: body,
userAgent: client._options.userAgent,
timeoutMs: options?.timeoutMs || client._options.timeoutMs || -1,
}, options);
if (!requestRes.ok) {
return [requestRes, { status: "invalid" }];
}
const req = requestRes.value;
const doResult = await client._do(req, {
context,
isErrorStatusCode: (statusCode: number) =>
matchStatusCode({ status: statusCode } as Response, ["4XX", "5XX"]),
retryConfig: context.retryConfig,
retryCodes: context.retryCodes,
});
if (!doResult.ok) {
return [doResult, { status: "request-error", request: req }];
}
const response = doResult.value;
const [result] = await M.match<
models.BatchTrackResponse,
| AutumnError
| ResponseValidationError
| ConnectionError
| RequestAbortedError
| RequestTimeoutError
| InvalidRequestError
| UnexpectedClientError
| SDKValidationError
>(
M.json(202, models.BatchTrackResponse$inboundSchema),
M.fail("4XX"),
M.fail("5XX"),
)(response, req);
if (!result.ok) {
return [result, { status: "complete", request: req, response }];
}
return [result, { status: "complete", request: req, response }];
}

View File

@@ -34,7 +34,7 @@ import { Result } from "../types/fp.js";
* @example
* ```typescript
* // Schedule a transition from a trial plan to a paid plan
* const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779292757190,"plans":[{"planId":"trial_plan"}]},{"startsAt":1780502357190,"plans":[{"planId":"pro_plan"}]}] });
* const response = await client.billing.createSchedule({ customerId: "cus_123", phases: [{"startsAt":1779977746466,"plans":[{"planId":"trial_plan"}]},{"startsAt":1781187346466,"plans":[{"planId":"pro_plan"}]}] });
* ```
*
* @param customerId - The ID of the customer to create the schedule for.

View File

@@ -49,6 +49,7 @@ import { Result } from "../types/fp.js";
* @param subscriptionStatus - Filter customer products used for entity hydration and plan matching. Defaults to active and scheduled. (optional)
* @param search - Search entities by id or name. (optional)
* @param processors - Filter by parent customer processor type (stripe, revenuecat, vercel). (optional)
* @param customerId - Restrict the response to entities owned by this customer id. Use to bulk-fetch all entities for one customer in a single paginated call instead of iterating entities.get. (optional)
*
* @returns A paginated list of entity objects including their current subscriptions, purchases, balances, and flags.
*/

View File

@@ -49,6 +49,7 @@ import { Result } from "../types/fp.js";
* @param eventName - Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event. (optional)
* @param value - The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat). (optional)
* @param properties - Additional properties to attach to this usage event. (optional)
* @param async - If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information. (optional)
*
* @returns The usage value recorded, with either a single updated balance or a map of updated balances. If Autumn is experiencing degraded service from a downstream provider, the API may return 202 after accepting the event for replay so it can be tracked as soon as the service is restored.
*/

View File

@@ -638,7 +638,7 @@ export type AttachCustomize = {
*/
price?: AttachBasePrice | null | undefined;
/**
* Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
* Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
*/
items?: Array<AttachItemPlanItem> | undefined;
/**

View File

@@ -0,0 +1,156 @@
/*
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
*/
import * as z from "zod/v4-mini";
import { remap as remap$ } from "../lib/primitives.js";
import { safeParse } from "../lib/schemas.js";
import { Result as SafeParseResult } from "../types/fp.js";
import * as types from "../types/primitives.js";
import { SDKValidationError } from "./sdk-validation-error.js";
export type BatchTrackGlobals = {
xApiVersion?: string | undefined;
};
export type BatchTrackLock = {
/**
* A unique identifier for this lock. Used to finalize the lock later via balances.finalize.
*/
lockId: string;
/**
* Must be true to enable locking.
*/
enabled: true;
/**
* Unix timestamp (ms) when the lock automatically expires and releases the held balance.
*/
expiresAt?: number | undefined;
};
export type RequestBody = {
/**
* The ID of the customer.
*/
customerId: string;
/**
* The ID of the feature to track usage for. Required if event_name is not provided.
*/
featureId?: string | undefined;
/**
* The ID of the entity for entity-scoped balances (e.g., per-seat limits).
*/
entityId?: string | undefined;
/**
* Event name to track usage for. Use instead of feature_id when multiple features should be tracked from a single event.
*/
eventName?: string | undefined;
/**
* The amount of usage to record. Defaults to 1. Use negative values to credit balance (e.g., when removing a seat).
*/
value?: number | undefined;
/**
* Additional properties to attach to this usage event.
*/
properties?: { [k: string]: any } | undefined;
/**
* If true, enqueue the event for asynchronous processing and return 202 immediately. The response will not include balance information.
*/
async?: boolean | undefined;
lock?: BatchTrackLock | undefined;
};
/**
* Batch accepted. All items passed synchronous validation. Enqueue is best-effort: partial failures (some items enqueued, some not) are logged server-side and are NOT surfaced in the response body; clients must not retry on 202. See the endpoint description for full partial-failure semantics.
*/
export type BatchTrackResponse = {
success: true;
};
/** @internal */
export type BatchTrackLock$Outbound = {
lock_id: string;
enabled: true;
expires_at?: number | undefined;
};
/** @internal */
export const BatchTrackLock$outboundSchema: z.ZodMiniType<
BatchTrackLock$Outbound,
BatchTrackLock
> = z.pipe(
z.object({
lockId: z.string(),
enabled: z.literal(true),
expiresAt: z.optional(z.number()),
}),
z.transform((v) => {
return remap$(v, {
lockId: "lock_id",
expiresAt: "expires_at",
});
}),
);
export function batchTrackLockToJSON(batchTrackLock: BatchTrackLock): string {
return JSON.stringify(BatchTrackLock$outboundSchema.parse(batchTrackLock));
}
/** @internal */
export type RequestBody$Outbound = {
customer_id: string;
feature_id?: string | undefined;
entity_id?: string | undefined;
event_name?: string | undefined;
value?: number | undefined;
properties?: { [k: string]: any } | undefined;
async?: boolean | undefined;
lock?: BatchTrackLock$Outbound | undefined;
};
/** @internal */
export const RequestBody$outboundSchema: z.ZodMiniType<
RequestBody$Outbound,
RequestBody
> = z.pipe(
z.object({
customerId: z.string(),
featureId: z.optional(z.string()),
entityId: z.optional(z.string()),
eventName: z.optional(z.string()),
value: z.optional(z.number()),
properties: z.optional(z.record(z.string(), z.any())),
async: z.optional(z.boolean()),
lock: z.optional(z.lazy(() => BatchTrackLock$outboundSchema)),
}),
z.transform((v) => {
return remap$(v, {
customerId: "customer_id",
featureId: "feature_id",
entityId: "entity_id",
eventName: "event_name",
});
}),
);
export function requestBodyToJSON(requestBody: RequestBody): string {
return JSON.stringify(RequestBody$outboundSchema.parse(requestBody));
}
/** @internal */
export const BatchTrackResponse$inboundSchema: z.ZodMiniType<
BatchTrackResponse,
unknown
> = z.object({
success: types.literal(true),
});
export function batchTrackResponseFromJSON(
jsonString: string,
): SafeParseResult<BatchTrackResponse, SDKValidationError> {
return safeParse(
jsonString,
(x) => BatchTrackResponse$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'BatchTrackResponse' from JSON`,
);
}

View File

@@ -648,7 +648,7 @@ export type BillingUpdateCustomize = {
*/
price?: BillingUpdateBasePrice | null | undefined;
/**
* Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.
* Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items / update_items.
*/
items?: Array<BillingUpdateItemPlanItem> | undefined;
/**

View File

@@ -7,6 +7,7 @@ export * from "./attach-op.js";
export * from "./autumn-default-error.js";
export * from "./autumn-error.js";
export * from "./balance.js";
export * from "./batch-track-op.js";
export * from "./billing-update-op.js";
export * from "./check-op.js";
export * from "./create-balance-op.js";

Some files were not shown because too many files have changed in this diff Show More