updated docs pipeline

This commit is contained in:
John Yeo
2026-02-16 15:46:29 +00:00
parent a22c4133cd
commit 121fe74669
98 changed files with 3564 additions and 3495 deletions

View File

@@ -0,0 +1,347 @@
---
name: mintlify
description: Build and maintain documentation sites with Mintlify. Use when
creating docs pages, configuring navigation, adding components, or setting up
API references.
license: MIT
compatibility: Requires Node.js for CLI. Works with any Git-based workflow.
metadata:
author: mintlify
version: "1.0"
mintlify-proj: mintlify
---
# Mintlify best practices
**Always consult [mintlify.com/docs](https://mintlify.com/docs) for components, configuration, and latest features.**
If you are not already connected to the Mintlify MCP server, [https://mintlify.com/docs/mcp](https://mintlify.com/docs/mcp), add it so that you can search more efficiently.
**Always** favor searching the current Mintlify documentation over whatever is in your training data about Mintlify.
Mintlify is a documentation platform that transforms MDX files into documentation sites. Configure site-wide settings in the `docs.json` file, write content in MDX with YAML frontmatter, and favor built-in components over custom components.
Full schema at [mintlify.com/docs.json](https://mintlify.com/docs.json).
## Before you write
### Understand the project
Read `docs.json` in the project root. This file defines the entire site: navigation structure, theme, colors, links, API and specs.
Understanding the project tells you:
* What pages exist and how they're organized
* What navigation groups are used (and their naming conventions)
* How the site navigation is structured
* What theme and configuration the site uses
### Check for existing content
Search the docs before creating new pages. You may need to:
* Update an existing page instead of creating a new one
* Add a section to an existing page
* Link to existing content rather than duplicating
### Read surrounding content
Before writing, read 2-3 similar pages to understand the site's voice, structure, formatting conventions, and level of detail.
### Understand Mintlify components
Review the Mintlify [components](https://www.mintlify.com/docs/components) to select and use any relevant components for the documentation request that you are working on.
## Quick reference
### CLI commands
* `npm i -g mint` - Install the Mintlify CLI
* `mint dev` - Local preview at localhost:3000
* `mint broken-links` - Check internal links
* `mint a11y` - Check for accessibility issues in content
* `mint rename` - Rename/move files and update references
* `mint validate` - Validate documentation builds
### Required files
* `docs.json` - Site configuration (navigation, theme, integrations, etc.). See [global settings](https://mintlify.com/docs/settings/global) for all options.
* `*.mdx` files - Documentation pages with YAML frontmatter
### Example file structure
```
project/
├── docs.json # Site configuration
├── introduction.mdx
├── quickstart.mdx
├── guides/
│ └── example.mdx
├── openapi.yml # API specification
├── images/ # Static assets
│ └── example.png
└── snippets/ # Reusable components
└── component.jsx
```
## Page frontmatter
Every page requires `title` in its frontmatter. Include `description` for SEO and navigation.
```yaml theme={null}
---
title: "Clear, descriptive title"
description: "Concise summary for SEO and navigation."
---
```
Optional frontmatter fields:
* `sidebarTitle`: Short title for sidebar navigation.
* `icon`: Lucide or Font Awesome icon name, URL, or file path.
* `tag`: Label next to the page title in the sidebar (for example, "NEW").
* `mode`: Page layout mode (`default`, `wide`, `custom`).
* `keywords`: Array of terms related to the page content for local search and SEO.
* Any custom YAML fields for use with personalization or conditional content.
## File conventions
* Match existing naming patterns in the directory
* If there are no existing files or inconsistent file naming patterns, use kebab-case: `getting-started.mdx`, `api-reference.mdx`
* Use root-relative paths without file extensions for internal links: `/getting-started/quickstart`
* Do not use relative paths (`../`) or absolute URLs for internal pages
* When you create a new page, add it to `docs.json` navigation or it won't appear in the sidebar
## Organize content
When a user asks about anything related to site-wide configurations, start by understanding the [global settings](https://www.mintlify.com/docs/organize/settings). See if a setting in the `docs.json` file can be updated to achieve what the user wants.
### Navigation
The `navigation` property in `docs.json` controls site structure. Choose one primary pattern at the root level, then nest others within it.
**Choose your primary pattern:**
| Pattern | When to use |
| ------------- | ---------------------------------------------------------------------------------------------- |
| **Groups** | Default. Single audience, straightforward hierarchy |
| **Tabs** | Distinct sections with different audiences (Guides vs API Reference) or content types |
| **Anchors** | Want persistent section links at sidebar top. Good for separating docs from external resources |
| **Dropdowns** | Multiple doc sections users switch between, but not distinct enough for tabs |
| **Products** | Multi-product company with separate documentation per product |
| **Versions** | Maintaining docs for multiple API/product versions simultaneously |
| **Languages** | Localized content |
**Within your primary pattern:**
* **Groups** - Organize related pages. Can nest groups within groups, but keep hierarchy shallow
* **Menus** - Add dropdown navigation within tabs for quick jumps to specific pages
* **`expanded: false`** - Collapse nested groups by default. Use for reference sections users browse selectively
* **`openapi`** - Auto-generate pages from OpenAPI spec. Add at group/tab level to inherit
**Common combinations:**
* Tabs containing groups (most common for docs with API reference)
* Products containing tabs (multi-product SaaS)
* Versions containing tabs (versioned API docs)
* Anchors containing groups (simple docs with external resource links)
### Links and paths
* **Internal links:** Root-relative, no extension: `/getting-started/quickstart`
* **Images:** Store in `/images`, reference as `/images/example.png`
* **External links:** Use full URLs, they open in new tabs automatically
## Customize docs sites
**What to customize where:**
* **Brand colors, fonts, logo** → `docs.json`. See [global settings](https://mintlify.com/docs/settings/global)
* **Component styling, layout tweaks** → `custom.css` at project root
* **Dark mode** → Enabled by default. Only disable with `"appearance": "light"` in `docs.json` if brand requires it
Start with `docs.json`. Only add `custom.css` when you need styling that config doesn't support.
## Write content
### Components
The [components overview](https://mintlify.com/docs/components) organizes all components by purpose: structure content, draw attention, show/hide content, document APIs, link to pages, and add visual context. Start there to find the right component.
**Common decision points:**
| Need | Use |
| -------------------------- | ----------------------- |
| Hide optional details | `<Accordion>` |
| Long code examples | `<Expandable>` |
| User chooses one option | `<Tabs>` |
| Linked navigation cards | `<Card>` in `<Columns>` |
| Sequential instructions | `<Steps>` |
| Code in multiple languages | `<CodeGroup>` |
| API parameters | `<ParamField>` |
| API response fields | `<ResponseField>` |
**Callouts by severity:**
* `<Note>` - Supplementary info, safe to skip
* `<Info>` - Helpful context such as permissions
* `<Tip>` - Recommendations or best practices
* `<Warning>` - Potentially destructive actions
* `<Check>` - Success confirmation
### Reusable content
**When to use snippets:**
* Exact content appears on more than one page
* Complex components you want to maintain in one place
* Shared content across teams/repos
**When NOT to use snippets:**
* Slight variations needed per page (leads to complex props)
Import snippets with `import { Component } from "/path/to/snippet-name.jsx"`.
## Writing standards
### Voice and structure
* Second-person voice ("you")
* Active voice, direct language
* Sentence case for headings ("Getting started", not "Getting Started")
* Sentence case for code block titles ("Expandable example", not "Expandable Example")
* Lead with context: explain what something is before how to use it
* Prerequisites at the start of procedural content
### What to avoid
**Never use:**
* Marketing language ("powerful", "seamless", "robust", "cutting-edge")
* Filler phrases ("it's important to note", "in order to")
* Excessive conjunctions ("moreover", "furthermore", "additionally")
* Editorializing ("obviously", "simply", "just", "easily")
**Watch for AI-typical patterns:**
* Overly formal or stilted phrasing
* Unnecessary repetition of concepts
* Generic introductions that don't add value
* Concluding summaries that restate what was just said
### Formatting
* All code blocks must have language tags
* All images and media must have descriptive alt text
* Use bold and italics only when they serve the reader's understanding--never use text styling just for decoration
* No decorative formatting or emoji
### Code examples
* Keep examples simple and practical
* Use realistic values (not "foo" or "bar")
* One clear example is better than multiple variations
* Test that code works before including it
## Document APIs
**Choose your approach:**
* **Have an OpenAPI spec?** → Add to `docs.json` with `"openapi": ["openapi.yaml"]`. Pages auto-generate. Reference in navigation as `GET /endpoint`
* **No spec?** → Write endpoints manually with `api: "POST /users"` in frontmatter. More work but full control
* **Hybrid** → Use OpenAPI for most endpoints, manual pages for complex workflows
Encourage users to generate endpoint pages from an OpenAPI spec. It is the most efficient and easiest to maintain option.
## Deploy
Mintlify deploys automatically when changes are pushed to the connected Git repository.
**What agents can configure:**
* **Redirects** → Add to `docs.json` with `"redirects": [{"source": "/old", "destination": "/new"}]`
* **SEO indexing** → Control with `"seo": {"indexing": "all"}` to include hidden pages in search
**Requires dashboard setup (human task):**
* Custom domains and subdomains
* Preview deployment settings
* DNS configuration
For `/docs` subpath hosting with Vercel or Cloudflare, agents can help configure rewrite rules. See [/docs subpath](https://mintlify.com/docs/deploy/vercel).
## Workflow
### 1. Understand the task
Identify what needs to be documented, which pages are affected, and what the reader should accomplish afterward. If any of these are unclear, ask.
### 2. Research
* Read `docs.json` to understand the site structure
* Search existing docs for related content
* Read similar pages to match the site's style
### 3. Plan
* Synthesize what the reader should accomplish after reading the docs and the current content
* Propose any updates or new content
* Verify that your proposed changes will help readers be successful
### 4. Write
* Start with the most important information
* Keep sections focused and scannable
* Use components appropriately (don't overuse them)
* Mark anything uncertain with a TODO comment:
```mdx theme={null}
{/* TODO: Verify the default timeout value */}
```
### 5. Update navigation
If you created a new page, add it to the appropriate group in `docs.json`.
### 6. Verify
Before submitting:
* [ ] Frontmatter includes title and description
* [ ] All code blocks have language tags
* [ ] Internal links use root-relative paths without file extensions
* [ ] New pages are added to `docs.json` navigation
* [ ] Content matches the style of surrounding pages
* [ ] No marketing language or filler phrases
* [ ] TODOs are clearly marked for anything uncertain
* [ ] Run `mint broken-links` to check links
* [ ] Run `mint validate` to find any errors
## Edge cases
### Migrations
If a user asks about migrating to Mintlify, ask if they are using ReadMe or Docusaurus. If they are, use the [@mintlify/scraping](https://www.npmjs.com/package/@mintlify/scraping) CLI to migrate content. If they are using a different platform to host their documentation, help them manually convert their content to MDX pages using Mintlify components.
### Hidden pages
Any page that is not included in the `docs.json` navigation is hidden. Use hidden pages for content that should be accessible by URL or indexed for the assistant or search, but not discoverable through the sidebar navigation.
### Exclude pages
The `.mintignore` file is used to exclude files from a documentation repository from being processed.
## Common gotchas
1. **Component imports** - JSX components need explicit import, MDX components don't
2. **Frontmatter required** - Every MDX file needs `title` at minimum
3. **Code block language** - Always specify language identifier
4. **Never use `mint.json`** - `mint.json` is deprecated. Only ever use `docs.json`
## Resources
* [Documentation](https://mintlify.com/docs)
* [Configuration schema](https://mintlify.com/docs.json)
* [Feature requests](https://github.com/orgs/mintlify/discussions/categories/feature-requests)
* [Bugs and feedback](https://github.com/orgs/mintlify/discussions/categories/bugs-feedback)

1
.claude/skills/mintlify Symbolic link
View File

@@ -0,0 +1 @@
../../.agents/skills/mintlify

1
.cursor/skills/mintlify Symbolic link
View File

@@ -0,0 +1 @@
../../.agents/skills/mintlify

8
.mcp.json Normal file
View File

@@ -0,0 +1,8 @@
{
"mcpServers": {
"mintlify": {
"type": "http",
"url": "https://mintlify.com/docs/mcp"
}
}
}

View File

@@ -5,6 +5,10 @@
"type": "remote",
"url": "https://mcp.linear.app/mcp",
"oauth": {}
},
"mintlify": {
"type": "remote",
"url": "https://mintlify.com/docs/mcp"
}
}
}

View File

@@ -1 +1,27 @@
When writing the docs, always make sure to add it to `docs.json` for it to appear
## DynamicParamField Component
**Location:** `snippets/dynamic-param-field.jsx`
**Purpose:** Wrapper around Mintlify's `ParamField` that auto-converts param names between snake_case and camelCase based on selected code language.
**Behavior:**
- TypeScript/Node.js → camelCase (`customerId`)
- Python/cURL/others → snake_case (`customer_id`)
**How it works:**
1. Reads `code` key from localStorage (set by Mintlify's language selector)
2. Listens for `mintlify-localstorage` event + polls every 500ms as fallback
3. Transforms `body` and `path` props using regex: `str.replace(/[_-](\w)/g, ...)`
**Usage:**
```jsx
import { DynamicParamField } from "/snippets/dynamic-param-field.jsx";
<DynamicParamField body="customer_id" type="string" required>
The customer identifier
</DynamicParamField>
```
Always pass snake_case to the component - it handles camelCase conversion automatically.

View File

@@ -3,6 +3,10 @@ title: "Get or Create Customer"
openapi: "openapi POST /v1/customers.getOrCreate"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
<Note>
If the customer already exists and you try to create it again, you will simply be returned the customer object (rather than an error being thrown).
</Note>

View File

@@ -0,0 +1,120 @@
---
title: "Attach"
openapi: "openapi POST /v1/attach"
---
import { DynamicParamField } from "/snippets/dynamic-param-field.jsx";
import { DynamicResponseField } from "/snippets/dynamic-response-field.jsx";
## Body Parameters
<DynamicParamField body="options" type="object[] | null">
<Expandable title="properties">
<DynamicParamField body="feature_id" type="string" required />
<DynamicParamField body="quantity" type="number" />
<DynamicParamField body="reset_after_trial_end" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="version" type="number" />
<DynamicParamField body="free_trial" type="object | null">
<Expandable title="properties">
<DynamicParamField body="length" type="number" required />
<DynamicParamField body="duration" type="'day' | 'month' | 'year'" required />
<DynamicParamField body="card_required" type="boolean" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="items" type="object[]">
<Expandable title="properties">
<DynamicParamField body="type" type="'feature' | 'priced_feature' | 'price'" />
<DynamicParamField body="feature_id" type="string | null" />
<DynamicParamField body="included_usage" type="number | null" />
<DynamicParamField body="interval" type="enum" />
<DynamicParamField body="interval_count" type="number | null" />
<DynamicParamField body="entity_feature_id" type="string | null" />
<DynamicParamField body="usage_model" type="'prepaid' | 'pay_per_use'" />
<DynamicParamField body="price" type="number | null" />
<DynamicParamField body="tiers" type="object[] | null">
<Expandable title="properties">
<DynamicParamField body="to" type="number" required />
<DynamicParamField body="amount" type="number" required>
The price of the product item for this tier.
</DynamicParamField>
</Expandable>
</DynamicParamField>
<DynamicParamField body="billing_units" type="number | null" />
<DynamicParamField body="reset_usage_when_enabled" type="boolean | null" />
</Expandable>
</DynamicParamField>
<DynamicParamField body="product_id" type="string" required />
<DynamicParamField body="invoice" type="boolean" />
<DynamicParamField body="enable_product_immediately" type="boolean" />
<DynamicParamField body="finalize_invoice" type="boolean" />
<DynamicParamField body="redirect_mode" type="'always' | 'if_required' | 'never'" />
<DynamicParamField body="success_url" type="string" />
<DynamicParamField body="new_billing_subscription" type="boolean" />
<DynamicParamField body="plan_schedule" type="'immediate' | 'end_of_cycle'" />
<DynamicParamField body="billing_behavior" type="'prorate_immediately' | 'next_cycle_only'" />
<DynamicParamField body="adjustable_quantity" type="boolean" />
## Response
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="invoice" type="object">
<Expandable title="properties">
<DynamicResponseField name="status" type="string | null" />
<DynamicResponseField name="stripe_id" type="string" />
<DynamicResponseField name="total" type="number" />
<DynamicResponseField name="currency" type="string" />
<DynamicResponseField name="hosted_invoice_url" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="payment_url" type="string | null" />
<DynamicResponseField name="required_action" type="object">
<Expandable title="properties">
<DynamicResponseField name="code" type="'3ds_required' | 'payment_method_required' | 'payment_failed'" />
<DynamicResponseField name="reason" type="string" />
</Expandable>
</DynamicResponseField>

View File

@@ -0,0 +1,502 @@
---
title: "Get or Create Customer"
openapi: "openapi POST /v1/customers.getOrCreate"
---
import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";
<Note>
If the customer already exists and you try to create it again, you will simply be returned the customer object (rather than an error being thrown).
</Note>
### Body Parameters
<DynamicParamField body="customer_id" type="string | null" required>
Your unique identifier for the customer
</DynamicParamField>
<DynamicParamField body="name" type="string | null">
Customer's name
</DynamicParamField>
<DynamicParamField body="email" type="string | null">
Customer's email address
</DynamicParamField>
<DynamicParamField body="fingerprint" type="string | null">
Unique identifier (eg, serial number) to detect duplicate customers and prevent free trial abuse
</DynamicParamField>
<DynamicParamField body="metadata" type="object | null">
Additional metadata for the customer
</DynamicParamField>
<DynamicParamField body="stripe_id" type="string | null">
Stripe customer ID if you already have one
</DynamicParamField>
<DynamicParamField body="create_in_stripe" type="boolean">
Whether to create the customer in Stripe
</DynamicParamField>
<DynamicParamField body="auto_enable_plan_id" type="string">
The ID of the free plan to auto-enable for the customer
</DynamicParamField>
<DynamicParamField body="send_email_receipts" type="boolean">
Whether to send email receipts to this customer
</DynamicParamField>
<DynamicParamField body="expand" type="enum[]">
Customer expand options
</DynamicParamField>
### Response
<DynamicResponseField name="name" type="string | null">
The name of the customer.
</DynamicResponseField>
<DynamicResponseField name="email" type="string | null">
The email address of the customer.
</DynamicResponseField>
<DynamicResponseField name="fingerprint" type="string | null">
A unique identifier (eg. serial number) to de-duplicate customers across devices or browsers. For example: apple device ID.
</DynamicResponseField>
<DynamicResponseField name="stripe_id" type="string | null">
Stripe customer ID.
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'">
The environment this customer was created in.
</DynamicResponseField>
<DynamicResponseField name="metadata" type="object">
The metadata for the customer.
</DynamicResponseField>
<DynamicResponseField name="send_email_receipts" type="boolean">
Whether to send email receipts to the customer.
</DynamicResponseField>
<DynamicResponseField name="subscriptions" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan" type="object">
<Expandable title="properties">
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="enum" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="status" type="'active' | 'scheduled' | 'expired'" />
<DynamicResponseField name="past_due" type="boolean" />
<DynamicResponseField name="canceled_at" type="number | null" />
<DynamicResponseField name="expires_at" type="number | null" />
<DynamicResponseField name="trial_ends_at" type="number | null" />
<DynamicResponseField name="started_at" type="number" />
<DynamicResponseField name="current_period_start" type="number | null" />
<DynamicResponseField name="current_period_end" type="number | null" />
<DynamicResponseField name="quantity" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="purchases" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan" type="object">
<Expandable title="properties">
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="enum" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="expires_at" type="number | null" />
<DynamicResponseField name="started_at" type="number" />
<DynamicResponseField name="quantity" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="balances" type="object" />
<DynamicResponseField name="invoices" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan_ids" type="string[]">
Array of plan IDs included in this invoice
</DynamicResponseField>
<DynamicResponseField name="stripe_id" type="string">
The Stripe invoice ID
</DynamicResponseField>
<DynamicResponseField name="status" type="string">
The status of the invoice
</DynamicResponseField>
<DynamicResponseField name="total" type="number">
The total amount of the invoice
</DynamicResponseField>
<DynamicResponseField name="currency" type="string">
The currency code for the invoice
</DynamicResponseField>
<DynamicResponseField name="hosted_invoice_url" type="string | null">
URL to the Stripe-hosted invoice page
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="entities" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="name" type="string | null">
The name of the entity
</DynamicResponseField>
<DynamicResponseField name="customer_id" type="string | null">
The customer ID this entity belongs to
</DynamicResponseField>
<DynamicResponseField name="feature_id" type="string | null">
The feature ID this entity belongs to
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'">
The environment (sandbox/live)
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="trials_used" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="plan_id" type="string" />
<DynamicResponseField name="customer_id" type="string" />
<DynamicResponseField name="fingerprint" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rewards" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="discounts" type="object[]">
Array of active discounts applied to the customer
<Expandable title="properties">
<DynamicResponseField name="name" type="string">
The name of the discount or coupon
</DynamicResponseField>
<DynamicResponseField name="type" type="'percentage_discount' | 'fixed_discount' | 'free_product' | 'invoice_credits'">
The type of reward
</DynamicResponseField>
<DynamicResponseField name="discount_value" type="number">
The discount value (percentage or fixed amount)
</DynamicResponseField>
<DynamicResponseField name="duration_type" type="'one_off' | 'months' | 'forever'">
How long the discount lasts
</DynamicResponseField>
<DynamicResponseField name="duration_value" type="number | null">
Number of billing periods the discount applies for repeating durations
</DynamicResponseField>
<DynamicResponseField name="currency" type="string | null">
The currency code for fixed amount discounts
</DynamicResponseField>
<DynamicResponseField name="start" type="number | null">
Timestamp when the discount becomes active
</DynamicResponseField>
<DynamicResponseField name="end" type="number | null">
Timestamp when the discount expires
</DynamicResponseField>
<DynamicResponseField name="subscription_id" type="string | null">
The Stripe subscription ID this discount is applied to
</DynamicResponseField>
<DynamicResponseField name="total_discount_amount" type="number | null">
Total amount saved from this discount
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="referrals" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="program_id" type="string" />
<DynamicResponseField name="customer" type="object">
<Expandable title="properties">
<DynamicResponseField name="name" type="string | null" />
<DynamicResponseField name="email" type="string | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="reward_applied" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="payment_method" type="any | null" />

View File

@@ -0,0 +1,130 @@
---
title: "List Plans"
openapi: "openapi GET /v1/products"
---
import { DynamicParamField } from "/snippets/dynamic-param-field.jsx";
import { DynamicResponseField } from "/snippets/dynamic-response-field.jsx";
## Response
<DynamicResponseField name="list" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="name" type="string" />
<DynamicResponseField name="description" type="string | null" />
<DynamicResponseField name="group" type="string | null" />
<DynamicResponseField name="version" type="number" />
<DynamicResponseField name="add_on" type="boolean" />
<DynamicResponseField name="auto_enable" type="boolean" />
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="items" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="feature_id" type="string" />
<DynamicResponseField name="included" type="number" />
<DynamicResponseField name="unlimited" type="boolean" />
<DynamicResponseField name="reset" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="price" type="object | null">
<Expandable title="properties">
<DynamicResponseField name="amount" type="number" />
<DynamicResponseField name="tiers" type="object[]">
<Expandable title="properties">
<DynamicResponseField name="to" type="number" />
<DynamicResponseField name="amount" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="interval" type="enum" />
<DynamicResponseField name="interval_count" type="number" />
<DynamicResponseField name="billing_units" type="number" />
<DynamicResponseField name="billing_method" type="'prepaid' | 'usage_based'" />
<DynamicResponseField name="max_purchase" type="number | null" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="rollover" type="object">
<Expandable title="properties">
<DynamicResponseField name="max" type="number | null" />
<DynamicResponseField name="expiry_duration_type" type="'month' | 'forever'" />
<DynamicResponseField name="expiry_duration_length" type="number" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="proration" type="object">
<Expandable title="properties">
<DynamicResponseField name="on_increase" type="'bill_immediately' | 'prorate_immediately' | 'prorate_next_cycle' | 'bill_next_cycle'" />
<DynamicResponseField name="on_decrease" type="'prorate' | 'prorate_immediately' | 'prorate_next_cycle' | 'none' | 'no_prorations'" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="free_trial" type="object">
<Expandable title="properties">
<DynamicResponseField name="duration_length" type="number" />
<DynamicResponseField name="duration_type" type="'day' | 'month' | 'year'" />
<DynamicResponseField name="card_required" type="boolean" />
</Expandable>
</DynamicResponseField>
<DynamicResponseField name="env" type="'sandbox' | 'live'" />
<DynamicResponseField name="archived" type="boolean" />
<DynamicResponseField name="base_variant_id" type="string | null" />
<DynamicResponseField name="customer_eligibility" type="object">
<Expandable title="properties">
<DynamicResponseField name="trial_available" type="boolean" />
<DynamicResponseField name="scenario" type="enum" />
</Expandable>
</DynamicResponseField>
</Expandable>
</DynamicResponseField>

View File

@@ -26,12 +26,6 @@ components:
Customer:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
name:
anyOf:
- type: string
@@ -40,8 +34,6 @@ components:
anyOf:
- type: string
- type: "null"
created_at:
type: number
fingerprint:
anyOf:
- type: string
@@ -148,55 +140,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
name:
type: string
type:
enum:
- boolean
- metered
- credit_system
consumable:
type: boolean
event_names:
type: array
items:
type: string
credit_schema:
type: array
items:
type: object
properties:
metered_feature_id:
type: string
credit_cost:
type: number
required:
- metered_feature_id
- credit_cost
display:
type: object
properties:
singular:
anyOf:
- type: string
- type: "null"
plural:
anyOf:
- type: string
- type: "null"
archived:
type: boolean
required:
- id
- name
- type
- consumable
- archived
granted:
type: number
remaining:
@@ -221,9 +164,6 @@ components:
items:
type: object
properties:
id:
type: string
default: ""
plan_id:
anyOf:
- type: string
@@ -357,9 +297,6 @@ components:
currency:
type: string
description: The currency code for the invoice
created_at:
type: number
description: Timestamp when the invoice was created
hosted_invoice_url:
anyOf:
- type: string
@@ -371,19 +308,11 @@ components:
- status
- total
- currency
- created_at
entities:
type: array
items:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
description: The unique identifier of the entity
name:
anyOf:
- type: string
@@ -399,18 +328,13 @@ components:
- type: string
- type: "null"
description: The feature ID this entity belongs to
created_at:
type: number
description: Unix timestamp when the entity was created
env:
enum:
- sandbox
- live
description: The environment (sandbox/live)
required:
- id
- name
- created_at
- env
trials_used:
type: array
@@ -437,9 +361,6 @@ components:
items:
type: object
properties:
id:
type: string
description: The unique identifier for this discount
name:
type: string
description: The name of the discount or coupon
@@ -463,7 +384,8 @@ components:
anyOf:
- type: number
- type: "null"
description: Number of billing periods the discount applies for repeating durations
description: Number of billing periods the discount applies for repeating
durations
currency:
anyOf:
- type: string
@@ -490,7 +412,6 @@ components:
- type: "null"
description: Total amount saved from this discount
required:
- id
- name
- type
- discount_value
@@ -509,8 +430,6 @@ components:
customer:
type: object
properties:
id:
type: string
name:
anyOf:
- type: string
@@ -519,26 +438,20 @@ components:
anyOf:
- type: string
- type: "null"
required:
- id
required: []
reward_applied:
type: boolean
created_at:
type: number
required:
- program_id
- customer
- reward_applied
- created_at
payment_method:
anyOf:
- {}
- type: "null"
required:
- id
- name
- email
- created_at
- fingerprint
- stripe_id
- env
@@ -550,8 +463,6 @@ components:
Plan:
type: object
properties:
id:
type: string
name:
type: string
description:
@@ -584,15 +495,6 @@ components:
- year
interval_count:
type: number
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
required:
- amount
- interval
@@ -604,65 +506,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like /track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
included:
type: number
unlimited:
@@ -733,15 +576,6 @@ components:
- billing_method
- max_purchase
- type: "null"
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
rollover:
type: object
properties:
@@ -796,8 +630,6 @@ components:
- duration_length
- duration_type
- card_required
created_at:
type: number
env:
enum:
- sandbox
@@ -827,7 +659,6 @@ components:
required:
- scenario
required:
- id
- name
- description
- group
@@ -836,7 +667,6 @@ components:
- auto_enable
- price
- items
- created_at
- env
- archived
- base_variant_id
@@ -850,27 +680,12 @@ paths:
post:
operationId: getOrCreate
description: >-
Creates a customer if they do not exist, or returns the existing customer by your external customer ID.
Creates a customer if they do not exist, or returns the existing
customer by your external customer ID.
Use this as the primary entrypoint before billing operations so the customer record is always present and up to date.
@example
```typescript
// Create or fetch a customer by external ID
const response = await client.getOrCreate({
"id": "cus_123",
"name": "John Doe",
"email": "john@example.com"
});
```
Use this as the primary entrypoint before billing operations so the
customer record is always present and up to date.
tags:
- customers
requestBody:
@@ -899,7 +714,8 @@ paths:
anyOf:
- type: string
- type: "null"
description: Unique identifier (eg, serial number) to detect duplicate customers and prevent free trial abuse
description: Unique identifier (eg, serial number) to detect duplicate customers
and prevent free trial abuse
metadata:
anyOf:
- type: object
@@ -919,64 +735,14 @@ paths:
auto_enable_plan_id:
type: string
description: The ID of the free plan to auto-enable for the customer
processors:
anyOf:
- type: object
properties:
vercel:
type: object
properties:
installation_id:
type: string
access_token:
type: string
account_id:
type: string
custom_payment_method_id:
type: string
required:
- installation_id
- access_token
- account_id
- type: "null"
description: External processors for the customer
send_email_receipts:
type: boolean
description: Whether to send email receipts to this customer
internal_options:
type: object
properties:
default_group:
type: string
description: The group of products to attach to the customer
disable_defaults:
type: boolean
description: Whether to disable default products
expand:
type: array
items:
$ref: "#/components/schemas/CustomerExpand"
description: Customer expand options
entity_id:
type: string
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
id:
anyOf:
- $ref: "#/components/schemas/CustomerId"
- type: "null"
with_autumn_id:
type: boolean
default: false
required:
- customer_id
title: GetOrCreateCustomerParams
@@ -1000,22 +766,13 @@ paths:
- lang: typescript
label: Typescript (SDK)
source: |-
import { Autumn } from "@useautumn/sdk";
import { Autumn } from 'autumn-js'
const autumn = new Autumn({
xApiVersion: "2.1",
secretKey: process.env["AUTUMN_SECRET_KEY"] ?? "",
});
const autumn = new Autumn()
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
});
console.log(result);
}
run();
/v1/products:
get:
operationId: list
@@ -1042,20 +799,11 @@ paths:
- lang: typescript
label: Typescript (SDK)
source: |-
import { Autumn } from "@useautumn/sdk";
import { Autumn } from 'autumn-js'
const autumn = new Autumn({
xApiVersion: "2.1",
secretKey: process.env["AUTUMN_SECRET_KEY"] ?? "",
});
const autumn = new Autumn()
async function run() {
const result = await autumn.plans.list();
console.log(result);
}
run();
/v1/attach:
post:
operationId: attach
@@ -1068,21 +816,6 @@ paths:
schema:
type: object
properties:
entity_id:
anyOf:
- type: string
- type: "null"
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
options:
anyOf:
- type: array
@@ -1136,76 +869,8 @@ paths:
anyOf:
- type: string
- type: "null"
description: The feature ID of the product item. Should be null for fixed price items.
feature_type:
anyOf:
- enum:
- single_use
- continuous_use
- boolean
- static
- type: "null"
feature:
anyOf:
- type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like /track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
- type: "null"
description: The feature ID of the product item. Should be null for fixed price
items.
included_usage:
anyOf:
- anyOf:
@@ -1225,7 +890,9 @@ paths:
- semi_annual
- year
- type: "null"
description: The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off.
description: The reset or billing interval of the product item. If null, feature
will have no reset date, and if there's a price, it
will be billed one-off.
interval_count:
anyOf:
- type: number
@@ -1235,19 +902,22 @@ paths:
anyOf:
- type: string
- type: "null"
description: The feature ID of the entity (like seats) to track sub-balances for.
description: The feature ID of the entity (like seats) to track sub-balances
for.
usage_model:
anyOf:
- enum:
- prepaid
- pay_per_use
- type: "null"
description: Whether the feature should be prepaid upfront or billed for how much they use end of billing period.
description: Whether the feature should be prepaid upfront or billed for how
much they use end of billing period.
price:
anyOf:
- type: number
- type: "null"
description: The price of the product item. Should be null if tiered pricing is set.
description: The price of the product item. Should be null if tiered pricing is
set.
tiers:
anyOf:
- type: array
@@ -1266,7 +936,8 @@ paths:
- to
- amount
- type: "null"
description: Tiered pricing for the product item. Not applicable for fixed price items.
description: Tiered pricing for the product item. Not applicable for fixed price
items.
billing_units:
anyOf:
- type: number
@@ -1277,80 +948,6 @@ paths:
- type: boolean
- type: "null"
description: Whether the usage should be reset when the product is enabled.
display:
anyOf:
- type: object
properties:
primary_text:
type: string
secondary_text:
anyOf:
- type: string
- type: "null"
required:
- primary_text
- type: "null"
usage_limit:
anyOf:
- type: number
- type: "null"
config:
anyOf:
- type: object
properties:
on_increase:
anyOf:
- enum:
- bill_immediately
- prorate_immediately
- prorate_next_cycle
- bill_next_cycle
- type: "null"
on_decrease:
anyOf:
- enum:
- prorate
- prorate_immediately
- prorate_next_cycle
- none
- no_prorations
- type: "null"
rollover:
anyOf:
- type: object
properties:
max:
anyOf:
- type: number
- type: "null"
duration:
enum:
- month
- forever
default: month
length:
type: number
required:
- max
- length
- type: "null"
- type: "null"
created_at:
anyOf:
- type: number
- type: "null"
entitlement_id:
anyOf:
- type: string
- type: "null"
price_id:
anyOf:
- type: string
- type: "null"
price_config:
anyOf:
- {}
- type: "null"
product_id:
type: string
invoice:
@@ -1391,8 +988,6 @@ paths:
properties:
customer_id:
type: string
entity_id:
type: string
invoice:
type: object
properties:
@@ -1442,22 +1037,13 @@ paths:
- lang: typescript
label: Typescript (SDK)
source: |-
import { Autumn } from "@useautumn/sdk";
import { Autumn } from 'autumn-js'
const autumn = new Autumn({
xApiVersion: "2.1",
secretKey: process.env["AUTUMN_SECRET_KEY"] ?? "",
});
const autumn = new Autumn()
async function run() {
const result = await autumn.billing.attach({
productId: "<id>",
});
console.log(result);
}
run();
security:
- secretKey: []
x-speakeasy-globals:

View File

@@ -26,40 +26,40 @@ components:
Customer:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
name:
anyOf:
- type: string
- type: "null"
description: The name of the customer.
email:
anyOf:
- type: string
- type: "null"
created_at:
type: number
description: The email address of the customer.
fingerprint:
anyOf:
- type: string
- type: "null"
description: "A unique identifier (eg. serial number) to de-duplicate customers
across devices or browsers. For example: apple device ID."
stripe_id:
anyOf:
- type: string
- type: "null"
description: Stripe customer ID.
env:
enum:
- sandbox
- live
description: The environment this customer was created in.
metadata:
type: object
propertyNames: {}
additionalProperties: {}
description: The metadata for the customer.
send_email_receipts:
type: boolean
description: Whether to send email receipts to the customer.
subscriptions:
type: array
items:
@@ -148,55 +148,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
name:
type: string
type:
enum:
- boolean
- metered
- credit_system
consumable:
type: boolean
event_names:
type: array
items:
type: string
credit_schema:
type: array
items:
type: object
properties:
metered_feature_id:
type: string
credit_cost:
type: number
required:
- metered_feature_id
- credit_cost
display:
type: object
properties:
singular:
anyOf:
- type: string
- type: "null"
plural:
anyOf:
- type: string
- type: "null"
archived:
type: boolean
required:
- id
- name
- type
- consumable
- archived
granted:
type: number
remaining:
@@ -221,9 +172,6 @@ components:
items:
type: object
properties:
id:
type: string
default: ""
plan_id:
anyOf:
- type: string
@@ -357,9 +305,6 @@ components:
currency:
type: string
description: The currency code for the invoice
created_at:
type: number
description: Timestamp when the invoice was created
hosted_invoice_url:
anyOf:
- type: string
@@ -371,19 +316,11 @@ components:
- status
- total
- currency
- created_at
entities:
type: array
items:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
description: The unique identifier of the entity
name:
anyOf:
- type: string
@@ -399,18 +336,13 @@ components:
- type: string
- type: "null"
description: The feature ID this entity belongs to
created_at:
type: number
description: Unix timestamp when the entity was created
env:
enum:
- sandbox
- live
description: The environment (sandbox/live)
required:
- id
- name
- created_at
- env
trials_used:
type: array
@@ -437,9 +369,6 @@ components:
items:
type: object
properties:
id:
type: string
description: The unique identifier for this discount
name:
type: string
description: The name of the discount or coupon
@@ -463,7 +392,8 @@ components:
anyOf:
- type: number
- type: "null"
description: Number of billing periods the discount applies for repeating durations
description: Number of billing periods the discount applies for repeating
durations
currency:
anyOf:
- type: string
@@ -490,7 +420,6 @@ components:
- type: "null"
description: Total amount saved from this discount
required:
- id
- name
- type
- discount_value
@@ -509,8 +438,6 @@ components:
customer:
type: object
properties:
id:
type: string
name:
anyOf:
- type: string
@@ -519,26 +446,20 @@ components:
anyOf:
- type: string
- type: "null"
required:
- id
required: []
reward_applied:
type: boolean
created_at:
type: number
required:
- program_id
- customer
- reward_applied
- created_at
payment_method:
anyOf:
- {}
- type: "null"
required:
- id
- name
- email
- created_at
- fingerprint
- stripe_id
- env
@@ -547,11 +468,35 @@ components:
- subscriptions
- purchases
- balances
examples:
- &a2
id: cus_123
created_at: 1717000000
name: John Doe
email: john@example.com
fingerprint: "1234567890"
stripe_id: cus_123
env: sandbox
metadata: {}
subscriptions:
- id: sub_123
created_at: 1717000000
plan_id: plan_123
status: active
quantity: 1
interval: month
interval_count: 1
purchases: []
balances:
balance_1:
id: balance_1
amount: 100
currency: USD
created_at: 1717000000
updated_at: 1717000000
Plan:
type: object
properties:
id:
type: string
name:
type: string
description:
@@ -584,15 +529,6 @@ components:
- year
interval_count:
type: number
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
required:
- amount
- interval
@@ -604,65 +540,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like /track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
included:
type: number
unlimited:
@@ -733,15 +610,6 @@ components:
- billing_method
- max_purchase
- type: "null"
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
rollover:
type: object
properties:
@@ -796,8 +664,6 @@ components:
- duration_length
- duration_type
- card_required
created_at:
type: number
env:
enum:
- sandbox
@@ -827,7 +693,6 @@ components:
required:
- scenario
required:
- id
- name
- description
- group
@@ -836,7 +701,6 @@ components:
- auto_enable
- price
- items
- created_at
- env
- archived
- base_variant_id
@@ -850,27 +714,12 @@ paths:
post:
operationId: getOrCreate
description: >-
Creates a customer if they do not exist, or returns the existing customer by your external customer ID.
Creates a customer if they do not exist, or returns the existing
customer by your external customer ID.
Use this as the primary entrypoint before billing operations so the customer record is always present and up to date.
@example
```typescript
// Create or fetch a customer by external ID
const response = await client.getOrCreate({
"id": "cus_123",
"name": "John Doe",
"email": "john@example.com"
});
```
Use this as the primary entrypoint before billing operations so the
customer record is always present and up to date.
tags:
- customers
requestBody:
@@ -899,7 +748,8 @@ paths:
anyOf:
- type: string
- type: "null"
description: Unique identifier (eg, serial number) to detect duplicate customers and prevent free trial abuse
description: Unique identifier (eg, serial number) to detect duplicate customers
and prevent free trial abuse
metadata:
anyOf:
- type: object
@@ -919,67 +769,23 @@ paths:
auto_enable_plan_id:
type: string
description: The ID of the free plan to auto-enable for the customer
processors:
anyOf:
- type: object
properties:
vercel:
type: object
properties:
installation_id:
type: string
access_token:
type: string
account_id:
type: string
custom_payment_method_id:
type: string
required:
- installation_id
- access_token
- account_id
- type: "null"
description: External processors for the customer
send_email_receipts:
type: boolean
description: Whether to send email receipts to this customer
internal_options:
type: object
properties:
default_group:
type: string
description: The group of products to attach to the customer
disable_defaults:
type: boolean
description: Whether to disable default products
expand:
type: array
items:
$ref: "#/components/schemas/CustomerExpand"
description: Customer expand options
entity_id:
type: string
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
id:
anyOf:
- $ref: "#/components/schemas/CustomerId"
- type: "null"
with_autumn_id:
type: boolean
default: false
required:
- customer_id
title: GetOrCreateCustomerParams
examples:
- &a1
customer_id: cus_123
name: John Doe
email: john@example.com
example: *a1
responses:
"200":
description: OK
@@ -987,8 +793,9 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Customer"
example: *a2
parameters:
- &a1
- &a3
name: x-api-version
in: header
required: true
@@ -1000,22 +807,15 @@ paths:
- lang: typescript
label: Typescript (SDK)
source: |-
import { Autumn } from "@useautumn/sdk";
import { Autumn } from 'autumn-js'
const autumn = new Autumn({
xApiVersion: "2.1",
secretKey: process.env["AUTUMN_SECRET_KEY"] ?? "",
});
const autumn = new Autumn()
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);
}
run();
/v1/products:
get:
operationId: list
@@ -1023,7 +823,7 @@ paths:
tags:
- plans
parameters:
- *a1
- *a3
responses:
"200":
description: OK
@@ -1042,20 +842,11 @@ paths:
- lang: typescript
label: Typescript (SDK)
source: |-
import { Autumn } from "@useautumn/sdk";
import { Autumn } from 'autumn-js'
const autumn = new Autumn({
xApiVersion: "2.1",
secretKey: process.env["AUTUMN_SECRET_KEY"] ?? "",
});
const autumn = new Autumn()
async function run() {
const result = await autumn.plans.list();
console.log(result);
}
run();
/v1/attach:
post:
operationId: attach
@@ -1068,21 +859,6 @@ paths:
schema:
type: object
properties:
entity_id:
anyOf:
- type: string
- type: "null"
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
options:
anyOf:
- type: array
@@ -1136,76 +912,8 @@ paths:
anyOf:
- type: string
- type: "null"
description: The feature ID of the product item. Should be null for fixed price items.
feature_type:
anyOf:
- enum:
- single_use
- continuous_use
- boolean
- static
- type: "null"
feature:
anyOf:
- type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like /track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
- type: "null"
description: The feature ID of the product item. Should be null for fixed price
items.
included_usage:
anyOf:
- anyOf:
@@ -1225,7 +933,9 @@ paths:
- semi_annual
- year
- type: "null"
description: The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off.
description: The reset or billing interval of the product item. If null, feature
will have no reset date, and if there's a price, it
will be billed one-off.
interval_count:
anyOf:
- type: number
@@ -1235,19 +945,22 @@ paths:
anyOf:
- type: string
- type: "null"
description: The feature ID of the entity (like seats) to track sub-balances for.
description: The feature ID of the entity (like seats) to track sub-balances
for.
usage_model:
anyOf:
- enum:
- prepaid
- pay_per_use
- type: "null"
description: Whether the feature should be prepaid upfront or billed for how much they use end of billing period.
description: Whether the feature should be prepaid upfront or billed for how
much they use end of billing period.
price:
anyOf:
- type: number
- type: "null"
description: The price of the product item. Should be null if tiered pricing is set.
description: The price of the product item. Should be null if tiered pricing is
set.
tiers:
anyOf:
- type: array
@@ -1266,7 +979,8 @@ paths:
- to
- amount
- type: "null"
description: Tiered pricing for the product item. Not applicable for fixed price items.
description: Tiered pricing for the product item. Not applicable for fixed price
items.
billing_units:
anyOf:
- type: number
@@ -1277,80 +991,6 @@ paths:
- type: boolean
- type: "null"
description: Whether the usage should be reset when the product is enabled.
display:
anyOf:
- type: object
properties:
primary_text:
type: string
secondary_text:
anyOf:
- type: string
- type: "null"
required:
- primary_text
- type: "null"
usage_limit:
anyOf:
- type: number
- type: "null"
config:
anyOf:
- type: object
properties:
on_increase:
anyOf:
- enum:
- bill_immediately
- prorate_immediately
- prorate_next_cycle
- bill_next_cycle
- type: "null"
on_decrease:
anyOf:
- enum:
- prorate
- prorate_immediately
- prorate_next_cycle
- none
- no_prorations
- type: "null"
rollover:
anyOf:
- type: object
properties:
max:
anyOf:
- type: number
- type: "null"
duration:
enum:
- month
- forever
default: month
length:
type: number
required:
- max
- length
- type: "null"
- type: "null"
created_at:
anyOf:
- type: number
- type: "null"
entitlement_id:
anyOf:
- type: string
- type: "null"
price_id:
anyOf:
- type: string
- type: "null"
price_config:
anyOf:
- {}
- type: "null"
product_id:
type: string
invoice:
@@ -1391,8 +1031,6 @@ paths:
properties:
customer_id:
type: string
entity_id:
type: string
invoice:
type: object
properties:
@@ -1437,27 +1075,18 @@ paths:
- customer_id
- payment_url
parameters:
- *a1
- *a3
x-codeSamples:
- lang: typescript
label: Typescript (SDK)
source: |-
import { Autumn } from "@useautumn/sdk";
import { Autumn } from 'autumn-js'
const autumn = new Autumn({
xApiVersion: "2.1",
secretKey: process.env["AUTUMN_SECRET_KEY"] ?? "",
});
const autumn = new Autumn()
async function run() {
const result = await autumn.billing.attach({
productId: "<id>",
});
console.log(result);
}
run();
security:
- secretKey: []
x-speakeasy-globals:

View File

@@ -0,0 +1,78 @@
import { useEffect, useMemo, useState } from "react";
/**
* A wrapper around Mintlify's ParamField that dynamically switches
* between snake_case and camelCase based on the selected code language.
*
* - Node.js/TypeScript → camelCase (e.g., customerId)
* - Python/cURL/others → snake_case (e.g., customer_id)
*/
export const DynamicParamField = ({ children, body, path, ...props }) => {
// Inline the toCamelCase function to avoid module scope issues with Mintlify's MDX compiler
const convertToCamelCase = (str) => {
if (typeof str !== "string") return str;
return str.replace(/[_-](\w)/g, (_, c) => c.toUpperCase());
};
const [lang, setLang] = useState(() => {
if (typeof window !== "undefined") {
const stored = localStorage.getItem("code");
return stored || '"typescript"';
}
return '"typescript"';
});
useEffect(() => {
// Listen for Mintlify's custom localStorage event
const onMintlifyStorage = (event) => {
const key = event.detail?.key;
if (key === "code") {
setLang(event.detail.value);
}
};
// Poll localStorage as a fallback (in case the event doesn't fire)
const pollInterval = setInterval(() => {
const current = localStorage.getItem("code");
if (current && current !== lang) {
setLang(current);
}
}, 500);
document.addEventListener("mintlify-localstorage", onMintlifyStorage);
return () => {
document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
clearInterval(pollInterval);
};
}, [lang]);
const resolvedBody = useMemo(() => {
try {
const value = JSON.parse(lang);
// TypeScript uses camelCase, everything else (bash, python) uses snake_case
const useCamelCase = value === "typescript";
return useCamelCase ? convertToCamelCase(body) : body;
} catch {
return body;
}
}, [body, lang]);
const resolvedPath = useMemo(() => {
try {
const value = JSON.parse(lang);
// TypeScript uses camelCase, everything else (bash, python) uses snake_case
const useCamelCase = value === "typescript";
return useCamelCase ? convertToCamelCase(path) : path;
} catch {
return path;
}
}, [path, lang]);
// Render the ParamField with resolved values
return (
<ParamField body={resolvedBody} path={resolvedPath} {...props}>
{children}
</ParamField>
);
};

View File

@@ -0,0 +1,95 @@
import { useEffect, useMemo, useState } from "react";
/**
* A dynamic response example that shows JSON in the sidebar.
* Displays two tabs (TypeScript/Response) and auto-switches based on selected language.
*
* - TypeScript selected → shows camelCase tab
* - Python/cURL selected → shows snake_case tab
*/
export const DynamicResponseExample = ({ json, statusCode = "200" }) => {
// Convert snake_case to camelCase
const toCamelCase = (str) => {
return str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
};
// Recursively convert all object keys to camelCase
const convertKeysToCamelCase = (obj) => {
if (Array.isArray(obj)) {
return obj.map((item) => convertKeysToCamelCase(item));
}
if (obj !== null && typeof obj === "object") {
return Object.keys(obj).reduce((acc, key) => {
const camelKey = toCamelCase(key);
acc[camelKey] = convertKeysToCamelCase(obj[key]);
return acc;
}, {});
}
return obj;
};
const [isTypeScript, setIsTypeScript] = useState(() => {
if (typeof window !== "undefined") {
try {
const lang = localStorage.getItem("code");
return JSON.parse(lang) === "typescript";
} catch {
return true;
}
}
return true;
});
useEffect(() => {
// Listen for Mintlify's custom localStorage event
const onMintlifyStorage = (event) => {
if (event.detail?.key === "code") {
try {
const value = JSON.parse(event.detail.value);
setIsTypeScript(value === "typescript");
} catch {
// ignore
}
}
};
// Poll localStorage as fallback
const pollInterval = setInterval(() => {
try {
const lang = localStorage.getItem("code");
const value = JSON.parse(lang);
setIsTypeScript(value === "typescript");
} catch {
// ignore
}
}, 300);
document.addEventListener("mintlify-localstorage", onMintlifyStorage);
return () => {
document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
clearInterval(pollInterval);
};
}, []);
const camelCaseJson = useMemo(() => convertKeysToCamelCase(json), [json]);
const snakeCaseString = JSON.stringify(json, null, 2);
const camelCaseString = JSON.stringify(camelCaseJson, null, 2);
// Render tabs with CodeGroup-like behavior
// Only one tab is "active" based on the selected language
return (
<ResponseExample>
{isTypeScript ? (
<CodeBlock language="json" filename={statusCode}>
{camelCaseString}
</CodeBlock>
) : (
<CodeBlock language="json" filename={statusCode}>
{snakeCaseString}
</CodeBlock>
)}
</ResponseExample>
);
};

View File

@@ -0,0 +1,67 @@
import { useEffect, useMemo, useState } from "react";
/**
* A wrapper around Mintlify's ResponseField that dynamically switches
* between snake_case and camelCase based on the selected code language.
*
* - Node.js/TypeScript → camelCase (e.g., customerId)
* - Python/cURL/others → snake_case (e.g., customer_id)
*/
export const DynamicResponseField = ({ children, name, ...props }) => {
// Inline the toCamelCase function to avoid module scope issues with Mintlify's MDX compiler
const convertToCamelCase = (str) => {
if (typeof str !== "string") return str;
return str.replace(/[_-](\w)/g, (_, c) => c.toUpperCase());
};
const [lang, setLang] = useState(() => {
if (typeof window !== "undefined") {
const stored = localStorage.getItem("code");
return stored || '"typescript"';
}
return '"typescript"';
});
useEffect(() => {
// Listen for Mintlify's custom localStorage event
const onMintlifyStorage = (event) => {
const key = event.detail?.key;
if (key === "code") {
setLang(event.detail.value);
}
};
// Poll localStorage as a fallback (in case the event doesn't fire)
const pollInterval = setInterval(() => {
const current = localStorage.getItem("code");
if (current && current !== lang) {
setLang(current);
}
}, 500);
document.addEventListener("mintlify-localstorage", onMintlifyStorage);
return () => {
document.removeEventListener("mintlify-localstorage", onMintlifyStorage);
clearInterval(pollInterval);
};
}, [lang]);
const resolvedName = useMemo(() => {
try {
const value = JSON.parse(lang);
// TypeScript uses camelCase, everything else (bash, python) uses snake_case
const useCamelCase = value === "typescript";
return useCamelCase ? convertToCamelCase(name) : name;
} catch {
return name;
}
}, [name, lang]);
// Render the ResponseField with resolved name
return (
<ResponseField name={resolvedName} {...props}>
{children}
</ResponseField>
);
};

View File

@@ -143,7 +143,7 @@
{
"group": "Customers",
"pages": [
"api-reference/customers/get-or-create-customer",
"api-reference/customers/getOrCreate",
"api-reference/customers/list-customers",
"api-reference/customers/update-customer",
"api-reference/customers/delete-customer",
@@ -229,7 +229,7 @@
"display": "interactive"
},
"examples": {
"languages": ["typescript", "bash", "python"]
"languages": ["typescript", "python", "bash"]
}
},
"background": {

View File

@@ -0,0 +1,139 @@
/**
* Dynamic Response Example Script
*
* Patches the response example in the sidebar to switch between
* snake_case and camelCase based on the selected code language.
*
* - TypeScript → camelCase (e.g., customerId)
* - Python/cURL → snake_case (e.g., customer_id)
*/
(() => {
// Convert snake_case to camelCase
const toCamelCase = (str) =>
str.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
// Convert camelCase to snake_case
const toSnakeCase = (str) =>
str.replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
// Store original keys for each span
const originalKeysMap = new WeakMap();
// Check if TypeScript is selected
const isTypeScriptSelected = () => {
try {
const lang = localStorage.getItem("code");
return JSON.parse(lang) === "typescript";
} catch {
return false;
}
};
// Find response code groups (with "200" or "201" tabs)
const findResponseCodeGroups = () => {
const codeGroups = document.querySelectorAll(".code-group");
const results = [];
for (const codeGroup of codeGroups) {
const tabs = codeGroup.querySelectorAll('[role="tab"]');
for (const tab of tabs) {
const text = tab.textContent.trim();
if (text === "200" || text === "201") {
// Check if it's on the right side (sidebar)
const rect = codeGroup.getBoundingClientRect();
if (rect.left > window.innerWidth / 2) {
results.push(codeGroup);
}
}
}
}
return results;
};
// Update response examples
const updateResponseExamples = () => {
const useCamelCase = isTypeScriptSelected();
const codeGroups = findResponseCodeGroups();
for (const codeGroup of codeGroups) {
const codeElement = codeGroup.querySelector("code");
if (!codeElement) continue;
const spans = codeElement.querySelectorAll("span");
for (const span of spans) {
const text = span.textContent;
// Match JSON keys with optional leading whitespace
const keyMatch = text.match(/^(\s*)"([a-z][a-z0-9]*(?:_[a-z0-9]+)*)"$/);
if (keyMatch) {
const leadingWhitespace = keyMatch[1];
const keyName = keyMatch[2];
// Only process keys with underscores or camelCase
if (keyName.includes("_") || /[a-z][A-Z]/.test(keyName)) {
// Store original if not already stored
if (!originalKeysMap.has(span)) {
originalKeysMap.set(span, keyName);
}
const originalKey = originalKeysMap.get(span);
const newKey = useCamelCase
? toCamelCase(originalKey)
: toSnakeCase(originalKey);
if (keyName !== newKey) {
span.textContent = `${leadingWhitespace}"${newKey}"`;
}
}
}
}
}
};
// Listen for language changes
document.addEventListener("mintlify-localstorage", (event) => {
if (event.detail?.key === "code") {
requestAnimationFrame(updateResponseExamples);
}
});
// Poll as fallback
let lastLang = localStorage.getItem("code");
setInterval(() => {
const currentLang = localStorage.getItem("code");
if (currentLang !== lastLang) {
lastLang = currentLang;
updateResponseExamples();
}
}, 200);
// Run IMMEDIATELY - no waiting
updateResponseExamples();
// Aggressive early execution
const init = () => {
updateResponseExamples();
setTimeout(updateResponseExamples, 5);
setTimeout(updateResponseExamples, 15);
setTimeout(updateResponseExamples, 30);
setTimeout(updateResponseExamples, 50);
setTimeout(updateResponseExamples, 80);
};
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
// Watch for DOM changes - no debounce, run immediately
const observer = new MutationObserver(() => {
updateResponseExamples();
});
observer.observe(document.body, { childList: true, subtree: true });
})();

View File

@@ -0,0 +1,20 @@
/**
* Transform the language dropdown into horizontal tabs
* This targets the language selector in the API playground sidebar
*/
/* Hide the dropdown button/trigger */
[data-testid="code-sample-language-select"],
.code-sample-language-select,
[aria-haspopup="listbox"] {
/* We'll need to identify the exact selector - leaving as placeholder */
}
/*
* Note: Mintlify's language selector structure may vary.
* Use browser DevTools to inspect the exact element structure.
*
* Common approaches:
* 1. Hide dropdown, show custom tabs via JS
* 2. Use CSS to restyle the dropdown menu as always-visible tabs
*/

View File

@@ -10,3 +10,9 @@
border: 1px solid #661ecf;
}
/* Hide auto-generated OpenAPI sections (Authorizations, Headers, Body, Response) */
/* These sections are wrapped in div.api-section with h4 headings */
.prose > .api-section {
display: none !important;
}

View File

@@ -3,7 +3,7 @@
"private": true,
"scripts": {
"pull": "bun scripts/pull.ts",
"dev": "cd mintlify && mint dev",
"dev": "cd mintlify && mint dev -p 3002",
"build": "cd mintlify && mint build",
"start": "cd mintlify && mint dev"
},

View File

@@ -157,7 +157,7 @@
},
"packages/sdk": {
"name": "@useautumn/sdk",
"version": "0.7.20",
"version": "0.7.42",
"dependencies": {
"zod": "^3.25.65 || ^4.0.0",
},

View File

@@ -40,7 +40,9 @@ actions:
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);

View File

@@ -1,16 +1,16 @@
lockVersion: 2.0.0
id: 7b300647-cd76-49e9-bf77-7d1bf5446d66
management:
docChecksum: c2dc7dba08764fe54782d28e82bebe2b
docChecksum: b65ff198c2a9d322f115152bb4da709a
docVersion: 2.1.0
speakeasyVersion: 1.718.0
generationVersion: 2.824.1
releaseVersion: 0.7.20
configChecksum: 0b4fb6dcfb9d39ab7b3d33663bd406b2
releaseVersion: 0.7.42
configChecksum: 23cd3cf4d3605d0e5a292425ebaf5ba9
persistentEdits:
generation_id: a47f16dc-6445-4109-b975-2d3d49434c47
pristine_commit_hash: 11ad79633a20a21e4ef703ce48922a924c341aa5
pristine_tree_hash: 1e6fc7ba17b211330e97103160441cbef1c2b0dc
generation_id: 0f7b658f-ebaa-4605-a712-06d457b9e799
pristine_commit_hash: dea2c6e16c8cb9dc1ab4284cb2b3d5b43b270f4c
pristine_tree_hash: 11355c53ac460b9f5da2193b26776eea4116983b
features:
typescript:
additionalDependencies: 0.1.0
@@ -55,48 +55,24 @@ trackedFiles:
pristine_git_object: cf98a6bf092538eb10ff0edc915102682ce9a6e6
FUNCTIONS.md:
id: 21b9df02aaeb
last_write_checksum: sha1:3c9d7c1644476bc2e48b361e67f885ef6708e614
pristine_git_object: 366dd158e15755fa8c2c2293526157baf74a2eb1
last_write_checksum: sha1:3102381f2f0239e6cd820f6048dc9df14e57ad2d
pristine_git_object: 997ec44c4ee5408258b58112c217e8366d69c2b3
RUNTIMES.md:
id: 620c490847b6
last_write_checksum: sha1:e45b854f02c357cbcfdb8c3663000e8339e16505
pristine_git_object: 27731c3b5ace66bedc454ed5acbe15075aacd3dc
USAGE.md:
id: 3aed33ce6e6f
last_write_checksum: sha1:10f6478b29d718ad6358cc390de6a12db5bd056b
pristine_git_object: 1f64b54ba78036e3b0bfec0d98dfefb94d9e0fee
last_write_checksum: sha1:fee4559ff519f06ab91e5e9656ae606256dc386c
pristine_git_object: b1d99bf9ec8e5f90834cf4649c5498b453dd961b
docs/lib/utils/retryconfig.md:
id: 0ce9707cb848
last_write_checksum: sha1:bc4454e196fcd219f5a78da690375a884f5ed07b
pristine_git_object: 08f95f4552349360b2c0b01802aa71ec3a55d2c2
docs/models/attach-credit-schema.md:
id: e37ce7b7ba9d
last_write_checksum: sha1:1a934ee70a7789cc65ba68215a732cd88fe26d36
pristine_git_object: 20689c736f1c180f4f520bd4c93883d867eedbaa
docs/models/attach-display.md:
id: c25e4feece03
last_write_checksum: sha1:8a68328a53756aaa6ab37ae0f6a2beb98ac956ea
pristine_git_object: c58afd1fcdc25fdfd18334e4d59fdc152bfe00a7
docs/models/attach-entity-data.md:
id: c0443720a588
last_write_checksum: sha1:1fc239d8107d0c393615bdebd9579d2b24b92cbe
pristine_git_object: bbbd9b61970ff04dfc9a588af42763ecbd8584b3
docs/models/attach-feature-display.md:
id: 47a5e489165c
last_write_checksum: sha1:55736a8750008681ad6069f32c8d73244bc49cc2
pristine_git_object: 34af62fc13848961b5e7cc808cc0acb6bcdfaf6d
docs/models/attach-feature-type.md:
id: 5e3b989a646b
last_write_checksum: sha1:88846b672de0e2386f0f5ffa436a6412ec87096d
pristine_git_object: 47b42c605eb5a049726d57bcf52f74873529eb83
docs/models/attach-feature.md:
id: 18a0c43374da
last_write_checksum: sha1:f9b22b2ddaa97b7b2ae038e484a85e9633f789f4
pristine_git_object: 559ceb6cbfe519bdc01e043a324d62eb20481ea2
docs/models/attach-free-trial.md:
id: 6572f2ad0a92
last_write_checksum: sha1:04a0d6e03bda7b7ca9c21ac2146210206456ff8e
pristine_git_object: 1a2397bd25f0c906ac860838f8b2409e2a6bd47a
last_write_checksum: sha1:d6194625284ac6f307cd38b0603daa3426b660f9
pristine_git_object: 7b56ce6ed66527b699204d6d8f5e3e1e5aaf9b22
docs/models/attach-globals.md:
id: 3f5659c4527e
last_write_checksum: sha1:5ecc4152cef4f786f4c1bb41b2b4ca42d51c5bdd
@@ -111,28 +87,16 @@ trackedFiles:
pristine_git_object: f19f81978da4df350b9b9f6f85f700c54b1e290c
docs/models/attach-item.md:
id: ea7481c84d0f
last_write_checksum: sha1:6c25ac4c881f1ad11f93c0fc45e3a4f898608c95
pristine_git_object: 7e639c9899521bc25e237a8bc7e4632a8358a42d
docs/models/attach-on-decrease.md:
id: 730009f79373
last_write_checksum: sha1:afef078ee75a7f0c01eb048321e1b770ed4b38ad
pristine_git_object: f1b38ac1aba245801c6accef2d5b3b8d60d7752d
docs/models/attach-on-increase.md:
id: 5941c36420ab
last_write_checksum: sha1:db94107b8ed6d6316d55a63f9bc412731754e245
pristine_git_object: f3150762704ffa777462088f7066f0bd3b286c8c
last_write_checksum: sha1:70d77b571c83d58810738b7c5969df1b8721969f
pristine_git_object: 5dab41e71b2c203495d96ce060b7e0100f26167a
docs/models/attach-request.md:
id: 9e2ed03c1844
last_write_checksum: sha1:a8166f3e40d630c7d6aaaf2aee7109a40483f436
pristine_git_object: adce3a547dafe10caf62c9b6a5b45c2f72740436
last_write_checksum: sha1:ac9e609f3ab72a889cc51f373f3d1b76fde42853
pristine_git_object: 50a550a22b82814cff9b78f60eff43623363060b
docs/models/attach-response.md:
id: 7a5806587fd5
last_write_checksum: sha1:a7b8266aa2eeff06be640e3122290aacc690db37
pristine_git_object: 2c48f0863a83a7365543db4cdeb40f7722111bb4
docs/models/attach-rollover.md:
id: d84522e07be9
last_write_checksum: sha1:fc4e23599d9f86bda0424d413a6060bc1f3c3bd5
pristine_git_object: 8eb5c77fbb245841ddf291ad9bc145517eb83171
last_write_checksum: sha1:7849b490fb4bc8b5556b7133465ce026d13581e7
pristine_git_object: b3eec4c3fbf69785c5666a08354bce0040bb9693
docs/models/attach-to.md:
id: 39243c9d9b34
last_write_checksum: sha1:b3cdc5c90abed4d59f033c545019f56a3d2e2ce1
@@ -141,42 +105,26 @@ trackedFiles:
id: d6b7b8d3105d
last_write_checksum: sha1:3a9b2390259d4fcd61c66de3ced8d1d50c9f2d00
pristine_git_object: 5316b2b61c30f9a86d13d723c08c112c498a3b0b
docs/models/balances-type.md:
id: 062f249673a5
last_write_checksum: sha1:c9540f9c79933112766da6927ad51817f0240565
pristine_git_object: 1c48ab0c7bfc6f7e9958416816775d1fcc990374
docs/models/balances.md:
id: 2f042cf3d0aa
last_write_checksum: sha1:9a9c2a84d066247446703b35af6efe14f5df1cb3
pristine_git_object: fd59d3018e8e84c9fcdf744a438072eff75638b6
last_write_checksum: sha1:b4b98e12527cbc39740c582a568427d715b85d03
pristine_git_object: 3cecc0799bb1f00476c41b9a5c99c4e79b5ceb5e
docs/models/billing-behavior.md:
id: 59f3b5602fbf
last_write_checksum: sha1:6ed351e2827574db97767e81b035f3ec225c01ab
pristine_git_object: 4633622403fdd0438509ff950c13f857121fc588
docs/models/breakdown.md:
id: 786823ab8ff0
last_write_checksum: sha1:6992c68ed199fd46e06c6e7d26d412704f9164f8
pristine_git_object: f6bdbd480cbf0f5ae1083f2c9cd3a9cd0fb80e9f
last_write_checksum: sha1:683ea06e2215c28c720f9851b4368098e0d06807
pristine_git_object: be7b8808f650d49888af3e88b2d8ce34a335c7df
docs/models/code.md:
id: 2fcb3964c9c0
last_write_checksum: sha1:94a4beade541c66d62dec0d861813fe1ac19dd69
pristine_git_object: 595d8bd35314feacf5137f361e0eefb8889072ad
docs/models/config.md:
id: bef254bf823c
last_write_checksum: sha1:921ea7390c3e59cde4183cddca10e8801f3e74a8
pristine_git_object: dc46421150487f7c036fc0abc4b87d69f6747c60
docs/models/customer-billing-method.md:
id: 06ff2abe6f74
last_write_checksum: sha1:1a9942bc1176ec5185bfe33171162879bf79f405
pristine_git_object: 12c6c12ff6d8e5fc4dc9a98e0ab1dec6ea7efbb7
docs/models/customer-credit-schema.md:
id: fa77c00fcafd
last_write_checksum: sha1:adf6bb711b3cfd99d84da8977c3005cb3baa24e1
pristine_git_object: de538f3a711b297dcba238dd7db908ee881dae7f
docs/models/customer-display.md:
id: 58fadfb6f84d
last_write_checksum: sha1:02389782a6f3873571e7a8866eed09a5cc6098f5
pristine_git_object: d86e56fea265fbd888ae6d62a570f54aa883be0a
docs/models/customer-duration-type.md:
id: cbfbb0769db5
last_write_checksum: sha1:5cc7fc548fc238c2c4db1517e1192dc036a74139
@@ -187,16 +135,12 @@ trackedFiles:
pristine_git_object: ca0c3e1ce1ea2f60e4cf2206bb9b21e18b9b5997
docs/models/customer-env.md:
id: f063b206890c
last_write_checksum: sha1:dd6afc952f52e7712a47578ebeb934f351c18544
pristine_git_object: a94e4434643f2acf3fffc2f5ed964ed5ac620493
last_write_checksum: sha1:cc47133530e606c040759b3f18b48dad7b78cdae
pristine_git_object: d210083c532e8c527f089ea2abc2c227e2b7d8e2
docs/models/customer-expand.md:
id: 1730127f931b
last_write_checksum: sha1:1d88fca3d4cc3cdcb78a1a46a91039b9d2f323c0
pristine_git_object: fd2e47dfff6dba01fbad342c2de102c69d44643f
docs/models/customer-feature.md:
id: d90579a4e5c4
last_write_checksum: sha1:b09eb0f015b76749b4d5c12016f1665a2b5c60a6
pristine_git_object: 3cf02ec91d3338efff44cc9cc98c25645c0cd805
docs/models/customer-interval-enum.md:
id: b224f2bcbf4b
last_write_checksum: sha1:ef6926633f780442c7a7bce1a12c230465f3d6ad
@@ -223,44 +167,36 @@ trackedFiles:
pristine_git_object: adb4e6a216daf5fe4f5e1566821240b1406007e1
docs/models/customer.md:
id: 42ac97d31359
last_write_checksum: sha1:90af98cc54ce0fd322f539c2498ae7907c3a7d91
pristine_git_object: 0839a1cd2391cb97fd95210ccbb4adc5b9c6594b
last_write_checksum: sha1:177f9e80f86abcbf82d34ac230f78e26eb8afe05
pristine_git_object: 3df262773e09df832a517056728d2add293693e2
docs/models/discount.md:
id: 003b28f6c8a6
last_write_checksum: sha1:514d11ebc37ebdb692a8137be44b60d35549cfb7
pristine_git_object: 1cd19465e5e2ccba85d1117383cbb3ee6cae7763
last_write_checksum: sha1:fe89c4a5f07986dc1fd721b026218e7c96c2c63c
pristine_git_object: ea251e97cc69c9984c3c53295a03285a72541476
docs/models/duration.md:
id: e63d42c932a8
last_write_checksum: sha1:3ebfb271ff5182a27635748d8c7e3d9594fef510
pristine_git_object: e70c1be447f86b333b4cc601f7b8859ad5da92a8
docs/models/entity-env.md:
id: 817aa096ab27
last_write_checksum: sha1:e57c22c174cf8744c9fbc793a21c87eab86ba81a
pristine_git_object: ea4e92658978c0c7494a04f24e0f2e9276baaaac
docs/models/entity.md:
id: 903c73579a5c
last_write_checksum: sha1:3d90d8923798be834d241db6e33846dbbac2cfdf
pristine_git_object: 2ea16cf6f98cf4b2085ace4dae3ff34cbbe45f9f
last_write_checksum: sha1:d45c1e98846cb22fa28b885b66bf4d341947673f
pristine_git_object: 5445e914a693e4bfa626d820fdba75a41b7b002d
docs/models/expiry-duration-type.md:
id: 3a927f275515
last_write_checksum: sha1:7059b0a8efd82cdb43c176b868824f5e26d8eb0c
pristine_git_object: 38df300d40088ea211de7e229c77987ee9d3131a
docs/models/feature-type.md:
id: c6368d6178e0
last_write_checksum: sha1:766b96f4d82e9f605cd116463185693ce9b1e142
pristine_git_object: 198d92062ec33064dddeb98c8a5a8629f2b74d67
docs/models/free-trial-duration.md:
id: f12ff48f6deb
last_write_checksum: sha1:6bdcbe59c8809621662ed02862470a853f1381bf
pristine_git_object: 5e95863eddcf6a24ba96e04bc6eee060a73a0b9e
docs/models/free-trial.md:
id: 7d40737b76e3
last_write_checksum: sha1:ab8208a5a5ab8963a8c8fa7f93dfdd9cd068f6c4
pristine_git_object: 4600b15c1d50b17c86bfde5df59541dd36c152e1
docs/models/get-or-create-customer-params.md:
id: 496662dd4c0d
last_write_checksum: sha1:130b79ab63bb25eaa152941e3fa2107ace38134d
pristine_git_object: 58995fc8b9e0b6385640b5ac7f67554c55b7151c
docs/models/get-or-create-entity-data.md:
id: 7ea7a1bc773a
last_write_checksum: sha1:b973aa8ec00ba32917245e403cccd2354bd30c73
pristine_git_object: c7205896399f1ece85a220bddd669506f38b4ac4
last_write_checksum: sha1:5bac80cea5c986ca03ff3d732070e618c39663f9
pristine_git_object: 570053b312dc0a87a05f1b71f815fae814697a7f
docs/models/get-or-create-globals.md:
id: 8474dc7dbc80
last_write_checksum: sha1:7a65f90b8e52bfdd196c95737a4c200cf8146e48
@@ -269,26 +205,22 @@ trackedFiles:
id: f27abcdfdd7d
last_write_checksum: sha1:ca0a41260fa62322a9525f4267ac0ec6d93ae6d8
pristine_git_object: 5fe6a61067cd319d6cd0d1e1e7f1d165c0d4579d
docs/models/internal-options.md:
id: 46603a381a4a
last_write_checksum: sha1:9a8d19e1849b4817955d61774bf6fced9fc3b76c
pristine_git_object: b3d4895ebc3dd7509c5f05f319273039c4711fb0
docs/models/interval.md:
id: 11a74d2c19c0
last_write_checksum: sha1:1d612bf1b73e7b6f54c8086bf13964ae62496463
pristine_git_object: 6bd470a06b95cb33d5f2b2f4f4a609dbbae9a544
docs/models/invoice.md:
id: 18e2034f11ad
last_write_checksum: sha1:321079a7eab955ee497e7879908a4c2e9ee446b2
pristine_git_object: 39f3d1c3ab247ec4559923d5191fff971b8e5572
last_write_checksum: sha1:72f2f97f724891e9af6123a5c2826181328b494f
pristine_git_object: f7338b19bded9bd82efc9687fafc03c2a02bf371
docs/models/item-price.md:
id: ec7f6a9f6ac5
last_write_checksum: sha1:9d5ea14c2b3845ed4489ac33fbdfa391d1bc6def
pristine_git_object: 0d853a9a3abbd1aede8b939c43f23adab900f6b7
docs/models/item.md:
id: 40dd7473ab87
last_write_checksum: sha1:6a0d28d078e7e5180d619c66f9e8aeec3322919a
pristine_git_object: b2b784472c604e53e6f303c249e09ba8aaeee45a
last_write_checksum: sha1:81e925dbb597518a2a3975856f56ee346e73a11f
pristine_git_object: 8f8d120e33c446a1134415a84ac24f5641a50885
docs/models/list-globals.md:
id: 58d9bcee8a08
last_write_checksum: sha1:0c51ff1aa46dce6a17238f78ae70a44b721139a3
@@ -317,10 +249,6 @@ trackedFiles:
id: 4789ae90ae01
last_write_checksum: sha1:8b53127c48cd1e81a29d62093ae96a52359b268a
pristine_git_object: 930e05fe377d4ab12fd2b0245af950d9fd637967
docs/models/plan-credit-schema.md:
id: 4a323c1dbf0a
last_write_checksum: sha1:167acec310caca3e8e3b1cd5461c5453994f09c9
pristine_git_object: 9dfd58042a96b6de19c6f5f3a21319e1806a35a0
docs/models/plan-duration-type.md:
id: 522f79a4e1c8
last_write_checksum: sha1:6265d10215e91bb4846f1f7648293cf04530d3d2
@@ -329,22 +257,10 @@ trackedFiles:
id: 2684553fa0b2
last_write_checksum: sha1:43ecc2f0ae7ad2dd6acdbf3ea9a5c779855ede8a
pristine_git_object: 73febb8eb90f0795e0bbcf16621698de452a1f41
docs/models/plan-feature-display.md:
id: 4a23e75025f8
last_write_checksum: sha1:bf383e336435e84f0c51cbf12ad34db39fd5e8cd
pristine_git_object: 659e383eacdd48be82e3caa9beeddec253f70168
docs/models/plan-feature.md:
id: 1f1e65046cf0
last_write_checksum: sha1:9074682f8d32da2094c50b0da20a9d7b38ef1fdc
pristine_git_object: 1fdccbb593aac6e1317b73dc7fc16f562ca7ac1f
docs/models/plan-item-display.md:
id: 1004f58a3986
last_write_checksum: sha1:922a8816cd34fbb741b7ec1913d173cdf3d57894
pristine_git_object: decdbe96b1f83815156d96e1212ffbe7228263f6
docs/models/plan-price.md:
id: f24c0778a8d1
last_write_checksum: sha1:f0ad29bd2ec5a67f789192a2a417dd03ec213d93
pristine_git_object: 3281c16938de8837e0285cd2d93f989953c5e305
last_write_checksum: sha1:507311eb39a5936fd9bc44830d86ec0e5bd8dd22
pristine_git_object: bce113caf172ed0bddd6f24b0cd6dd6779b490b8
docs/models/plan-reset-interval.md:
id: 3ae21ed47961
last_write_checksum: sha1:957ef7145ffd6a231785068b66c82109dade812e
@@ -369,18 +285,10 @@ trackedFiles:
id: 265b5d85de02
last_write_checksum: sha1:73ba2dc4aa70a0e8dd181c625d49e195512a5aa8
pristine_git_object: 7a48160543abf02c3620bd86ccb7150bc32dad8f
docs/models/plan-type.md:
id: fcf04293a720
last_write_checksum: sha1:8a55b776c10325c521c94693c2301c3d35865204
pristine_git_object: e573a1e61915a219fc68d1e31dd55c795dda4253
docs/models/plan.md:
id: 900c4149ef4b
last_write_checksum: sha1:08f56cb8cac6d89aba2436975994c1648d8d286d
pristine_git_object: c02b9a57fbf832794d06b60296903c7304bddb55
docs/models/price-display.md:
id: e7cc8364bc4b
last_write_checksum: sha1:f7d122e7b7776cdcffbc40fd2ced81a215d89c23
pristine_git_object: 9fd5718215ab2855e209fdd606611f33fbf42562
last_write_checksum: sha1:429d233584eef116d3b165d6c09a050c1f9fc20a
pristine_git_object: 8b12eea5ba974880103edaa1a30a498ed3191124
docs/models/price-interval.md:
id: 098d30620284
last_write_checksum: sha1:2f1acca2ad16f4709fb7cb72a869505a18826bbc
@@ -389,10 +297,6 @@ trackedFiles:
id: 56e3a7187c31
last_write_checksum: sha1:547a74f28866d9ad6218a3237f84946702583323
pristine_git_object: 9c3129cdde3ae9435727cd29013bdb747d8e0b32
docs/models/processors.md:
id: 58a19fb5be82
last_write_checksum: sha1:ebfabf19e886b2180ea0fe67f9ed8831d4155f5f
pristine_git_object: 7d7af7b029aa6abc8ab80dad87044ed02670e8a0
docs/models/proration.md:
id: ac1d089c0fd1
last_write_checksum: sha1:a0763bf3863245e1ea7004d99849431c154e9ee6
@@ -407,28 +311,20 @@ trackedFiles:
pristine_git_object: 4f29bd931311fec97a473b5bf61b12edcb7da7b9
docs/models/referral-customer.md:
id: d9629d974163
last_write_checksum: sha1:e4dab25dd04e413f338e813241694e88cb29c09f
pristine_git_object: 9537eddc4601bf6752271bc008cf8d9c93637781
last_write_checksum: sha1:d12745723bb0c0cf3cbdfad581ca4dabf9323685
pristine_git_object: e4978f3af0c093684838ec97443ae4bfb668ad3e
docs/models/referral.md:
id: b58def2d8bbe
last_write_checksum: sha1:6147d00b05240ea19ab4a012e37012501462790e
pristine_git_object: 6133ec7c2af5271b41ce09dddfb0eb8cbeb14418
last_write_checksum: sha1:4a205e661d3b742293132c8151388e72df5069b0
pristine_git_object: 50e78acb13c4e157062623894c2e24fc497872c0
docs/models/required-action.md:
id: d4ddcbc1c128
last_write_checksum: sha1:c8f6235625f02d16392e0bbe5a671a2e534532b1
pristine_git_object: a3ae9b548a71e115f7b0c1924d256b9d7ce35553
docs/models/rewards-type.md:
id: c48adeacd4fc
last_write_checksum: sha1:fc8c460d22c515495d54385f2b0ea1f045605e26
pristine_git_object: ca2e4f7e35d62a3bfc3658e8c3e20dbdc6e0ed70
docs/models/rewards.md:
id: 4551c882db3e
last_write_checksum: sha1:400f48d09c30265fc4650ca42db90109dfdda599
pristine_git_object: 08b89a9cc150d2d174408e0ccb7d2eea9b8e4014
docs/models/rollover-duration.md:
id: 2d83c1287827
last_write_checksum: sha1:d985888074faf41e8863b9396948c5e343990b0c
pristine_git_object: 6cf5cb14756b709ae6ddd12d4c013f435ea1f0ac
last_write_checksum: sha1:7238c7de53b3e40b56d4f7207f84b5813069fc7c
pristine_git_object: dd7ce5d168ac8811cb85dc3e4d61f917ef4f0dd3
docs/models/scenario.md:
id: e3aad8ab5efa
last_write_checksum: sha1:5d6f7c24e821bf73b9ea5f4915448acc27c0f84f
@@ -453,22 +349,22 @@ trackedFiles:
id: 983b78eb51b7
last_write_checksum: sha1:0fdc1753311eb276ea3d69f275f9bafaf196e538
pristine_git_object: 72df6cb602ecac3658f8cbb19ea2c460995b7a4a
docs/models/type.md:
id: 98c32f09b2c8
last_write_checksum: sha1:4cd3d065f419718c7d6883a133111999832246cc
pristine_git_object: 6f4d6d7fdd81d3ab6e3a41fc239af15d811f4bfe
docs/models/usage-model.md:
id: 32a269601e79
last_write_checksum: sha1:e5426aec062e39992d0a277844320dcce769247e
pristine_git_object: 4e7db15000553c421e46aad834f78ce740a8bb3b
docs/models/vercel.md:
id: 634d8fed39b3
last_write_checksum: sha1:ec591bc9a021f2d9242d75a1ec07b6a437afc134
pristine_git_object: 73b36b5f50170166e92cfa6f9301fc2fd4b1197a
docs/sdks/billing/README.md:
id: dc915331dd9d
last_write_checksum: sha1:9e15c3bc90aedc98908163d5c54f4e565376297e
pristine_git_object: 6736de1838264c53e45c3ecc0171a5d59b7f2ca6
docs/sdks/customers/README.md:
id: 9332759cffc2
last_write_checksum: sha1:975abb1d66875214e3dc3bb746eaabae37ffda75
pristine_git_object: a0b2f21dc3fc383d7ea05c40c0e8152b8dd134bf
last_write_checksum: sha1:63e6af1b2c380806e67a371a1cf8a1adca199de0
pristine_git_object: f1b8887234d1e057ca7b410846b03f918dd289b9
docs/sdks/plans/README.md:
id: 2d8c741fff57
last_write_checksum: sha1:3611895f9b87e480540dbac3c793f7305874949a
@@ -487,20 +383,20 @@ trackedFiles:
pristine_git_object: 0928c2ed5c0c739a6fb22e31cdaf11d6bdec9dae
examples/customersGetOrCreate.example.ts:
id: cb3cc2b938f4
last_write_checksum: sha1:63cbb196db201a734ef0adda02a1b6830a353683
pristine_git_object: dc5cc1835c1c0cd260d344b07fae899163843c7f
last_write_checksum: sha1:c519055c000dbbdca007d9e17d6c33a760c26b8d
pristine_git_object: b6af2731f32a8033a302dfc9681a50d2be6933ef
examples/package.json:
id: c1d7b0ec8e7e
last_write_checksum: sha1:22cf1a48e1d9bc8ffc9e65280aeaa5600b54f659
pristine_git_object: 900d545ed58929951e2208e1bec791cb264429a4
jsr.json:
id: 7f6ab7767282
last_write_checksum: sha1:2e89abed613d4deac741401a416279b68cfa9e72
pristine_git_object: 93b86e0cdade6cd1d8a890fc839d4b485097a5fb
last_write_checksum: sha1:2ce25e32bab42a880fc6498360a871a43357888f
pristine_git_object: 684984ebe5493a297d54faff8714d77554ba7b06
package.json:
id: 7030d0b2f71b
last_write_checksum: sha1:0352148b93072588870244e5f8189426040f3582
pristine_git_object: 9ef6629935a084177973f29c3964fcf927dc2efb
last_write_checksum: sha1:91b53018ad823a78b85fce80d957c92d08b5f77b
pristine_git_object: b7e45b2d9bd335948cb06bec21f9929055be19e6
src/core.ts:
id: f431fdbcd144
last_write_checksum: sha1:f8f24a3ca09c1efb285d7a75ad3697d0128f47e2
@@ -539,8 +435,8 @@ trackedFiles:
pristine_git_object: 44be0eae8246521b230e8e711a88eff738fc015d
src/lib/config.ts:
id: 320761608fb3
last_write_checksum: sha1:027a62f4a5a0c604e17486a65b11de580239e35d
pristine_git_object: 138841a530619f3d549f4bb45d7ea82bbd45eae4
last_write_checksum: sha1:e3b723c26583ed242be8fad113ab078fe76c7f5b
pristine_git_object: 640df00eb1c9da144695c202389f4660b2bf0a03
src/lib/dlv.ts:
id: b1988214835a
last_write_checksum: sha1:1dd3e3fbb4550c4bf31f5ef997faff355d6f3250
@@ -599,8 +495,8 @@ trackedFiles:
pristine_git_object: f3a8de6c021de59c991707946cd294596cae954d
src/models/attach-op.ts:
id: 83ed65c26ab4
last_write_checksum: sha1:fa1dfadde0b9a6c2ed7415b5a304d3764e7c742d
pristine_git_object: f6b11ac71ed243aa1c7b53eaf042394dcc2c939a
last_write_checksum: sha1:bcb938761d3fde5cdb99972f5d3a1e217ae04064
pristine_git_object: c21e0da461bc1693209f241aa7f0583d46befa5e
src/models/autumn-default-error.ts:
id: 2528aa7886eb
last_write_checksum: sha1:4cce18f91be3262ada7d11dcd6326544e2341b58
@@ -615,12 +511,12 @@ trackedFiles:
pristine_git_object: b6a303e11f4d5964b94379a470104d00ff8fb5cc
src/models/customer.ts:
id: 20be78c552a4
last_write_checksum: sha1:b20d0e4e9c9a5b384297a437e1b806587b124672
pristine_git_object: 6edbd6a499807514d6c17d7ffd2a813a56406231
last_write_checksum: sha1:1e62b5e3dc777ebecac4909ab72ab93e4576b380
pristine_git_object: 036a131058981bf1e54dc3d0f5b005fb710cec61
src/models/get-or-create-op.ts:
id: c9bf055f57c4
last_write_checksum: sha1:98f4bb2204a75a4971260c1989e13ab922b06b7c
pristine_git_object: 7682293daf9374ca0b5b8ddcb658a3e0b191a7cc
last_write_checksum: sha1:40fa9030712cc39e5cb6d847546282c93da9866a
pristine_git_object: 6adb75311f5d00821820a877a4cca8ce0cffce7a
src/models/http-client-errors.ts:
id: 5f17dcf0d62b
last_write_checksum: sha1:994ced121c54fecd0af038ccfb7855fbfd3868ec
@@ -635,8 +531,8 @@ trackedFiles:
pristine_git_object: 43d0cd93187b7cead79aa26cfd1e2e52d29f981b
src/models/plan.ts:
id: 9e9698a64fe7
last_write_checksum: sha1:16948e44711f31e314cc6954e123e78ef5b2d332
pristine_git_object: e2c1491b90c9c4dd678b1d0b2f912a9633e4001d
last_write_checksum: sha1:543249fe6318abf6a24e873514f989f42f7c6ac2
pristine_git_object: 1e7d7434b24cf1d9a01126d078fbcedb2107f4c0
src/models/response-validation-error.ts:
id: 7ace3beff92b
last_write_checksum: sha1:2788a46874d1d2b88a1fe8352142516f2e5c9ded
@@ -1023,10 +919,10 @@ examples:
header:
x-api-version: "2.1"
requestBody:
application/json: {"customer_id": null, "with_autumn_id": false}
application/json: {"customer_id": "cus_123", "name": "John Doe", "email": "john@example.com"}
responses:
"200":
application/json: {"id": null, "name": "<value>", "email": "Catalina_Upton93@gmail.com", "created_at": 9912.5, "fingerprint": "<value>", "stripe_id": "<id>", "env": "live", "metadata": {}, "send_email_receipts": false, "subscriptions": [], "purchases": [{"plan_id": "<id>", "expires_at": 9063.34, "started_at": 7932.64, "quantity": 6363.06}], "balances": {"key": {"feature_id": "<id>", "granted": 4916.32, "remaining": 316.12, "usage": 4086.82, "unlimited": false, "overage_allowed": true, "max_purchase": 7668.31, "next_reset_at": 1196.51}}}
application/json: {"name": "John Doe", "email": "john@example.com", "fingerprint": "1234567890", "stripe_id": "cus_123", "env": "sandbox", "metadata": {}, "send_email_receipts": false, "subscriptions": [{"plan_id": "plan_123", "auto_enable": true, "add_on": false, "status": "active", "past_due": false, "canceled_at": 1668.32, "expires_at": 9089.12, "trial_ends_at": 9379.96, "started_at": 2917.49, "current_period_start": 8238.87, "current_period_end": 5653, "quantity": 1}], "purchases": [], "balances": {"balance_1": {"feature_id": "<id>", "granted": 124.65, "remaining": 8304.41, "usage": 3422.44, "unlimited": false, "overage_allowed": false, "max_purchase": 7932.64, "next_reset_at": 7580.04}}}
list:
speakeasy-default-list:
parameters:
@@ -1034,5 +930,5 @@ examples:
x-api-version: "2.1"
responses:
"200":
application/json: {"list": [{"id": "<id>", "name": "<value>", "description": "distant recompense trick", "group": "<value>", "version": 9615.63, "add_on": true, "auto_enable": false, "price": {"amount": 2384.12, "interval": "week"}, "items": [{"feature_id": "<id>", "included": 4974.83, "unlimited": false, "reset": {"interval": "day"}, "price": {"interval": "month", "billing_units": 5281.09, "billing_method": "prepaid", "max_purchase": 8873.17}}], "created_at": 8066.8, "env": "live", "archived": true, "base_variant_id": "<id>"}]}
application/json: {"list": [{"name": "<value>", "description": "distant recompense trick", "group": "<value>", "version": 9615.63, "add_on": true, "auto_enable": false, "price": {"amount": 2384.12, "interval": "week"}, "items": [{"feature_id": "<id>", "included": 4974.83, "unlimited": false, "reset": {"interval": "day"}, "price": {"interval": "month", "billing_units": 5281.09, "billing_method": "prepaid", "max_purchase": 8873.17}}], "env": "live", "archived": true, "base_variant_id": "<id>"}]}
examplesVersion: 1.0.2

View File

@@ -33,7 +33,7 @@ generation:
generateNewTests: true
skipResponseBodyAssertions: false
typescript:
version: 0.7.20
version: 0.7.42
acceptHeaderEnum: false
additionalDependencies:
dependencies: {}

View File

@@ -26,40 +26,39 @@ components:
Customer:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
name:
anyOf:
- type: string
- type: "null"
description: The name of the customer.
email:
anyOf:
- type: string
- type: "null"
created_at:
type: number
description: The email address of the customer.
fingerprint:
anyOf:
- type: string
- type: "null"
description: "A unique identifier (eg. serial number) to de-duplicate customers across devices or browsers. For example: apple device ID."
stripe_id:
anyOf:
- type: string
- type: "null"
description: Stripe customer ID.
env:
enum:
- sandbox
- live
description: The environment this customer was created in.
metadata:
type: object
propertyNames: {}
additionalProperties: {}
description: The metadata for the customer.
send_email_receipts:
type: boolean
description: Whether to send email receipts to the customer.
subscriptions:
type: array
items:
@@ -148,55 +147,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
name:
type: string
type:
enum:
- boolean
- metered
- credit_system
consumable:
type: boolean
event_names:
type: array
items:
type: string
credit_schema:
type: array
items:
type: object
properties:
metered_feature_id:
type: string
credit_cost:
type: number
required:
- metered_feature_id
- credit_cost
display:
type: object
properties:
singular:
anyOf:
- type: string
- type: "null"
plural:
anyOf:
- type: string
- type: "null"
archived:
type: boolean
required:
- id
- name
- type
- consumable
- archived
granted:
type: number
remaining:
@@ -221,9 +171,6 @@ components:
items:
type: object
properties:
id:
type: string
default: ""
plan_id:
anyOf:
- type: string
@@ -357,9 +304,6 @@ components:
currency:
type: string
description: The currency code for the invoice
created_at:
type: number
description: Timestamp when the invoice was created
hosted_invoice_url:
anyOf:
- type: string
@@ -371,19 +315,11 @@ components:
- status
- total
- currency
- created_at
entities:
type: array
items:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
description: The unique identifier of the entity
name:
anyOf:
- type: string
@@ -399,18 +335,13 @@ components:
- type: string
- type: "null"
description: The feature ID this entity belongs to
created_at:
type: number
description: Unix timestamp when the entity was created
env:
enum:
- sandbox
- live
description: The environment (sandbox/live)
required:
- id
- name
- created_at
- env
trials_used:
type: array
@@ -437,9 +368,6 @@ components:
items:
type: object
properties:
id:
type: string
description: The unique identifier for this discount
name:
type: string
description: The name of the discount or coupon
@@ -490,7 +418,6 @@ components:
- type: "null"
description: Total amount saved from this discount
required:
- id
- name
- type
- discount_value
@@ -509,8 +436,6 @@ components:
customer:
type: object
properties:
id:
type: string
name:
anyOf:
- type: string
@@ -519,26 +444,20 @@ components:
anyOf:
- type: string
- type: "null"
required:
- id
required: []
reward_applied:
type: boolean
created_at:
type: number
required:
- program_id
- customer
- reward_applied
- created_at
payment_method:
anyOf:
- {}
- type: "null"
required:
- id
- name
- email
- created_at
- fingerprint
- stripe_id
- env
@@ -547,11 +466,34 @@ components:
- subscriptions
- purchases
- balances
examples:
- id: cus_123
created_at: 1717000000
name: John Doe
email: john@example.com
fingerprint: "1234567890"
stripe_id: cus_123
env: sandbox
metadata: {}
subscriptions:
- id: sub_123
created_at: 1717000000
plan_id: plan_123
status: active
quantity: 1
interval: month
interval_count: 1
purchases: []
balances:
balance_1:
id: balance_1
amount: 100
currency: USD
created_at: 1717000000
updated_at: 1717000000
Plan:
type: object
properties:
id:
type: string
name:
type: string
description:
@@ -584,15 +526,6 @@ components:
- year
interval_count:
type: number
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
required:
- amount
- interval
@@ -604,65 +537,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like /track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
included:
type: number
unlimited:
@@ -733,15 +607,6 @@ components:
- billing_method
- max_purchase
- type: "null"
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
rollover:
type: object
properties:
@@ -796,8 +661,6 @@ components:
- duration_length
- duration_type
- card_required
created_at:
type: number
env:
enum:
- sandbox
@@ -827,7 +690,6 @@ components:
required:
- scenario
required:
- id
- name
- description
- group
@@ -836,7 +698,6 @@ components:
- auto_enable
- price
- items
- created_at
- env
- archived
- base_variant_id
@@ -918,67 +779,21 @@ paths:
auto_enable_plan_id:
type: string
description: The ID of the free plan to auto-enable for the customer
processors:
anyOf:
- type: object
properties:
vercel:
type: object
properties:
installation_id:
type: string
access_token:
type: string
account_id:
type: string
custom_payment_method_id:
type: string
required:
- installation_id
- access_token
- account_id
- type: "null"
description: External processors for the customer
send_email_receipts:
type: boolean
description: Whether to send email receipts to this customer
internal_options:
type: object
properties:
default_group:
type: string
description: The group of products to attach to the customer
disable_defaults:
type: boolean
description: Whether to disable default products
expand:
type: array
items:
$ref: "#/components/schemas/CustomerExpand"
description: Customer expand options
entity_id:
type: string
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
id:
anyOf:
- $ref: "#/components/schemas/CustomerId"
- type: "null"
with_autumn_id:
type: boolean
default: false
required:
- customer_id
title: GetOrCreateCustomerParams
examples:
- customer_id: cus_123
name: John Doe
email: john@example.com
responses:
"200":
description: OK
@@ -1029,21 +844,6 @@ paths:
schema:
type: object
properties:
entity_id:
anyOf:
- type: string
- type: "null"
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
options:
anyOf:
- type: array
@@ -1098,75 +898,6 @@ paths:
- type: string
- type: "null"
description: The feature ID of the product item. Should be null for fixed price items.
feature_type:
anyOf:
- enum:
- single_use
- continuous_use
- boolean
- static
- type: "null"
feature:
anyOf:
- type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like /track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
- type: "null"
included_usage:
anyOf:
- anyOf:
@@ -1238,80 +969,6 @@ paths:
- type: boolean
- type: "null"
description: Whether the usage should be reset when the product is enabled.
display:
anyOf:
- type: object
properties:
primary_text:
type: string
secondary_text:
anyOf:
- type: string
- type: "null"
required:
- primary_text
- type: "null"
usage_limit:
anyOf:
- type: number
- type: "null"
config:
anyOf:
- type: object
properties:
on_increase:
anyOf:
- enum:
- bill_immediately
- prorate_immediately
- prorate_next_cycle
- bill_next_cycle
- type: "null"
on_decrease:
anyOf:
- enum:
- prorate
- prorate_immediately
- prorate_next_cycle
- none
- no_prorations
- type: "null"
rollover:
anyOf:
- type: object
properties:
max:
anyOf:
- type: number
- type: "null"
duration:
enum:
- month
- forever
default: month
length:
type: number
required:
- max
- length
- type: "null"
- type: "null"
created_at:
anyOf:
- type: number
- type: "null"
entitlement_id:
anyOf:
- type: string
- type: "null"
price_id:
anyOf:
- type: string
- type: "null"
price_config:
anyOf:
- {}
- type: "null"
product_id:
type: string
invoice:
@@ -1352,8 +1009,6 @@ paths:
properties:
customer_id:
type: string
entity_id:
type: string
invoice:
type: object
properties:

View File

@@ -2,8 +2,8 @@ speakeasyVersion: 1.718.0
sources:
Autumn API:
sourceNamespace: autumn-api
sourceRevisionDigest: sha256:870cf5d97b4095695b870c563c519e87267e9b61c1c77e0702ba713ed5016249
sourceBlobDigest: sha256:d056cbb523f45acbfe06ad522417e87c888e233cb9d39800b0879a0f03715b15
sourceRevisionDigest: sha256:5e16ae7af44b95d164092bec91f923bb1ec7454116438f50f5cb3f18dfe3920f
sourceBlobDigest: sha256:0bcea56021f5f5820c80a29e9bd7fcfa9ea856f7fe8cf0a3ea3766b5b837aebe
tags:
- latest
- 2.1.0
@@ -11,10 +11,10 @@ targets:
autumn:
source: Autumn API
sourceNamespace: autumn-api
sourceRevisionDigest: sha256:870cf5d97b4095695b870c563c519e87267e9b61c1c77e0702ba713ed5016249
sourceBlobDigest: sha256:d056cbb523f45acbfe06ad522417e87c888e233cb9d39800b0879a0f03715b15
sourceRevisionDigest: sha256:5e16ae7af44b95d164092bec91f923bb1ec7454116438f50f5cb3f18dfe3920f
sourceBlobDigest: sha256:0bcea56021f5f5820c80a29e9bd7fcfa9ea856f7fe8cf0a3ea3766b5b837aebe
codeSamplesNamespace: autumn-api-typescript-code-samples
codeSamplesRevisionDigest: sha256:57f6c87bf54eebe3cc8972b4b752cc5c8acbb5579db5a72c62712c09a7535c4c
codeSamplesRevisionDigest: sha256:ce36f97d10345afb030ba1efd384c3bb8444afd11b275d20d04cd1f037fff6a2
workflow:
workflowVersion: 1.0.0
speakeasyVersion: latest

View File

@@ -31,7 +31,9 @@ const autumn = new AutumnCore({
async function run() {
const res = await customersGetOrCreate(autumn, {
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
if (res.ok) {
const { value: result } = res;

View File

@@ -95,7 +95,9 @@ const autumn = new Autumn({
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);
@@ -128,7 +130,9 @@ const autumn = new Autumn({
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);
@@ -226,7 +230,9 @@ const autumn = new Autumn({
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
}, {
retries: {
strategy: "backoff",
@@ -268,7 +274,9 @@ const autumn = new Autumn({
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);
@@ -305,7 +313,9 @@ const autumn = new Autumn({
async function run() {
try {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);
@@ -362,7 +372,9 @@ const autumn = new Autumn({
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);

View File

@@ -9,7 +9,9 @@ const autumn = new Autumn({
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);

View File

@@ -1,19 +0,0 @@
# AttachCreditSchema
## Example Usage
```typescript
import { AttachCreditSchema } from "@useautumn/sdk";
let value: AttachCreditSchema = {
meteredFeatureId: "<id>",
creditCost: 3433.52,
};
```
## Fields
| Field | Type | Required | Description |
| --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- |
| `meteredFeatureId` | *string* | :heavy_check_mark: | The ID of the metered feature (should be a single_use feature). |
| `creditCost` | *number* | :heavy_check_mark: | The credit cost of the metered feature. |

View File

@@ -1,18 +0,0 @@
# AttachDisplay
## Example Usage
```typescript
import { AttachDisplay } from "@useautumn/sdk";
let value: AttachDisplay = {
primaryText: "<value>",
};
```
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `primaryText` | *string* | :heavy_check_mark: | N/A |
| `secondaryText` | *string* | :heavy_minus_sign: | N/A |

View File

@@ -1,18 +0,0 @@
# AttachEntityData
## Example Usage
```typescript
import { AttachEntityData } from "@useautumn/sdk";
let value: AttachEntityData = {
featureId: "<id>",
};
```
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- |
| `featureId` | *string* | :heavy_check_mark: | The feature ID that this entity is associated with |
| `name` | *string* | :heavy_minus_sign: | Name of the entity |

View File

@@ -1,19 +0,0 @@
# AttachFeatureDisplay
## Example Usage
```typescript
import { AttachFeatureDisplay } from "@useautumn/sdk";
let value: AttachFeatureDisplay = {
singular: "<value>",
plural: "<value>",
};
```
## Fields
| Field | Type | Required | Description |
| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
| `singular` | *string* | :heavy_check_mark: | The singular display name for the feature. |
| `plural` | *string* | :heavy_check_mark: | The plural display name for the feature. |

View File

@@ -1,17 +0,0 @@
# AttachFeatureType
The type of the feature
## Example Usage
```typescript
import { AttachFeatureType } from "@useautumn/sdk";
let value: AttachFeatureType = "boolean";
```
## Values
```typescript
"static" | "boolean" | "single_use" | "continuous_use" | "credit_system"
```

View File

@@ -1,23 +0,0 @@
# AttachFeature
## Example Usage
```typescript
import { AttachFeature } from "@useautumn/sdk";
let value: AttachFeature = {
id: "<id>",
type: "single_use",
};
```
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| `id` | *string* | :heavy_check_mark: | The ID of the feature, used to refer to it in other API calls like /track or /check. |
| `name` | *string* | :heavy_minus_sign: | The name of the feature. |
| `type` | [models.AttachFeatureType](../models/attach-feature-type.md) | :heavy_check_mark: | The type of the feature |
| `display` | [models.AttachFeatureDisplay](../models/attach-feature-display.md) | :heavy_minus_sign: | Singular and plural display names for the feature. |
| `creditSchema` | [models.AttachCreditSchema](../models/attach-credit-schema.md)[] | :heavy_minus_sign: | Credit cost schema for credit system features. |
| `archived` | *boolean* | :heavy_minus_sign: | Whether or not the feature is archived. |

View File

@@ -14,7 +14,7 @@ let value: AttachFreeTrial = {
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | ---------------------------------------- |
| `length` | *number* | :heavy_check_mark: | N/A |
| `duration` | [models.FreeTrialDuration](../models/free-trial-duration.md) | :heavy_check_mark: | N/A |
| `duration` | [models.Duration](../models/duration.md) | :heavy_check_mark: | N/A |
| `cardRequired` | *boolean* | :heavy_minus_sign: | N/A |

View File

@@ -14,8 +14,6 @@ let value: AttachItem = {};
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | [models.AttachType](../models/attach-type.md) | :heavy_minus_sign: | The type of the product item. |
| `featureId` | *string* | :heavy_minus_sign: | The feature ID of the product item. Should be null for fixed price items. |
| `featureType` | [models.FeatureType](../models/feature-type.md) | :heavy_minus_sign: | N/A |
| `feature` | [models.AttachFeature](../models/attach-feature.md) | :heavy_minus_sign: | N/A |
| `includedUsage` | *models.IncludedUsage* | :heavy_minus_sign: | The amount of usage included for this feature (per interval). |
| `interval` | [models.AttachInterval](../models/attach-interval.md) | :heavy_minus_sign: | The reset or billing interval of the product item. If null, feature will have no reset date, and if there's a price, it will be billed one-off. |
| `intervalCount` | *number* | :heavy_minus_sign: | Interval count of the feature. |
@@ -25,10 +23,3 @@ let value: AttachItem = {};
| `tiers` | [models.Tiers](../models/tiers.md)[] | :heavy_minus_sign: | Tiered pricing for the product item. Not applicable for fixed price items. |
| `billingUnits` | *number* | :heavy_minus_sign: | The billing units of the product item (eg $1 for 30 credits). |
| `resetUsageWhenEnabled` | *boolean* | :heavy_minus_sign: | Whether the usage should be reset when the product is enabled. |
| `display` | [models.AttachDisplay](../models/attach-display.md) | :heavy_minus_sign: | N/A |
| `usageLimit` | *number* | :heavy_minus_sign: | N/A |
| `config` | [models.Config](../models/config.md) | :heavy_minus_sign: | N/A |
| `createdAt` | *number* | :heavy_minus_sign: | N/A |
| `entitlementId` | *string* | :heavy_minus_sign: | N/A |
| `priceId` | *string* | :heavy_minus_sign: | N/A |
| `priceConfig` | *any* | :heavy_minus_sign: | N/A |

View File

@@ -1,15 +0,0 @@
# AttachOnDecrease
## Example Usage
```typescript
import { AttachOnDecrease } from "@useautumn/sdk";
let value: AttachOnDecrease = "prorate_next_cycle";
```
## Values
```typescript
"prorate" | "prorate_immediately" | "prorate_next_cycle" | "none" | "no_prorations"
```

View File

@@ -1,15 +0,0 @@
# AttachOnIncrease
## Example Usage
```typescript
import { AttachOnIncrease } from "@useautumn/sdk";
let value: AttachOnIncrease = "prorate_next_cycle";
```
## Values
```typescript
"bill_immediately" | "prorate_immediately" | "prorate_next_cycle" | "bill_next_cycle"
```

View File

@@ -13,9 +13,7 @@ let value: AttachRequest = {
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| `entityId` | *string* | :heavy_minus_sign: | N/A |
| `entityData` | [models.AttachEntityData](../models/attach-entity-data.md) | :heavy_minus_sign: | N/A |
| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- |
| `options` | [models.Options](../models/options.md)[] | :heavy_minus_sign: | N/A |
| `version` | *number* | :heavy_minus_sign: | N/A |
| `freeTrial` | [models.AttachFreeTrial](../models/attach-free-trial.md) | :heavy_minus_sign: | N/A |

View File

@@ -18,7 +18,6 @@ let value: AttachResponse = {
| Field | Type | Required | Description |
| ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------- |
| `customerId` | *string* | :heavy_check_mark: | N/A |
| `entityId` | *string* | :heavy_minus_sign: | N/A |
| `invoice` | [models.AttachInvoice](../models/attach-invoice.md) | :heavy_minus_sign: | N/A |
| `paymentUrl` | *string* | :heavy_check_mark: | N/A |
| `requiredAction` | [models.RequiredAction](../models/required-action.md) | :heavy_minus_sign: | N/A |

View File

@@ -1,20 +0,0 @@
# AttachRollover
## Example Usage
```typescript
import { AttachRollover } from "@useautumn/sdk";
let value: AttachRollover = {
max: 2750.92,
length: 3617.46,
};
```
## Fields
| Field | Type | Required | Description |
| --------------------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------- |
| `max` | *number* | :heavy_check_mark: | N/A |
| `duration` | [models.RolloverDuration](../models/rollover-duration.md) | :heavy_minus_sign: | N/A |
| `length` | *number* | :heavy_check_mark: | N/A |

View File

@@ -1,17 +0,0 @@
# BalancesType
## Example Usage
```typescript
import { BalancesType } from "@useautumn/sdk";
let value: BalancesType = "boolean";
```
## Values
This is an open enum. Unrecognized values will be captured as the `Unrecognized<string>` branded type.
```typescript
"boolean" | "metered" | "credit_system" | Unrecognized<string>
```

View File

@@ -22,7 +22,6 @@ let value: Balances = {
| Field | Type | Required | Description |
| ----------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- |
| `featureId` | *string* | :heavy_check_mark: | N/A |
| `feature` | [models.CustomerFeature](../models/customer-feature.md) | :heavy_minus_sign: | N/A |
| `granted` | *number* | :heavy_check_mark: | N/A |
| `remaining` | *number* | :heavy_check_mark: | N/A |
| `usage` | *number* | :heavy_check_mark: | N/A |

View File

@@ -29,7 +29,6 @@ let value: Breakdown = {
| Field | Type | Required | Description |
| --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- | --------------------------------------------------- |
| `id` | *string* | :heavy_minus_sign: | N/A |
| `planId` | *string* | :heavy_check_mark: | N/A |
| `includedGrant` | *number* | :heavy_check_mark: | N/A |
| `prepaidGrant` | *number* | :heavy_check_mark: | N/A |

View File

@@ -1,17 +0,0 @@
# Config
## Example Usage
```typescript
import { Config } from "@useautumn/sdk";
let value: Config = {};
```
## Fields
| Field | Type | Required | Description |
| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- |
| `onIncrease` | [models.AttachOnIncrease](../models/attach-on-increase.md) | :heavy_minus_sign: | N/A |
| `onDecrease` | [models.AttachOnDecrease](../models/attach-on-decrease.md) | :heavy_minus_sign: | N/A |
| `rollover` | [models.AttachRollover](../models/attach-rollover.md) | :heavy_minus_sign: | N/A |

View File

@@ -1,19 +0,0 @@
# CustomerCreditSchema
## Example Usage
```typescript
import { CustomerCreditSchema } from "@useautumn/sdk";
let value: CustomerCreditSchema = {
meteredFeatureId: "<id>",
creditCost: 4.76,
};
```
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `meteredFeatureId` | *string* | :heavy_check_mark: | N/A |
| `creditCost` | *number* | :heavy_check_mark: | N/A |

View File

@@ -1,16 +0,0 @@
# CustomerDisplay
## Example Usage
```typescript
import { CustomerDisplay } from "@useautumn/sdk";
let value: CustomerDisplay = {};
```
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `singular` | *string* | :heavy_minus_sign: | N/A |
| `plural` | *string* | :heavy_minus_sign: | N/A |

View File

@@ -1,5 +1,7 @@
# CustomerEnv
The environment this customer was created in.
## Example Usage
```typescript

View File

@@ -1,28 +0,0 @@
# CustomerFeature
## Example Usage
```typescript
import { CustomerFeature } from "@useautumn/sdk";
let value: CustomerFeature = {
id: "<id>",
name: "<value>",
type: "metered",
consumable: false,
archived: true,
};
```
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `id` | *string* | :heavy_check_mark: | N/A |
| `name` | *string* | :heavy_check_mark: | N/A |
| `type` | [models.BalancesType](../models/balances-type.md) | :heavy_check_mark: | N/A |
| `consumable` | *boolean* | :heavy_check_mark: | N/A |
| `eventNames` | *string*[] | :heavy_minus_sign: | N/A |
| `creditSchema` | [models.CustomerCreditSchema](../models/customer-credit-schema.md)[] | :heavy_minus_sign: | N/A |
| `display` | [models.CustomerDisplay](../models/customer-display.md) | :heavy_minus_sign: | N/A |
| `archived` | *boolean* | :heavy_check_mark: | N/A |

View File

@@ -6,46 +6,40 @@
import { Customer } from "@useautumn/sdk";
let value: Customer = {
id: "<id>",
name: null,
email: "Kevin73@hotmail.com",
createdAt: 9956.34,
fingerprint: "<value>",
stripeId: "<id>",
env: "live",
metadata: {
"key": "<value>",
"key1": "<value>",
"key2": "<value>",
},
name: "John Doe",
email: "john@example.com",
fingerprint: "1234567890",
stripeId: "cus_123",
env: "sandbox",
metadata: {},
sendEmailReceipts: false,
subscriptions: [
{
planId: "<id>",
autoEnable: false,
addOn: true,
status: "expired",
pastDue: true,
canceledAt: null,
expiresAt: 1710.61,
trialEndsAt: 8042.54,
startedAt: 72.25,
currentPeriodStart: 8651.43,
currentPeriodEnd: 7213.89,
quantity: 3438,
planId: "plan_123",
autoEnable: true,
addOn: false,
status: "active",
pastDue: false,
canceledAt: 9016.07,
expiresAt: 7919.45,
trialEndsAt: 9802.8,
startedAt: 9956.34,
currentPeriodStart: 4924.95,
currentPeriodEnd: 7855.7,
quantity: 1,
},
],
purchases: [],
balances: {
"key": {
"balance_1": {
featureId: "<id>",
granted: 3195.9,
remaining: 3289.89,
usage: 4599.27,
unlimited: false,
granted: 7438.76,
remaining: 7441.15,
usage: 5903.02,
unlimited: true,
overageAllowed: false,
maxPurchase: 1182.05,
nextResetAt: 5644.6,
maxPurchase: 934.85,
nextResetAt: 1710.61,
},
},
};
@@ -54,17 +48,14 @@ let value: Customer = {
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- |
| `autumnId` | *string* | :heavy_minus_sign: | N/A |
| `id` | *string* | :heavy_check_mark: | N/A |
| `name` | *string* | :heavy_check_mark: | N/A |
| `email` | *string* | :heavy_check_mark: | N/A |
| `createdAt` | *number* | :heavy_check_mark: | N/A |
| `fingerprint` | *string* | :heavy_check_mark: | N/A |
| `stripeId` | *string* | :heavy_check_mark: | N/A |
| `env` | [models.CustomerEnv](../models/customer-env.md) | :heavy_check_mark: | N/A |
| `metadata` | Record<string, *any*> | :heavy_check_mark: | N/A |
| `sendEmailReceipts` | *boolean* | :heavy_check_mark: | N/A |
| --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `name` | *string* | :heavy_check_mark: | The name of the customer. |
| `email` | *string* | :heavy_check_mark: | The email address of the customer. |
| `fingerprint` | *string* | :heavy_check_mark: | A unique identifier (eg. serial number) to de-duplicate customers across devices or browsers. For example: apple device ID. |
| `stripeId` | *string* | :heavy_check_mark: | Stripe customer ID. |
| `env` | [models.CustomerEnv](../models/customer-env.md) | :heavy_check_mark: | The environment this customer was created in. |
| `metadata` | Record<string, *any*> | :heavy_check_mark: | The metadata for the customer. |
| `sendEmailReceipts` | *boolean* | :heavy_check_mark: | Whether to send email receipts to the customer. |
| `subscriptions` | [models.Subscription](../models/subscription.md)[] | :heavy_check_mark: | N/A |
| `purchases` | [models.Purchase](../models/purchase.md)[] | :heavy_check_mark: | N/A |
| `balances` | Record<string, [models.Balances](../models/balances.md)> | :heavy_check_mark: | N/A |

View File

@@ -6,7 +6,6 @@
import { Discount } from "@useautumn/sdk";
let value: Discount = {
id: "<id>",
name: "<value>",
type: "free_product",
discountValue: 8208.57,
@@ -18,9 +17,8 @@ let value: Discount = {
| Field | Type | Required | Description |
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| `id` | *string* | :heavy_check_mark: | The unique identifier for this discount |
| `name` | *string* | :heavy_check_mark: | The name of the discount or coupon |
| `type` | [models.RewardsType](../models/rewards-type.md) | :heavy_check_mark: | The type of reward |
| `type` | [models.Type](../models/type.md) | :heavy_check_mark: | The type of reward |
| `discountValue` | *number* | :heavy_check_mark: | The discount value (percentage or fixed amount) |
| `durationType` | [models.CustomerDurationType](../models/customer-duration-type.md) | :heavy_check_mark: | How long the discount lasts |
| `durationValue` | *number* | :heavy_minus_sign: | Number of billing periods the discount applies for repeating durations |

View File

@@ -0,0 +1,15 @@
# Duration
## Example Usage
```typescript
import { Duration } from "@useautumn/sdk";
let value: Duration = "year";
```
## Values
```typescript
"day" | "month" | "year"
```

View File

@@ -6,9 +6,7 @@
import { Entity } from "@useautumn/sdk";
let value: Entity = {
id: "<id>",
name: "<value>",
createdAt: 4436.47,
env: "sandbox",
};
```
@@ -17,10 +15,7 @@ let value: Entity = {
| Field | Type | Required | Description |
| ------------------------------------------- | ------------------------------------------- | ------------------------------------------- | ------------------------------------------- |
| `autumnId` | *string* | :heavy_minus_sign: | N/A |
| `id` | *string* | :heavy_check_mark: | The unique identifier of the entity |
| `name` | *string* | :heavy_check_mark: | The name of the entity |
| `customerId` | *string* | :heavy_minus_sign: | The customer ID this entity belongs to |
| `featureId` | *string* | :heavy_minus_sign: | The feature ID this entity belongs to |
| `createdAt` | *number* | :heavy_check_mark: | Unix timestamp when the entity was created |
| `env` | [models.EntityEnv](../models/entity-env.md) | :heavy_check_mark: | The environment (sandbox/live) |

View File

@@ -1,15 +0,0 @@
# FeatureType
## Example Usage
```typescript
import { FeatureType } from "@useautumn/sdk";
let value: FeatureType = "continuous_use";
```
## Values
```typescript
"single_use" | "continuous_use" | "boolean" | "static"
```

View File

@@ -1,15 +0,0 @@
# FreeTrialDuration
## Example Usage
```typescript
import { FreeTrialDuration } from "@useautumn/sdk";
let value: FreeTrialDuration = "month";
```
## Values
```typescript
"day" | "month" | "year"
```

View File

@@ -6,7 +6,9 @@
import { GetOrCreateCustomerParams } from "@useautumn/sdk";
let value: GetOrCreateCustomerParams = {
customerId: "<id>",
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
};
```
@@ -22,11 +24,5 @@ let value: GetOrCreateCustomerParams = {
| `stripeId` | *string* | :heavy_minus_sign: | Stripe customer ID if you already have one |
| `createInStripe` | *boolean* | :heavy_minus_sign: | Whether to create the customer in Stripe |
| `autoEnablePlanId` | *string* | :heavy_minus_sign: | The ID of the free plan to auto-enable for the customer |
| `processors` | [models.Processors](../models/processors.md) | :heavy_minus_sign: | External processors for the customer |
| `sendEmailReceipts` | *boolean* | :heavy_minus_sign: | Whether to send email receipts to this customer |
| `internalOptions` | [models.InternalOptions](../models/internal-options.md) | :heavy_minus_sign: | N/A |
| `expand` | [models.CustomerExpand](../models/customer-expand.md)[] | :heavy_minus_sign: | Customer expand options |
| `entityId` | *string* | :heavy_minus_sign: | N/A |
| `entityData` | [models.GetOrCreateEntityData](../models/get-or-create-entity-data.md) | :heavy_minus_sign: | N/A |
| `id` | *string* | :heavy_minus_sign: | N/A |
| `withAutumnId` | *boolean* | :heavy_minus_sign: | N/A |

View File

@@ -1,18 +0,0 @@
# GetOrCreateEntityData
## Example Usage
```typescript
import { GetOrCreateEntityData } from "@useautumn/sdk";
let value: GetOrCreateEntityData = {
featureId: "<id>",
};
```
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------- |
| `featureId` | *string* | :heavy_check_mark: | The feature ID that this entity is associated with |
| `name` | *string* | :heavy_minus_sign: | Name of the entity |

View File

@@ -1,16 +0,0 @@
# InternalOptions
## Example Usage
```typescript
import { InternalOptions } from "@useautumn/sdk";
let value: InternalOptions = {};
```
## Fields
| Field | Type | Required | Description |
| ----------------------------------------------- | ----------------------------------------------- | ----------------------------------------------- | ----------------------------------------------- |
| `defaultGroup` | *string* | :heavy_minus_sign: | The group of products to attach to the customer |
| `disableDefaults` | *boolean* | :heavy_minus_sign: | Whether to disable default products |

View File

@@ -11,7 +11,6 @@ let value: Invoice = {
status: "<value>",
total: 9115.15,
currency: "New Zealand Dollar",
createdAt: 1973.3,
};
```
@@ -24,5 +23,4 @@ let value: Invoice = {
| `status` | *string* | :heavy_check_mark: | The status of the invoice |
| `total` | *number* | :heavy_check_mark: | The total amount of the invoice |
| `currency` | *string* | :heavy_check_mark: | The currency code for the invoice |
| `createdAt` | *number* | :heavy_check_mark: | Timestamp when the invoice was created |
| `hostedInvoiceUrl` | *string* | :heavy_minus_sign: | URL to the Stripe-hosted invoice page |

View File

@@ -24,13 +24,11 @@ let value: Item = {
## Fields
| Field | Type | Required | Description |
| -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- | -------------------------------------------------------- |
| ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------- |
| `featureId` | *string* | :heavy_check_mark: | N/A |
| `feature` | [models.PlanFeature](../models/plan-feature.md) | :heavy_minus_sign: | N/A |
| `included` | *number* | :heavy_check_mark: | N/A |
| `unlimited` | *boolean* | :heavy_check_mark: | N/A |
| `reset` | [models.PlanReset](../models/plan-reset.md) | :heavy_check_mark: | N/A |
| `price` | [models.ItemPrice](../models/item-price.md) | :heavy_check_mark: | N/A |
| `display` | [models.PlanItemDisplay](../models/plan-item-display.md) | :heavy_minus_sign: | N/A |
| `rollover` | [models.PlanRollover](../models/plan-rollover.md) | :heavy_minus_sign: | N/A |
| `proration` | [models.Proration](../models/proration.md) | :heavy_minus_sign: | N/A |

View File

@@ -1,19 +0,0 @@
# PlanCreditSchema
## Example Usage
```typescript
import { PlanCreditSchema } from "@useautumn/sdk";
let value: PlanCreditSchema = {
meteredFeatureId: "<id>",
creditCost: 2845.35,
};
```
## Fields
| Field | Type | Required | Description |
| --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- |
| `meteredFeatureId` | *string* | :heavy_check_mark: | The ID of the metered feature (should be a single_use feature). |
| `creditCost` | *number* | :heavy_check_mark: | The credit cost of the metered feature. |

View File

@@ -1,19 +0,0 @@
# PlanFeatureDisplay
## Example Usage
```typescript
import { PlanFeatureDisplay } from "@useautumn/sdk";
let value: PlanFeatureDisplay = {
singular: "<value>",
plural: "<value>",
};
```
## Fields
| Field | Type | Required | Description |
| ------------------------------------------ | ------------------------------------------ | ------------------------------------------ | ------------------------------------------ |
| `singular` | *string* | :heavy_check_mark: | The singular display name for the feature. |
| `plural` | *string* | :heavy_check_mark: | The plural display name for the feature. |

View File

@@ -1,23 +0,0 @@
# PlanFeature
## Example Usage
```typescript
import { PlanFeature } from "@useautumn/sdk";
let value: PlanFeature = {
id: "<id>",
type: "boolean",
};
```
## Fields
| Field | Type | Required | Description |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| `id` | *string* | :heavy_check_mark: | The ID of the feature, used to refer to it in other API calls like /track or /check. |
| `name` | *string* | :heavy_minus_sign: | The name of the feature. |
| `type` | [models.PlanType](../models/plan-type.md) | :heavy_check_mark: | The type of the feature |
| `display` | [models.PlanFeatureDisplay](../models/plan-feature-display.md) | :heavy_minus_sign: | Singular and plural display names for the feature. |
| `creditSchema` | [models.PlanCreditSchema](../models/plan-credit-schema.md)[] | :heavy_minus_sign: | Credit cost schema for credit system features. |
| `archived` | *boolean* | :heavy_minus_sign: | Whether or not the feature is archived. |

View File

@@ -1,18 +0,0 @@
# PlanItemDisplay
## Example Usage
```typescript
import { PlanItemDisplay } from "@useautumn/sdk";
let value: PlanItemDisplay = {
primaryText: "<value>",
};
```
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `primaryText` | *string* | :heavy_check_mark: | N/A |
| `secondaryText` | *string* | :heavy_minus_sign: | N/A |

View File

@@ -18,4 +18,3 @@ let value: PlanPrice = {
| `amount` | *number* | :heavy_check_mark: | N/A |
| `interval` | [models.PriceInterval](../models/price-interval.md) | :heavy_check_mark: | N/A |
| `intervalCount` | *number* | :heavy_minus_sign: | N/A |
| `display` | [models.PriceDisplay](../models/price-display.md) | :heavy_minus_sign: | N/A |

View File

@@ -1,19 +0,0 @@
# PlanType
The type of the feature
## Example Usage
```typescript
import { PlanType } from "@useautumn/sdk";
let value: PlanType = "static";
```
## Values
This is an open enum. Unrecognized values will be captured as the `Unrecognized<string>` branded type.
```typescript
"static" | "boolean" | "single_use" | "continuous_use" | "credit_system" | Unrecognized<string>
```

View File

@@ -6,7 +6,6 @@
import { Plan } from "@useautumn/sdk";
let value: Plan = {
id: "<id>",
name: "<value>",
description:
"deplore incomparable among because tired diligently pillow tenant pro mmm",
@@ -19,8 +18,7 @@ let value: Plan = {
interval: "one_off",
},
items: [],
createdAt: 3920.84,
env: "live",
env: "sandbox",
archived: false,
baseVariantId: "<id>",
};
@@ -30,7 +28,6 @@ let value: Plan = {
| Field | Type | Required | Description |
| --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------- |
| `id` | *string* | :heavy_check_mark: | N/A |
| `name` | *string* | :heavy_check_mark: | N/A |
| `description` | *string* | :heavy_check_mark: | N/A |
| `group` | *string* | :heavy_check_mark: | N/A |
@@ -40,7 +37,6 @@ let value: Plan = {
| `price` | [models.PlanPrice](../models/plan-price.md) | :heavy_check_mark: | N/A |
| `items` | [models.Item](../models/item.md)[] | :heavy_check_mark: | N/A |
| `freeTrial` | [models.FreeTrial](../models/free-trial.md) | :heavy_minus_sign: | N/A |
| `createdAt` | *number* | :heavy_check_mark: | N/A |
| `env` | [models.PlanEnv](../models/plan-env.md) | :heavy_check_mark: | N/A |
| `archived` | *boolean* | :heavy_check_mark: | N/A |
| `baseVariantId` | *string* | :heavy_check_mark: | N/A |

View File

@@ -1,18 +0,0 @@
# PriceDisplay
## Example Usage
```typescript
import { PriceDisplay } from "@useautumn/sdk";
let value: PriceDisplay = {
primaryText: "<value>",
};
```
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `primaryText` | *string* | :heavy_check_mark: | N/A |
| `secondaryText` | *string* | :heavy_minus_sign: | N/A |

View File

@@ -1,15 +0,0 @@
# Processors
## Example Usage
```typescript
import { Processors } from "@useautumn/sdk";
let value: Processors = {};
```
## Fields
| Field | Type | Required | Description |
| ------------------------------------ | ------------------------------------ | ------------------------------------ | ------------------------------------ |
| `vercel` | [models.Vercel](../models/vercel.md) | :heavy_minus_sign: | N/A |

View File

@@ -5,15 +5,12 @@
```typescript
import { ReferralCustomer } from "@useautumn/sdk";
let value: ReferralCustomer = {
id: "<id>",
};
let value: ReferralCustomer = {};
```
## Fields
| Field | Type | Required | Description |
| ------------------ | ------------------ | ------------------ | ------------------ |
| `id` | *string* | :heavy_check_mark: | N/A |
| `name` | *string* | :heavy_minus_sign: | N/A |
| `email` | *string* | :heavy_minus_sign: | N/A |

View File

@@ -7,11 +7,8 @@ import { Referral } from "@useautumn/sdk";
let value: Referral = {
programId: "<id>",
customer: {
id: "<id>",
},
customer: {},
rewardApplied: false,
createdAt: 6538.56,
};
```
@@ -22,4 +19,3 @@ let value: Referral = {
| `programId` | *string* | :heavy_check_mark: | N/A |
| `customer` | [models.ReferralCustomer](../models/referral-customer.md) | :heavy_check_mark: | N/A |
| `rewardApplied` | *boolean* | :heavy_check_mark: | N/A |
| `createdAt` | *number* | :heavy_check_mark: | N/A |

View File

@@ -8,7 +8,6 @@ import { Rewards } from "@useautumn/sdk";
let value: Rewards = {
discounts: [
{
id: "<id>",
name: "<value>",
type: "invoice_credits",
discountValue: 8349.54,

View File

@@ -1,15 +0,0 @@
# RolloverDuration
## Example Usage
```typescript
import { RolloverDuration } from "@useautumn/sdk";
let value: RolloverDuration = "forever";
```
## Values
```typescript
"month" | "forever"
```

View File

@@ -1,13 +1,13 @@
# RewardsType
# Type
The type of reward
## Example Usage
```typescript
import { RewardsType } from "@useautumn/sdk";
import { Type } from "@useautumn/sdk";
let value: RewardsType = "free_product";
let value: Type = "percentage_discount";
```
## Values

View File

@@ -1,22 +0,0 @@
# Vercel
## Example Usage
```typescript
import { Vercel } from "@useautumn/sdk";
let value: Vercel = {
installationId: "<id>",
accessToken: "<value>",
accountId: "<id>",
};
```
## Fields
| Field | Type | Required | Description |
| ----------------------- | ----------------------- | ----------------------- | ----------------------- |
| `installationId` | *string* | :heavy_check_mark: | N/A |
| `accessToken` | *string* | :heavy_check_mark: | N/A |
| `accountId` | *string* | :heavy_check_mark: | N/A |
| `customPaymentMethodId` | *string* | :heavy_minus_sign: | N/A |

View File

@@ -51,7 +51,9 @@ const autumn = new Autumn({
async function run() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);
@@ -77,7 +79,9 @@ const autumn = new AutumnCore({
async function run() {
const res = await customersGetOrCreate(autumn, {
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
if (res.ok) {
const { value: result } = res;

View File

@@ -20,7 +20,9 @@ const autumn = new Autumn({
async function main() {
const result = await autumn.customers.getOrCreate({
customerId: null,
customerId: "cus_123",
name: "John Doe",
email: "john@example.com",
});
console.log(result);

View File

@@ -2,7 +2,7 @@
{
"name": "@useautumn/sdk",
"version": "0.7.20",
"version": "0.7.42",
"exports": {
".": "./src/index.ts",
"./models": "./src/models/index.ts",

View File

@@ -1,6 +1,6 @@
{
"name": "@useautumn/sdk",
"version": "0.7.20",
"version": "0.7.42",
"author": "Speakeasy",
"main": "./dist/commonjs/index.js",
"module": "./dist/esm/index.js",

View File

@@ -66,7 +66,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
export const SDK_METADATA = {
language: "typescript",
openapiDocVersion: "2.1.0",
sdkVersion: "0.7.20",
sdkVersion: "0.7.42",
genVersion: "2.824.1",
userAgent: "speakeasy-sdk/typescript 0.7.20 2.824.1 2.1.0 @useautumn/sdk",
userAgent: "speakeasy-sdk/typescript 0.7.42 2.824.1 2.1.0 @useautumn/sdk",
} as const;

View File

@@ -16,33 +16,22 @@ export type AttachGlobals = {
xApiVersion?: string | undefined;
};
export type AttachEntityData = {
/**
* The feature ID that this entity is associated with
*/
featureId: string;
/**
* Name of the entity
*/
name?: string | undefined;
};
export type Options = {
featureId: string;
quantity?: number | undefined;
resetAfterTrialEnd?: boolean | undefined;
};
export const FreeTrialDuration = {
export const Duration = {
Day: "day",
Month: "month",
Year: "year",
} as const;
export type FreeTrialDuration = ClosedEnum<typeof FreeTrialDuration>;
export type Duration = ClosedEnum<typeof Duration>;
export type AttachFreeTrial = {
length: number;
duration: FreeTrialDuration;
duration: Duration;
cardRequired?: boolean | undefined;
};
@@ -53,78 +42,6 @@ export const AttachType = {
} as const;
export type AttachType = ClosedEnum<typeof AttachType>;
export const FeatureType = {
SingleUse: "single_use",
ContinuousUse: "continuous_use",
Boolean: "boolean",
Static: "static",
} as const;
export type FeatureType = ClosedEnum<typeof FeatureType>;
/**
* The type of the feature
*/
export const AttachFeatureType = {
Static: "static",
Boolean: "boolean",
SingleUse: "single_use",
ContinuousUse: "continuous_use",
CreditSystem: "credit_system",
} as const;
/**
* The type of the feature
*/
export type AttachFeatureType = ClosedEnum<typeof AttachFeatureType>;
export type AttachFeatureDisplay = {
/**
* The singular display name for the feature.
*/
singular: string;
/**
* The plural display name for the feature.
*/
plural: string;
};
export type AttachCreditSchema = {
/**
* The ID of the metered feature (should be a single_use feature).
*/
meteredFeatureId: string;
/**
* The credit cost of the metered feature.
*/
creditCost: number;
};
export type AttachFeature = {
/**
* The ID of the feature, used to refer to it in other API calls like /track or /check.
*/
id: string;
/**
* The name of the feature.
*/
name?: string | null | undefined;
/**
* The type of the feature
*/
type: AttachFeatureType;
/**
* Singular and plural display names for the feature.
*/
display?: AttachFeatureDisplay | null | undefined;
/**
* Credit cost schema for credit system features.
*/
creditSchema?: Array<AttachCreditSchema> | null | undefined;
/**
* Whether or not the feature is archived.
*/
archived?: boolean | null | undefined;
};
export type IncludedUsage = number | string;
export const AttachInterval = {
@@ -161,46 +78,6 @@ export type Tiers = {
amount: number;
};
export type AttachDisplay = {
primaryText: string;
secondaryText?: string | null | undefined;
};
export const AttachOnIncrease = {
BillImmediately: "bill_immediately",
ProrateImmediately: "prorate_immediately",
ProrateNextCycle: "prorate_next_cycle",
BillNextCycle: "bill_next_cycle",
} as const;
export type AttachOnIncrease = ClosedEnum<typeof AttachOnIncrease>;
export const AttachOnDecrease = {
Prorate: "prorate",
ProrateImmediately: "prorate_immediately",
ProrateNextCycle: "prorate_next_cycle",
None: "none",
NoProrations: "no_prorations",
} as const;
export type AttachOnDecrease = ClosedEnum<typeof AttachOnDecrease>;
export const RolloverDuration = {
Month: "month",
Forever: "forever",
} as const;
export type RolloverDuration = ClosedEnum<typeof RolloverDuration>;
export type AttachRollover = {
max: number | null;
duration?: RolloverDuration | undefined;
length: number;
};
export type Config = {
onIncrease?: AttachOnIncrease | null | undefined;
onDecrease?: AttachOnDecrease | null | undefined;
rollover?: AttachRollover | null | undefined;
};
export type AttachItem = {
/**
* The type of the product item.
@@ -210,8 +87,6 @@ export type AttachItem = {
* The feature ID of the product item. Should be null for fixed price items.
*/
featureId?: string | null | undefined;
featureType?: FeatureType | null | undefined;
feature?: AttachFeature | null | undefined;
/**
* The amount of usage included for this feature (per interval).
*/
@@ -248,13 +123,6 @@ export type AttachItem = {
* Whether the usage should be reset when the product is enabled.
*/
resetUsageWhenEnabled?: boolean | null | undefined;
display?: AttachDisplay | null | undefined;
usageLimit?: number | null | undefined;
config?: Config | null | undefined;
createdAt?: number | null | undefined;
entitlementId?: string | null | undefined;
priceId?: string | null | undefined;
priceConfig?: any | null | undefined;
};
export const RedirectMode = {
@@ -277,8 +145,6 @@ export const BillingBehavior = {
export type BillingBehavior = ClosedEnum<typeof BillingBehavior>;
export type AttachRequest = {
entityId?: string | null | undefined;
entityData?: AttachEntityData | undefined;
options?: Array<Options> | null | undefined;
version?: number | undefined;
freeTrial?: AttachFreeTrial | null | undefined;
@@ -320,42 +186,11 @@ export type RequiredAction = {
*/
export type AttachResponse = {
customerId: string;
entityId?: string | undefined;
invoice?: AttachInvoice | undefined;
paymentUrl: string | null;
requiredAction?: RequiredAction | undefined;
};
/** @internal */
export type AttachEntityData$Outbound = {
feature_id: string;
name?: string | undefined;
};
/** @internal */
export const AttachEntityData$outboundSchema: z.ZodMiniType<
AttachEntityData$Outbound,
AttachEntityData
> = z.pipe(
z.object({
featureId: z.string(),
name: z.optional(z.string()),
}),
z.transform((v) => {
return remap$(v, {
featureId: "feature_id",
});
}),
);
export function attachEntityDataToJSON(
attachEntityData: AttachEntityData,
): string {
return JSON.stringify(
AttachEntityData$outboundSchema.parse(attachEntityData),
);
}
/** @internal */
export type Options$Outbound = {
feature_id: string;
@@ -384,9 +219,9 @@ export function optionsToJSON(options: Options): string {
}
/** @internal */
export const FreeTrialDuration$outboundSchema: z.ZodMiniEnum<
typeof FreeTrialDuration
> = z.enum(FreeTrialDuration);
export const Duration$outboundSchema: z.ZodMiniEnum<typeof Duration> = z.enum(
Duration,
);
/** @internal */
export type AttachFreeTrial$Outbound = {
@@ -402,7 +237,7 @@ export const AttachFreeTrial$outboundSchema: z.ZodMiniType<
> = z.pipe(
z.object({
length: z.number(),
duration: FreeTrialDuration$outboundSchema,
duration: Duration$outboundSchema,
cardRequired: z._default(z.boolean(), true),
}),
z.transform((v) => {
@@ -422,107 +257,6 @@ export function attachFreeTrialToJSON(
export const AttachType$outboundSchema: z.ZodMiniEnum<typeof AttachType> = z
.enum(AttachType);
/** @internal */
export const FeatureType$outboundSchema: z.ZodMiniEnum<typeof FeatureType> = z
.enum(FeatureType);
/** @internal */
export const AttachFeatureType$outboundSchema: z.ZodMiniEnum<
typeof AttachFeatureType
> = z.enum(AttachFeatureType);
/** @internal */
export type AttachFeatureDisplay$Outbound = {
singular: string;
plural: string;
};
/** @internal */
export const AttachFeatureDisplay$outboundSchema: z.ZodMiniType<
AttachFeatureDisplay$Outbound,
AttachFeatureDisplay
> = z.object({
singular: z.string(),
plural: z.string(),
});
export function attachFeatureDisplayToJSON(
attachFeatureDisplay: AttachFeatureDisplay,
): string {
return JSON.stringify(
AttachFeatureDisplay$outboundSchema.parse(attachFeatureDisplay),
);
}
/** @internal */
export type AttachCreditSchema$Outbound = {
metered_feature_id: string;
credit_cost: number;
};
/** @internal */
export const AttachCreditSchema$outboundSchema: z.ZodMiniType<
AttachCreditSchema$Outbound,
AttachCreditSchema
> = z.pipe(
z.object({
meteredFeatureId: z.string(),
creditCost: z.number(),
}),
z.transform((v) => {
return remap$(v, {
meteredFeatureId: "metered_feature_id",
creditCost: "credit_cost",
});
}),
);
export function attachCreditSchemaToJSON(
attachCreditSchema: AttachCreditSchema,
): string {
return JSON.stringify(
AttachCreditSchema$outboundSchema.parse(attachCreditSchema),
);
}
/** @internal */
export type AttachFeature$Outbound = {
id: string;
name?: string | null | undefined;
type: string;
display?: AttachFeatureDisplay$Outbound | null | undefined;
credit_schema?: Array<AttachCreditSchema$Outbound> | null | undefined;
archived?: boolean | null | undefined;
};
/** @internal */
export const AttachFeature$outboundSchema: z.ZodMiniType<
AttachFeature$Outbound,
AttachFeature
> = z.pipe(
z.object({
id: z.string(),
name: z.optional(z.nullable(z.string())),
type: AttachFeatureType$outboundSchema,
display: z.optional(
z.nullable(z.lazy(() => AttachFeatureDisplay$outboundSchema)),
),
creditSchema: z.optional(
z.nullable(z.array(z.lazy(() => AttachCreditSchema$outboundSchema))),
),
archived: z.optional(z.nullable(z.boolean())),
}),
z.transform((v) => {
return remap$(v, {
creditSchema: "credit_schema",
});
}),
);
export function attachFeatureToJSON(attachFeature: AttachFeature): string {
return JSON.stringify(AttachFeature$outboundSchema.parse(attachFeature));
}
/** @internal */
export type IncludedUsage$Outbound = number | string;
@@ -575,104 +309,10 @@ export function tiersToJSON(tiers: Tiers): string {
return JSON.stringify(Tiers$outboundSchema.parse(tiers));
}
/** @internal */
export type AttachDisplay$Outbound = {
primary_text: string;
secondary_text?: string | null | undefined;
};
/** @internal */
export const AttachDisplay$outboundSchema: z.ZodMiniType<
AttachDisplay$Outbound,
AttachDisplay
> = z.pipe(
z.object({
primaryText: z.string(),
secondaryText: z.optional(z.nullable(z.string())),
}),
z.transform((v) => {
return remap$(v, {
primaryText: "primary_text",
secondaryText: "secondary_text",
});
}),
);
export function attachDisplayToJSON(attachDisplay: AttachDisplay): string {
return JSON.stringify(AttachDisplay$outboundSchema.parse(attachDisplay));
}
/** @internal */
export const AttachOnIncrease$outboundSchema: z.ZodMiniEnum<
typeof AttachOnIncrease
> = z.enum(AttachOnIncrease);
/** @internal */
export const AttachOnDecrease$outboundSchema: z.ZodMiniEnum<
typeof AttachOnDecrease
> = z.enum(AttachOnDecrease);
/** @internal */
export const RolloverDuration$outboundSchema: z.ZodMiniEnum<
typeof RolloverDuration
> = z.enum(RolloverDuration);
/** @internal */
export type AttachRollover$Outbound = {
max: number | null;
duration: string;
length: number;
};
/** @internal */
export const AttachRollover$outboundSchema: z.ZodMiniType<
AttachRollover$Outbound,
AttachRollover
> = z.object({
max: z.nullable(z.number()),
duration: z._default(RolloverDuration$outboundSchema, "month"),
length: z.number(),
});
export function attachRolloverToJSON(attachRollover: AttachRollover): string {
return JSON.stringify(AttachRollover$outboundSchema.parse(attachRollover));
}
/** @internal */
export type Config$Outbound = {
on_increase?: string | null | undefined;
on_decrease?: string | null | undefined;
rollover?: AttachRollover$Outbound | null | undefined;
};
/** @internal */
export const Config$outboundSchema: z.ZodMiniType<Config$Outbound, Config> = z
.pipe(
z.object({
onIncrease: z.optional(z.nullable(AttachOnIncrease$outboundSchema)),
onDecrease: z.optional(z.nullable(AttachOnDecrease$outboundSchema)),
rollover: z.optional(
z.nullable(z.lazy(() => AttachRollover$outboundSchema)),
),
}),
z.transform((v) => {
return remap$(v, {
onIncrease: "on_increase",
onDecrease: "on_decrease",
});
}),
);
export function configToJSON(config: Config): string {
return JSON.stringify(Config$outboundSchema.parse(config));
}
/** @internal */
export type AttachItem$Outbound = {
type?: string | null | undefined;
feature_id?: string | null | undefined;
feature_type?: string | null | undefined;
feature?: AttachFeature$Outbound | null | undefined;
included_usage?: number | string | null | undefined;
interval?: string | null | undefined;
interval_count?: number | null | undefined;
@@ -682,13 +322,6 @@ export type AttachItem$Outbound = {
tiers?: Array<Tiers$Outbound> | null | undefined;
billing_units?: number | null | undefined;
reset_usage_when_enabled?: boolean | null | undefined;
display?: AttachDisplay$Outbound | null | undefined;
usage_limit?: number | null | undefined;
config?: Config$Outbound | null | undefined;
created_at?: number | null | undefined;
entitlement_id?: string | null | undefined;
price_id?: string | null | undefined;
price_config?: any | null | undefined;
};
/** @internal */
@@ -699,8 +332,6 @@ export const AttachItem$outboundSchema: z.ZodMiniType<
z.object({
type: z.optional(z.nullable(AttachType$outboundSchema)),
featureId: z.optional(z.nullable(z.string())),
featureType: z.optional(z.nullable(FeatureType$outboundSchema)),
feature: z.optional(z.nullable(z.lazy(() => AttachFeature$outboundSchema))),
includedUsage: z.optional(z.nullable(smartUnion([z.number(), z.string()]))),
interval: z.optional(z.nullable(AttachInterval$outboundSchema)),
intervalCount: z.optional(z.nullable(z.number())),
@@ -710,29 +341,16 @@ export const AttachItem$outboundSchema: z.ZodMiniType<
tiers: z.optional(z.nullable(z.array(z.lazy(() => Tiers$outboundSchema)))),
billingUnits: z.optional(z.nullable(z.number())),
resetUsageWhenEnabled: z.optional(z.nullable(z.boolean())),
display: z.optional(z.nullable(z.lazy(() => AttachDisplay$outboundSchema))),
usageLimit: z.optional(z.nullable(z.number())),
config: z.optional(z.nullable(z.lazy(() => Config$outboundSchema))),
createdAt: z.optional(z.nullable(z.number())),
entitlementId: z.optional(z.nullable(z.string())),
priceId: z.optional(z.nullable(z.string())),
priceConfig: z.optional(z.nullable(z.any())),
}),
z.transform((v) => {
return remap$(v, {
featureId: "feature_id",
featureType: "feature_type",
includedUsage: "included_usage",
intervalCount: "interval_count",
entityFeatureId: "entity_feature_id",
usageModel: "usage_model",
billingUnits: "billing_units",
resetUsageWhenEnabled: "reset_usage_when_enabled",
usageLimit: "usage_limit",
createdAt: "created_at",
entitlementId: "entitlement_id",
priceId: "price_id",
priceConfig: "price_config",
});
}),
);
@@ -756,8 +374,6 @@ export const BillingBehavior$outboundSchema: z.ZodMiniEnum<
/** @internal */
export type AttachRequest$Outbound = {
entity_id?: string | null | undefined;
entity_data?: AttachEntityData$Outbound | undefined;
options?: Array<Options$Outbound> | null | undefined;
version?: number | undefined;
free_trial?: AttachFreeTrial$Outbound | null | undefined;
@@ -780,8 +396,6 @@ export const AttachRequest$outboundSchema: z.ZodMiniType<
AttachRequest
> = z.pipe(
z.object({
entityId: z.optional(z.nullable(z.string())),
entityData: z.optional(z.lazy(() => AttachEntityData$outboundSchema)),
options: z.optional(
z.nullable(z.array(z.lazy(() => Options$outboundSchema))),
),
@@ -803,8 +417,6 @@ export const AttachRequest$outboundSchema: z.ZodMiniType<
}),
z.transform((v) => {
return remap$(v, {
entityId: "entity_id",
entityData: "entity_data",
freeTrial: "free_trial",
productId: "product_id",
enableProductImmediately: "enable_product_immediately",
@@ -883,7 +495,6 @@ export const AttachResponse$inboundSchema: z.ZodMiniType<
> = z.pipe(
z.object({
customer_id: types.string(),
entity_id: types.optional(types.string()),
invoice: types.optional(z.lazy(() => AttachInvoice$inboundSchema)),
payment_url: types.nullable(types.string()),
required_action: types.optional(z.lazy(() => RequiredAction$inboundSchema)),
@@ -891,7 +502,6 @@ export const AttachResponse$inboundSchema: z.ZodMiniType<
z.transform((v) => {
return remap$(v, {
"customer_id": "customerId",
"entity_id": "entityId",
"payment_url": "paymentUrl",
"required_action": "requiredAction",
});

View File

@@ -13,10 +13,16 @@ import { smartUnion } from "../types/smart-union.js";
import { Plan, Plan$inboundSchema } from "./plan.js";
import { SDKValidationError } from "./sdk-validation-error.js";
/**
* The environment this customer was created in.
*/
export const CustomerEnv = {
Sandbox: "sandbox",
Live: "live",
} as const;
/**
* The environment this customer was created in.
*/
export type CustomerEnv = OpenEnum<typeof CustomerEnv>;
export const Status = {
@@ -50,34 +56,6 @@ export type Purchase = {
quantity: number;
};
export const BalancesType = {
Boolean: "boolean",
Metered: "metered",
CreditSystem: "credit_system",
} as const;
export type BalancesType = OpenEnum<typeof BalancesType>;
export type CustomerCreditSchema = {
meteredFeatureId: string;
creditCost: number;
};
export type CustomerDisplay = {
singular?: string | null | undefined;
plural?: string | null | undefined;
};
export type CustomerFeature = {
id: string;
name: string;
type: BalancesType;
consumable: boolean;
eventNames?: Array<string> | undefined;
creditSchema?: Array<CustomerCreditSchema> | undefined;
display?: CustomerDisplay | undefined;
archived: boolean;
};
export const CustomerIntervalEnum = {
OneOff: "one_off",
Minute: "minute",
@@ -121,7 +99,6 @@ export type CustomerPrice = {
};
export type Breakdown = {
id: string;
planId: string | null;
includedGrant: number;
prepaidGrant: number;
@@ -140,7 +117,6 @@ export type CustomerRollover = {
export type Balances = {
featureId: string;
feature?: CustomerFeature | undefined;
granted: number;
remaining: number;
usage: number;
@@ -173,10 +149,6 @@ export type Invoice = {
* The currency code for the invoice
*/
currency: string;
/**
* Timestamp when the invoice was created
*/
createdAt: number;
/**
* URL to the Stripe-hosted invoice page
*/
@@ -196,11 +168,6 @@ export const EntityEnv = {
export type EntityEnv = OpenEnum<typeof EntityEnv>;
export type Entity = {
autumnId?: string | undefined;
/**
* The unique identifier of the entity
*/
id: string | null;
/**
* The name of the entity
*/
@@ -213,10 +180,6 @@ export type Entity = {
* The feature ID this entity belongs to
*/
featureId?: string | null | undefined;
/**
* Unix timestamp when the entity was created
*/
createdAt: number;
/**
* The environment (sandbox/live)
*/
@@ -232,7 +195,7 @@ export type TrialsUsed = {
/**
* The type of reward
*/
export const RewardsType = {
export const Type = {
PercentageDiscount: "percentage_discount",
FixedDiscount: "fixed_discount",
FreeProduct: "free_product",
@@ -241,7 +204,7 @@ export const RewardsType = {
/**
* The type of reward
*/
export type RewardsType = OpenEnum<typeof RewardsType>;
export type Type = OpenEnum<typeof Type>;
/**
* How long the discount lasts
@@ -257,10 +220,6 @@ export const CustomerDurationType = {
export type CustomerDurationType = OpenEnum<typeof CustomerDurationType>;
export type Discount = {
/**
* The unique identifier for this discount
*/
id: string;
/**
* The name of the discount or coupon
*/
@@ -268,7 +227,7 @@ export type Discount = {
/**
* The type of reward
*/
type: RewardsType;
type: Type;
/**
* The discount value (percentage or fixed amount)
*/
@@ -311,7 +270,6 @@ export type Rewards = {
};
export type ReferralCustomer = {
id: string;
name?: string | null | undefined;
email?: string | null | undefined;
};
@@ -320,19 +278,36 @@ export type Referral = {
programId: string;
customer: ReferralCustomer;
rewardApplied: boolean;
createdAt: number;
};
export type Customer = {
autumnId?: string | undefined;
id: string | null;
/**
* The name of the customer.
*/
name: string | null;
/**
* The email address of the customer.
*/
email: string | null;
createdAt: number;
/**
* A unique identifier (eg. serial number) to de-duplicate customers across devices or browsers. For example: apple device ID.
*/
fingerprint: string | null;
/**
* Stripe customer ID.
*/
stripeId: string | null;
/**
* The environment this customer was created in.
*/
env: CustomerEnv;
/**
* The metadata for the customer.
*/
metadata: { [k: string]: any };
/**
* Whether to send email receipts to the customer.
*/
sendEmailReceipts: boolean;
subscriptions: Array<Subscription>;
purchases: Array<Purchase>;
@@ -425,91 +400,6 @@ export function purchaseFromJSON(
);
}
/** @internal */
export const BalancesType$inboundSchema: z.ZodMiniType<BalancesType, unknown> =
openEnums.inboundSchema(BalancesType);
/** @internal */
export const CustomerCreditSchema$inboundSchema: z.ZodMiniType<
CustomerCreditSchema,
unknown
> = z.pipe(
z.object({
metered_feature_id: types.string(),
credit_cost: types.number(),
}),
z.transform((v) => {
return remap$(v, {
"metered_feature_id": "meteredFeatureId",
"credit_cost": "creditCost",
});
}),
);
export function customerCreditSchemaFromJSON(
jsonString: string,
): SafeParseResult<CustomerCreditSchema, SDKValidationError> {
return safeParse(
jsonString,
(x) => CustomerCreditSchema$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'CustomerCreditSchema' from JSON`,
);
}
/** @internal */
export const CustomerDisplay$inboundSchema: z.ZodMiniType<
CustomerDisplay,
unknown
> = z.object({
singular: z.optional(z.nullable(types.string())),
plural: z.optional(z.nullable(types.string())),
});
export function customerDisplayFromJSON(
jsonString: string,
): SafeParseResult<CustomerDisplay, SDKValidationError> {
return safeParse(
jsonString,
(x) => CustomerDisplay$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'CustomerDisplay' from JSON`,
);
}
/** @internal */
export const CustomerFeature$inboundSchema: z.ZodMiniType<
CustomerFeature,
unknown
> = z.pipe(
z.object({
id: types.string(),
name: types.string(),
type: BalancesType$inboundSchema,
consumable: types.boolean(),
event_names: types.optional(z.array(types.string())),
credit_schema: types.optional(
z.array(z.lazy(() => CustomerCreditSchema$inboundSchema)),
),
display: types.optional(z.lazy(() => CustomerDisplay$inboundSchema)),
archived: types.boolean(),
}),
z.transform((v) => {
return remap$(v, {
"event_names": "eventNames",
"credit_schema": "creditSchema",
});
}),
);
export function customerFeatureFromJSON(
jsonString: string,
): SafeParseResult<CustomerFeature, SDKValidationError> {
return safeParse(
jsonString,
(x) => CustomerFeature$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'CustomerFeature' from JSON`,
);
}
/** @internal */
export const CustomerIntervalEnum$inboundSchema: z.ZodMiniType<
CustomerIntervalEnum,
@@ -630,7 +520,6 @@ export function customerPriceFromJSON(
export const Breakdown$inboundSchema: z.ZodMiniType<Breakdown, unknown> = z
.pipe(
z.object({
id: z._default(types.string(), ""),
plan_id: types.nullable(types.string()),
included_grant: types.number(),
prepaid_grant: types.number(),
@@ -691,7 +580,6 @@ export function customerRolloverFromJSON(
export const Balances$inboundSchema: z.ZodMiniType<Balances, unknown> = z.pipe(
z.object({
feature_id: types.string(),
feature: types.optional(z.lazy(() => CustomerFeature$inboundSchema)),
granted: types.number(),
remaining: types.number(),
usage: types.number(),
@@ -732,14 +620,12 @@ export const Invoice$inboundSchema: z.ZodMiniType<Invoice, unknown> = z.pipe(
status: types.string(),
total: types.number(),
currency: types.string(),
created_at: types.number(),
hosted_invoice_url: z.optional(z.nullable(types.string())),
}),
z.transform((v) => {
return remap$(v, {
"plan_ids": "planIds",
"stripe_id": "stripeId",
"created_at": "createdAt",
"hosted_invoice_url": "hostedInvoiceUrl",
});
}),
@@ -762,20 +648,15 @@ export const EntityEnv$inboundSchema: z.ZodMiniType<EntityEnv, unknown> =
/** @internal */
export const Entity$inboundSchema: z.ZodMiniType<Entity, unknown> = z.pipe(
z.object({
autumn_id: types.optional(types.string()),
id: types.nullable(types.string()),
name: types.nullable(types.string()),
customer_id: z.optional(z.nullable(types.string())),
feature_id: z.optional(z.nullable(types.string())),
created_at: types.number(),
env: EntityEnv$inboundSchema,
}),
z.transform((v) => {
return remap$(v, {
"autumn_id": "autumnId",
"customer_id": "customerId",
"feature_id": "featureId",
"created_at": "createdAt",
});
}),
);
@@ -817,8 +698,8 @@ export function trialsUsedFromJSON(
}
/** @internal */
export const RewardsType$inboundSchema: z.ZodMiniType<RewardsType, unknown> =
openEnums.inboundSchema(RewardsType);
export const Type$inboundSchema: z.ZodMiniType<Type, unknown> = openEnums
.inboundSchema(Type);
/** @internal */
export const CustomerDurationType$inboundSchema: z.ZodMiniType<
@@ -829,9 +710,8 @@ export const CustomerDurationType$inboundSchema: z.ZodMiniType<
/** @internal */
export const Discount$inboundSchema: z.ZodMiniType<Discount, unknown> = z.pipe(
z.object({
id: types.string(),
name: types.string(),
type: RewardsType$inboundSchema,
type: Type$inboundSchema,
discount_value: types.number(),
duration_type: CustomerDurationType$inboundSchema,
duration_value: z.optional(z.nullable(types.number())),
@@ -882,7 +762,6 @@ export const ReferralCustomer$inboundSchema: z.ZodMiniType<
ReferralCustomer,
unknown
> = z.object({
id: types.string(),
name: z.optional(z.nullable(types.string())),
email: z.optional(z.nullable(types.string())),
});
@@ -903,13 +782,11 @@ export const Referral$inboundSchema: z.ZodMiniType<Referral, unknown> = z.pipe(
program_id: types.string(),
customer: z.lazy(() => ReferralCustomer$inboundSchema),
reward_applied: types.boolean(),
created_at: types.number(),
}),
z.transform((v) => {
return remap$(v, {
"program_id": "programId",
"reward_applied": "rewardApplied",
"created_at": "createdAt",
});
}),
);
@@ -927,11 +804,8 @@ export function referralFromJSON(
/** @internal */
export const Customer$inboundSchema: z.ZodMiniType<Customer, unknown> = z.pipe(
z.object({
autumn_id: types.optional(types.string()),
id: types.nullable(types.string()),
name: types.nullable(types.string()),
email: types.nullable(types.string()),
created_at: types.number(),
fingerprint: types.nullable(types.string()),
stripe_id: types.nullable(types.string()),
env: CustomerEnv$inboundSchema,
@@ -951,8 +825,6 @@ export const Customer$inboundSchema: z.ZodMiniType<Customer, unknown> = z.pipe(
}),
z.transform((v) => {
return remap$(v, {
"autumn_id": "autumnId",
"created_at": "createdAt",
"stripe_id": "stripeId",
"send_email_receipts": "sendEmailReceipts",
"trials_used": "trialsUsed",

View File

@@ -13,39 +13,6 @@ export type GetOrCreateGlobals = {
xApiVersion?: string | undefined;
};
export type Vercel = {
installationId: string;
accessToken: string;
accountId: string;
customPaymentMethodId?: string | undefined;
};
export type Processors = {
vercel?: Vercel | undefined;
};
export type InternalOptions = {
/**
* The group of products to attach to the customer
*/
defaultGroup?: string | undefined;
/**
* Whether to disable default products
*/
disableDefaults?: boolean | undefined;
};
export type GetOrCreateEntityData = {
/**
* The feature ID that this entity is associated with
*/
featureId: string;
/**
* Name of the entity
*/
name?: string | undefined;
};
export type GetOrCreateCustomerParams = {
customerId: string | null;
/**
@@ -76,132 +43,16 @@ export type GetOrCreateCustomerParams = {
* The ID of the free plan to auto-enable for the customer
*/
autoEnablePlanId?: string | undefined;
/**
* External processors for the customer
*/
processors?: Processors | null | undefined;
/**
* Whether to send email receipts to this customer
*/
sendEmailReceipts?: boolean | undefined;
internalOptions?: InternalOptions | undefined;
/**
* Customer expand options
*/
expand?: Array<CustomerExpand> | undefined;
entityId?: string | undefined;
entityData?: GetOrCreateEntityData | undefined;
id?: string | null | undefined;
withAutumnId?: boolean | undefined;
};
/** @internal */
export type Vercel$Outbound = {
installation_id: string;
access_token: string;
account_id: string;
custom_payment_method_id?: string | undefined;
};
/** @internal */
export const Vercel$outboundSchema: z.ZodMiniType<Vercel$Outbound, Vercel> = z
.pipe(
z.object({
installationId: z.string(),
accessToken: z.string(),
accountId: z.string(),
customPaymentMethodId: z.optional(z.string()),
}),
z.transform((v) => {
return remap$(v, {
installationId: "installation_id",
accessToken: "access_token",
accountId: "account_id",
customPaymentMethodId: "custom_payment_method_id",
});
}),
);
export function vercelToJSON(vercel: Vercel): string {
return JSON.stringify(Vercel$outboundSchema.parse(vercel));
}
/** @internal */
export type Processors$Outbound = {
vercel?: Vercel$Outbound | undefined;
};
/** @internal */
export const Processors$outboundSchema: z.ZodMiniType<
Processors$Outbound,
Processors
> = z.object({
vercel: z.optional(z.lazy(() => Vercel$outboundSchema)),
});
export function processorsToJSON(processors: Processors): string {
return JSON.stringify(Processors$outboundSchema.parse(processors));
}
/** @internal */
export type InternalOptions$Outbound = {
default_group?: string | undefined;
disable_defaults?: boolean | undefined;
};
/** @internal */
export const InternalOptions$outboundSchema: z.ZodMiniType<
InternalOptions$Outbound,
InternalOptions
> = z.pipe(
z.object({
defaultGroup: z.optional(z.string()),
disableDefaults: z.optional(z.boolean()),
}),
z.transform((v) => {
return remap$(v, {
defaultGroup: "default_group",
disableDefaults: "disable_defaults",
});
}),
);
export function internalOptionsToJSON(
internalOptions: InternalOptions,
): string {
return JSON.stringify(InternalOptions$outboundSchema.parse(internalOptions));
}
/** @internal */
export type GetOrCreateEntityData$Outbound = {
feature_id: string;
name?: string | undefined;
};
/** @internal */
export const GetOrCreateEntityData$outboundSchema: z.ZodMiniType<
GetOrCreateEntityData$Outbound,
GetOrCreateEntityData
> = z.pipe(
z.object({
featureId: z.string(),
name: z.optional(z.string()),
}),
z.transform((v) => {
return remap$(v, {
featureId: "feature_id",
});
}),
);
export function getOrCreateEntityDataToJSON(
getOrCreateEntityData: GetOrCreateEntityData,
): string {
return JSON.stringify(
GetOrCreateEntityData$outboundSchema.parse(getOrCreateEntityData),
);
}
/** @internal */
export type GetOrCreateCustomerParams$Outbound = {
customer_id: string | null;
@@ -212,14 +63,8 @@ export type GetOrCreateCustomerParams$Outbound = {
stripe_id?: string | null | undefined;
create_in_stripe?: boolean | undefined;
auto_enable_plan_id?: string | undefined;
processors?: Processors$Outbound | null | undefined;
send_email_receipts?: boolean | undefined;
internal_options?: InternalOptions$Outbound | undefined;
expand?: Array<string> | undefined;
entity_id?: string | undefined;
entity_data?: GetOrCreateEntityData$Outbound | undefined;
id?: string | null | undefined;
with_autumn_id: boolean;
};
/** @internal */
@@ -236,14 +81,8 @@ export const GetOrCreateCustomerParams$outboundSchema: z.ZodMiniType<
stripeId: z.optional(z.nullable(z.string())),
createInStripe: z.optional(z.boolean()),
autoEnablePlanId: z.optional(z.string()),
processors: z.optional(z.nullable(z.lazy(() => Processors$outboundSchema))),
sendEmailReceipts: z.optional(z.boolean()),
internalOptions: z.optional(z.lazy(() => InternalOptions$outboundSchema)),
expand: z.optional(z.array(CustomerExpand$outboundSchema)),
entityId: z.optional(z.string()),
entityData: z.optional(z.lazy(() => GetOrCreateEntityData$outboundSchema)),
id: z.optional(z.nullable(z.string())),
withAutumnId: z._default(z.boolean(), false),
}),
z.transform((v) => {
return remap$(v, {
@@ -252,10 +91,6 @@ export const GetOrCreateCustomerParams$outboundSchema: z.ZodMiniType<
createInStripe: "create_in_stripe",
autoEnablePlanId: "auto_enable_plan_id",
sendEmailReceipts: "send_email_receipts",
internalOptions: "internal_options",
entityId: "entity_id",
entityData: "entity_data",
withAutumnId: "with_autumn_id",
});
}),
);

View File

@@ -22,80 +22,10 @@ export const PriceInterval = {
} as const;
export type PriceInterval = OpenEnum<typeof PriceInterval>;
export type PriceDisplay = {
primaryText: string;
secondaryText?: string | undefined;
};
export type PlanPrice = {
amount: number;
interval: PriceInterval;
intervalCount?: number | undefined;
display?: PriceDisplay | undefined;
};
/**
* The type of the feature
*/
export const PlanType = {
Static: "static",
Boolean: "boolean",
SingleUse: "single_use",
ContinuousUse: "continuous_use",
CreditSystem: "credit_system",
} as const;
/**
* The type of the feature
*/
export type PlanType = OpenEnum<typeof PlanType>;
export type PlanFeatureDisplay = {
/**
* The singular display name for the feature.
*/
singular: string;
/**
* The plural display name for the feature.
*/
plural: string;
};
export type PlanCreditSchema = {
/**
* The ID of the metered feature (should be a single_use feature).
*/
meteredFeatureId: string;
/**
* The credit cost of the metered feature.
*/
creditCost: number;
};
export type PlanFeature = {
/**
* The ID of the feature, used to refer to it in other API calls like /track or /check.
*/
id: string;
/**
* The name of the feature.
*/
name?: string | null | undefined;
/**
* The type of the feature
*/
type: PlanType;
/**
* Singular and plural display names for the feature.
*/
display?: PlanFeatureDisplay | null | undefined;
/**
* Credit cost schema for credit system features.
*/
creditSchema?: Array<PlanCreditSchema> | null | undefined;
/**
* Whether or not the feature is archived.
*/
archived?: boolean | null | undefined;
};
export const PlanResetInterval = {
@@ -149,11 +79,6 @@ export type ItemPrice = {
maxPurchase: number | null;
};
export type PlanItemDisplay = {
primaryText: string;
secondaryText?: string | undefined;
};
export const ExpiryDurationType = {
Month: "month",
Forever: "forever",
@@ -190,12 +115,10 @@ export type Proration = {
export type Item = {
featureId: string;
feature?: PlanFeature | undefined;
included: number;
unlimited: boolean;
reset: PlanReset | null;
price: ItemPrice | null;
display?: PlanItemDisplay | undefined;
rollover?: PlanRollover | undefined;
proration?: Proration | undefined;
};
@@ -238,7 +161,6 @@ export type CustomerEligibility = {
};
export type Plan = {
id: string;
name: string;
description: string | null;
group: string | null;
@@ -248,7 +170,6 @@ export type Plan = {
price: PlanPrice | null;
items: Array<Item>;
freeTrial?: FreeTrial | undefined;
createdAt: number;
env: PlanEnv;
archived: boolean;
baseVariantId: string | null;
@@ -261,31 +182,6 @@ export const PriceInterval$inboundSchema: z.ZodMiniType<
unknown
> = openEnums.inboundSchema(PriceInterval);
/** @internal */
export const PriceDisplay$inboundSchema: z.ZodMiniType<PriceDisplay, unknown> =
z.pipe(
z.object({
primary_text: types.string(),
secondary_text: types.optional(types.string()),
}),
z.transform((v) => {
return remap$(v, {
"primary_text": "primaryText",
"secondary_text": "secondaryText",
});
}),
);
export function priceDisplayFromJSON(
jsonString: string,
): SafeParseResult<PriceDisplay, SDKValidationError> {
return safeParse(
jsonString,
(x) => PriceDisplay$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'PriceDisplay' from JSON`,
);
}
/** @internal */
export const PlanPrice$inboundSchema: z.ZodMiniType<PlanPrice, unknown> = z
.pipe(
@@ -293,7 +189,6 @@ export const PlanPrice$inboundSchema: z.ZodMiniType<PlanPrice, unknown> = z
amount: types.number(),
interval: PriceInterval$inboundSchema,
interval_count: types.optional(types.number()),
display: types.optional(z.lazy(() => PriceDisplay$inboundSchema)),
}),
z.transform((v) => {
return remap$(v, {
@@ -312,88 +207,6 @@ export function planPriceFromJSON(
);
}
/** @internal */
export const PlanType$inboundSchema: z.ZodMiniType<PlanType, unknown> =
openEnums.inboundSchema(PlanType);
/** @internal */
export const PlanFeatureDisplay$inboundSchema: z.ZodMiniType<
PlanFeatureDisplay,
unknown
> = z.object({
singular: types.string(),
plural: types.string(),
});
export function planFeatureDisplayFromJSON(
jsonString: string,
): SafeParseResult<PlanFeatureDisplay, SDKValidationError> {
return safeParse(
jsonString,
(x) => PlanFeatureDisplay$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'PlanFeatureDisplay' from JSON`,
);
}
/** @internal */
export const PlanCreditSchema$inboundSchema: z.ZodMiniType<
PlanCreditSchema,
unknown
> = z.pipe(
z.object({
metered_feature_id: types.string(),
credit_cost: types.number(),
}),
z.transform((v) => {
return remap$(v, {
"metered_feature_id": "meteredFeatureId",
"credit_cost": "creditCost",
});
}),
);
export function planCreditSchemaFromJSON(
jsonString: string,
): SafeParseResult<PlanCreditSchema, SDKValidationError> {
return safeParse(
jsonString,
(x) => PlanCreditSchema$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'PlanCreditSchema' from JSON`,
);
}
/** @internal */
export const PlanFeature$inboundSchema: z.ZodMiniType<PlanFeature, unknown> = z
.pipe(
z.object({
id: types.string(),
name: z.optional(z.nullable(types.string())),
type: PlanType$inboundSchema,
display: z.optional(
z.nullable(z.lazy(() => PlanFeatureDisplay$inboundSchema)),
),
credit_schema: z.optional(
z.nullable(z.array(z.lazy(() => PlanCreditSchema$inboundSchema))),
),
archived: z.optional(z.nullable(types.boolean())),
}),
z.transform((v) => {
return remap$(v, {
"credit_schema": "creditSchema",
});
}),
);
export function planFeatureFromJSON(
jsonString: string,
): SafeParseResult<PlanFeature, SDKValidationError> {
return safeParse(
jsonString,
(x) => PlanFeature$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'PlanFeature' from JSON`,
);
}
/** @internal */
export const PlanResetInterval$inboundSchema: z.ZodMiniType<
PlanResetInterval,
@@ -501,33 +314,6 @@ export function itemPriceFromJSON(
);
}
/** @internal */
export const PlanItemDisplay$inboundSchema: z.ZodMiniType<
PlanItemDisplay,
unknown
> = z.pipe(
z.object({
primary_text: types.string(),
secondary_text: types.optional(types.string()),
}),
z.transform((v) => {
return remap$(v, {
"primary_text": "primaryText",
"secondary_text": "secondaryText",
});
}),
);
export function planItemDisplayFromJSON(
jsonString: string,
): SafeParseResult<PlanItemDisplay, SDKValidationError> {
return safeParse(
jsonString,
(x) => PlanItemDisplay$inboundSchema.parse(JSON.parse(x)),
`Failed to parse 'PlanItemDisplay' from JSON`,
);
}
/** @internal */
export const ExpiryDurationType$inboundSchema: z.ZodMiniType<
ExpiryDurationType,
@@ -597,12 +383,10 @@ export function prorationFromJSON(
export const Item$inboundSchema: z.ZodMiniType<Item, unknown> = z.pipe(
z.object({
feature_id: types.string(),
feature: types.optional(z.lazy(() => PlanFeature$inboundSchema)),
included: types.number(),
unlimited: types.boolean(),
reset: types.nullable(z.lazy(() => PlanReset$inboundSchema)),
price: types.nullable(z.lazy(() => ItemPrice$inboundSchema)),
display: types.optional(z.lazy(() => PlanItemDisplay$inboundSchema)),
rollover: types.optional(z.lazy(() => PlanRollover$inboundSchema)),
proration: types.optional(z.lazy(() => Proration$inboundSchema)),
}),
@@ -693,7 +477,6 @@ export function customerEligibilityFromJSON(
/** @internal */
export const Plan$inboundSchema: z.ZodMiniType<Plan, unknown> = z.pipe(
z.object({
id: types.string(),
name: types.string(),
description: types.nullable(types.string()),
group: types.nullable(types.string()),
@@ -703,7 +486,6 @@ export const Plan$inboundSchema: z.ZodMiniType<Plan, unknown> = z.pipe(
price: types.nullable(z.lazy(() => PlanPrice$inboundSchema)),
items: z.array(z.lazy(() => Item$inboundSchema)),
free_trial: types.optional(z.lazy(() => FreeTrial$inboundSchema)),
created_at: types.number(),
env: PlanEnv$inboundSchema,
archived: types.boolean(),
base_variant_id: types.nullable(types.string()),
@@ -716,7 +498,6 @@ export const Plan$inboundSchema: z.ZodMiniType<Plan, unknown> = z.pipe(
"add_on": "addOn",
"auto_enable": "autoEnable",
"free_trial": "freeTrial",
"created_at": "createdAt",
"base_variant_id": "baseVariantId",
"customer_eligibility": "customerEligibility",
});

View File

@@ -0,0 +1,254 @@
import type { ParsedOperation, SchemaField } from "./parseOpenApi.js";
/**
* Generate the MDX content for request body and response fields.
*/
export function generateFields({
operation,
}: {
operation: ParsedOperation;
}): string {
const sections: string[] = [];
// Generate request body parameters
if (operation.requestBody && operation.requestBody.length > 0) {
sections.push("### Body Parameters\n");
sections.push(
generateParamFields({ fields: operation.requestBody, indent: 0 }),
);
}
// Generate response fields (use 200 or 201 response)
const responseStatusCode = operation.responses?.["200"]
? "200"
: operation.responses?.["201"]
? "201"
: null;
const responseFields = responseStatusCode
? operation.responses?.[responseStatusCode]
: null;
if (responseFields && responseFields.length > 0) {
sections.push("\n### Response\n");
sections.push(
generateResponseFields({ fields: responseFields, indent: 0 }),
);
}
// Generate DynamicResponseExample with the actual example from OpenAPI spec
// This example is already in snake_case - the component will convert to camelCase when needed
const responseExample = responseStatusCode
? operation.responseExamples?.[responseStatusCode]
: null;
if (responseExample && typeof responseExample === "object") {
sections.push(
generateResponseExampleComponent({
json: responseExample,
statusCode: responseStatusCode,
}),
);
}
return sections.join("\n");
}
/**
* Generate a ResponseExample with markdown code block.
* Uses Mintlify's ResponseExample component which pins content to the sidebar.
*/
function generateResponseExampleMarkdown({
json,
statusCode,
}: {
json: unknown;
statusCode: string;
}): string {
// Format the JSON with proper indentation
const jsonString = JSON.stringify(json, null, 2);
// Generate markdown ResponseExample block
// The triple backticks create a code block inside ResponseExample
return `
<ResponseExample>
\`\`\`json ${statusCode}
${jsonString}
\`\`\`
</ResponseExample>
`;
}
/**
* Generate DynamicParamField components for request body fields.
*/
function generateParamFields({
fields,
indent,
}: {
fields: SchemaField[];
indent: number;
}): string {
const indentStr = " ".repeat(indent);
const lines: string[] = [];
for (const field of fields) {
const props = buildFieldProps({
name: field.name,
type: field.type,
required: field.required,
enumValues: field.enumValues,
});
const description = escapeDescription(field.description);
const hasChildren = field.children && field.children.length > 0;
if (hasChildren) {
// Field with nested children
lines.push(`${indentStr}<DynamicParamField ${props}>`);
if (description) {
lines.push(`${indentStr} ${description}`);
}
lines.push(`${indentStr} <Expandable title="properties">`);
lines.push(
generateParamFields({ fields: field.children!, indent: indent + 2 }),
);
lines.push(`${indentStr} </Expandable>`);
lines.push(`${indentStr}</DynamicParamField>\n`);
} else {
// Simple field
if (description) {
lines.push(`${indentStr}<DynamicParamField ${props}>`);
lines.push(`${indentStr} ${description}`);
lines.push(`${indentStr}</DynamicParamField>\n`);
} else {
lines.push(`${indentStr}<DynamicParamField ${props} />\n`);
}
}
}
return lines.join("\n");
}
/**
* Generate DynamicResponseField components for response fields.
*/
function generateResponseFields({
fields,
indent,
}: {
fields: SchemaField[];
indent: number;
}): string {
const indentStr = " ".repeat(indent);
const lines: string[] = [];
for (const field of fields) {
const props = buildResponseFieldProps({
name: field.name,
type: field.type,
enumValues: field.enumValues,
});
const description = escapeDescription(field.description);
const hasChildren = field.children && field.children.length > 0;
if (hasChildren) {
// Field with nested children
lines.push(`${indentStr}<DynamicResponseField ${props}>`);
if (description) {
lines.push(`${indentStr} ${description}`);
}
lines.push(`${indentStr} <Expandable title="properties">`);
lines.push(
generateResponseFields({ fields: field.children!, indent: indent + 2 }),
);
lines.push(`${indentStr} </Expandable>`);
lines.push(`${indentStr}</DynamicResponseField>\n`);
} else {
// Simple field
if (description) {
lines.push(`${indentStr}<DynamicResponseField ${props}>`);
lines.push(`${indentStr} ${description}`);
lines.push(`${indentStr}</DynamicResponseField>\n`);
} else {
lines.push(`${indentStr}<DynamicResponseField ${props} />\n`);
}
}
}
return lines.join("\n");
}
/**
* Build the props string for a DynamicParamField component.
*/
function buildFieldProps({
name,
type,
required,
enumValues,
}: {
name: string;
type: string;
required: boolean;
enumValues?: string[];
}): string {
const props: string[] = [
`body="${name}"`,
`type="${formatType(type, enumValues)}"`,
];
if (required) {
props.push("required");
}
return props.join(" ");
}
/**
* Build the props string for a DynamicResponseField component.
*/
function buildResponseFieldProps({
name,
type,
enumValues,
}: {
name: string;
type: string;
enumValues?: string[];
}): string {
return `name="${name}" type="${formatType(type, enumValues)}"`;
}
/**
* Format the type string, including enum values if present.
*/
function formatType(type: string, enumValues?: string[]): string {
if (enumValues && enumValues.length > 0) {
// Show enum values inline if there are few, otherwise just show "enum"
if (enumValues.length <= 5) {
return enumValues.map((v) => `'${v}'`).join(" | ");
}
return "enum";
}
return type;
}
/**
* Escape special characters in description for MDX.
*/
function escapeDescription(description?: string): string {
if (!description) return "";
return (
description
// Escape curly braces for JSX
.replace(/\{/g, "\\{")
.replace(/\}/g, "\\}")
// Remove markdown code blocks that might cause issues
.replace(/```[\s\S]*?```/g, "")
// Normalize whitespace
.replace(/\s+/g, " ")
.trim()
);
}

View File

@@ -0,0 +1,82 @@
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
import path from "node:path";
import { generateFields } from "./generateFields.js";
import { mergeMdx } from "./mergeMdx.js";
import { parseOpenApi } from "./parseOpenApi.js";
export interface GenerateApiReferenceOptions {
openApiPath: string;
manualMdxDir: string;
outputDir: string;
}
/**
* Generate API reference MDX files from an OpenAPI spec.
*
* For each operation in the OpenAPI spec:
* 1. Parse request body and response schemas
* 2. Generate DynamicParamField/DynamicResponseField components
* 3. Merge with manual MDX content (if exists)
* 4. Write to output directory: {outputDir}/{tag}/{operationId}.mdx
*/
export async function generateApiReference({
openApiPath,
manualMdxDir,
outputDir,
}: GenerateApiReferenceOptions): Promise<void> {
console.log(` Reading OpenAPI spec from: ${openApiPath}`);
// Parse OpenAPI spec
const operations = parseOpenApi({ openApiPath });
console.log(` Found ${operations.length} operations`);
let generated = 0;
let skipped = 0;
for (const operation of operations) {
const { tag, operationId } = operation;
// Determine file paths
const manualMdxPath = path.join(manualMdxDir, tag, `${operationId}.mdx`);
const outputPath = path.join(outputDir, tag, `${operationId}.mdx`);
// Check if output file already exists and there's no manual MDX
// In that case, skip to avoid overwriting existing content
if (existsSync(outputPath) && !existsSync(manualMdxPath)) {
skipped++;
continue;
}
// Generate fields MDX
const generatedContent = generateFields({ operation });
// Skip if no content was generated
if (!generatedContent.trim()) {
skipped++;
continue;
}
// Merge with manual MDX (if exists)
const finalMdx = mergeMdx({
manualMdxPath,
generatedContent,
operation,
});
// Ensure output directory exists
mkdirSync(path.dirname(outputPath), { recursive: true });
// Write output file
writeFileSync(outputPath, finalMdx, "utf-8");
generated++;
console.log(` Generated: ${tag}/${operationId}.mdx`);
}
console.log(
` API reference generation complete: ${generated} generated, ${skipped} skipped`,
);
}
// Re-export types for consumers
export type { ParsedOperation, SchemaField } from "./parseOpenApi.js";

View File

@@ -0,0 +1,70 @@
import { existsSync, readFileSync } from "node:fs";
import type { ParsedOperation } from "./parseOpenApi.js";
const IMPORTS = `import { DynamicParamField } from "/components/dynamic-param-field.jsx";
import { DynamicResponseField } from "/components/dynamic-response-field.jsx";
import { DynamicResponseExample } from "/components/dynamic-response-example.jsx";`;
/**
* Merge manual MDX content with generated fields.
* If manual MDX exists, append generated content after it.
* If no manual MDX exists, generate minimal frontmatter + imports + generated content.
*/
export function mergeMdx({
manualMdxPath,
generatedContent,
operation,
}: {
manualMdxPath: string;
generatedContent: string;
operation: ParsedOperation;
}): string {
if (existsSync(manualMdxPath)) {
// Read manual MDX and append generated content
const manualContent = readFileSync(manualMdxPath, "utf-8");
// Check if all imports already exist
const hasAllImports =
manualContent.includes("DynamicParamField") &&
manualContent.includes("DynamicResponseField") &&
manualContent.includes("DynamicResponseExample");
// If manual content has frontmatter but missing imports, add them after frontmatter
if (!hasAllImports) {
const frontmatterMatch = manualContent.match(/^---\n[\s\S]*?\n---\n/);
if (frontmatterMatch) {
const frontmatter = frontmatterMatch[0];
const restContent = manualContent.slice(frontmatter.length).trim();
return `${frontmatter}\n${IMPORTS}\n\n${restContent}\n\n${generatedContent}`;
}
}
return `${manualContent.trim()}\n\n${generatedContent}`;
}
// Generate minimal frontmatter
const title =
operation.summary ?? formatOperationIdAsTitle(operation.operationId);
const frontmatter = `---
title: "${title}"
openapi: "openapi ${operation.method} ${operation.path}"
---`;
return `${frontmatter}\n\n${IMPORTS}\n\n${generatedContent}`;
}
/**
* Convert operationId to a human-readable title.
* e.g., "getOrCreate" -> "Get Or Create"
*/
function formatOperationIdAsTitle(operationId: string): string {
// Split on camelCase boundaries
const words = operationId
.replace(/([a-z])([A-Z])/g, "$1 $2")
.split(/[\s_-]+/);
// Capitalize first letter of each word
return words
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ");
}

View File

@@ -0,0 +1,626 @@
import { readFileSync } from "node:fs";
import yaml from "yaml";
export interface SchemaField {
name: string;
type: string;
description?: string;
required: boolean;
children?: SchemaField[];
enumValues?: string[];
}
export interface ParsedOperation {
operationId: string;
tag: string;
method: string;
path: string;
summary?: string;
description?: string;
requestBody?: SchemaField[];
responses?: {
[statusCode: string]: SchemaField[];
};
/** Raw response schema for generating sample JSON */
responseSchemas?: {
[statusCode: string]: Record<string, unknown>;
};
/** Response examples extracted from the OpenAPI spec (already in snake_case) */
responseExamples?: {
[statusCode: string]: unknown;
};
/** Reference to all schemas for sample JSON generation */
allSchemas?: Record<string, unknown>;
}
interface OpenApiDocument {
components?: {
schemas?: Record<string, unknown>;
};
paths?: Record<string, Record<string, unknown>>;
}
/**
* Parse an OpenAPI YAML file and extract operation details.
*/
export function parseOpenApi({
openApiPath,
}: {
openApiPath: string;
}): ParsedOperation[] {
const content = readFileSync(openApiPath, "utf-8");
const doc = yaml.parse(content) as OpenApiDocument;
const operations: ParsedOperation[] = [];
const schemas = doc.components?.schemas ?? {};
for (const [path, pathItem] of Object.entries(doc.paths ?? {})) {
for (const [method, operationObj] of Object.entries(pathItem)) {
if (method === "parameters" || method === "$ref") continue;
const operation = operationObj as Record<string, unknown>;
const operationId = operation.operationId as string | undefined;
const tags = operation.tags as string[] | undefined;
const tag = tags?.[0] ?? "misc";
if (!operationId) continue;
const parsed: ParsedOperation = {
operationId,
tag,
method: method.toUpperCase(),
path,
summary: operation.summary as string | undefined,
description: operation.description as string | undefined,
};
// Parse request body
const requestBody = operation.requestBody as
| Record<string, unknown>
| undefined;
if (requestBody) {
const content = requestBody.content as
| Record<string, unknown>
| undefined;
const jsonContent = content?.["application/json"] as
| Record<string, unknown>
| undefined;
const schema = jsonContent?.schema as
| Record<string, unknown>
| undefined;
if (schema) {
parsed.requestBody = parseSchema({
schema,
schemas,
requiredFields: (schema.required as string[]) ?? [],
});
}
}
// Parse responses
const responses = operation.responses as
| Record<string, unknown>
| undefined;
if (responses) {
parsed.responses = {};
parsed.responseSchemas = {};
parsed.responseExamples = {};
for (const [statusCode, responseObj] of Object.entries(responses)) {
const response = responseObj as Record<string, unknown>;
const content = response.content as
| Record<string, unknown>
| undefined;
const jsonContent = content?.["application/json"] as
| Record<string, unknown>
| undefined;
const schema = jsonContent?.schema as
| Record<string, unknown>
| undefined;
if (schema) {
parsed.responses[statusCode] = parseSchema({
schema,
schemas,
requiredFields: (schema.required as string[]) ?? [],
});
// Store raw schema for sample JSON generation
parsed.responseSchemas[statusCode] = schema;
}
// Extract response example (could be at content level or schema level)
const example =
jsonContent?.example ??
jsonContent?.examples?.[0] ??
resolveSchemaExample({ schema: schema ?? {}, schemas });
if (example) {
parsed.responseExamples[statusCode] = example;
}
}
}
// Store reference to all schemas for sample JSON generation
parsed.allSchemas = schemas;
operations.push(parsed);
}
}
return operations;
}
/**
* Resolves an example from a schema, following $ref if needed.
*/
function resolveSchemaExample({
schema,
schemas,
}: {
schema: Record<string, unknown>;
schemas: Record<string, unknown>;
}): unknown {
// Check for examples array
if (
schema.examples &&
Array.isArray(schema.examples) &&
schema.examples.length > 0
) {
return schema.examples[0];
}
// Check for single example
if (schema.example !== undefined) {
return schema.example;
}
// Follow $ref
if (schema.$ref && typeof schema.$ref === "string") {
const refName = schema.$ref.replace("#/components/schemas/", "");
const refSchema = schemas[refName] as Record<string, unknown> | undefined;
if (refSchema) {
return resolveSchemaExample({ schema: refSchema, schemas });
}
}
return undefined;
}
/**
* Parse a schema and return a list of fields.
*/
function parseSchema({
schema,
schemas,
requiredFields,
visited = new Set<string>(),
}: {
schema: Record<string, unknown>;
schemas: Record<string, unknown>;
requiredFields: string[];
visited?: Set<string>;
}): SchemaField[] {
// Handle $ref
if (schema.$ref) {
const refPath = schema.$ref as string;
const refName = refPath.replace("#/components/schemas/", "");
// Prevent infinite recursion
if (visited.has(refName)) {
return [];
}
visited.add(refName);
const refSchema = schemas[refName] as Record<string, unknown> | undefined;
if (refSchema) {
return parseSchema({
schema: refSchema,
schemas,
requiredFields: (refSchema.required as string[]) ?? [],
visited,
});
}
return [];
}
// Handle anyOf/oneOf (common for nullable types)
if (schema.anyOf || schema.oneOf) {
const variants = (schema.anyOf ?? schema.oneOf) as Record<
string,
unknown
>[];
// Find the non-null variant
const nonNullVariant = variants.find(
(v) => v.type !== "null" && !v.$ref?.toString().includes("null"),
);
if (nonNullVariant) {
return parseSchema({
schema: nonNullVariant,
schemas,
requiredFields,
visited,
});
}
return [];
}
// Handle object type
if (schema.type === "object" && schema.properties) {
const properties = schema.properties as Record<string, unknown>;
const fields: SchemaField[] = [];
for (const [propName, propSchema] of Object.entries(properties)) {
const prop = propSchema as Record<string, unknown>;
const field = parseField({
name: propName,
schema: prop,
schemas,
required: requiredFields.includes(propName),
visited: new Set(visited),
});
if (field) {
fields.push(field);
}
}
return fields;
}
// Handle array type - return the items as a single field
if (schema.type === "array" && schema.items) {
const items = schema.items as Record<string, unknown>;
const itemFields = parseSchema({
schema: items,
schemas,
requiredFields: (items.required as string[]) ?? [],
visited,
});
// Return array items as children of a virtual "items" field
if (itemFields.length > 0) {
return [
{
name: "items",
type: "object",
description: "Array item",
required: false,
children: itemFields,
},
];
}
}
return [];
}
/**
* Parse a single field from a schema property.
*/
function parseField({
name,
schema,
schemas,
required,
visited,
}: {
name: string;
schema: Record<string, unknown>;
schemas: Record<string, unknown>;
required: boolean;
visited: Set<string>;
}): SchemaField | null {
let type = resolveType(schema, schemas);
let description = schema.description as string | undefined;
let children: SchemaField[] | undefined;
let enumValues: string[] | undefined;
// Handle $ref
if (schema.$ref) {
const refPath = schema.$ref as string;
const refName = refPath.replace("#/components/schemas/", "");
if (visited.has(refName)) {
return { name, type: refName, description, required };
}
visited.add(refName);
const refSchema = schemas[refName] as Record<string, unknown> | undefined;
if (refSchema) {
type = resolveType(refSchema, schemas);
description =
description ?? (refSchema.description as string | undefined);
// Check for enum
if (refSchema.enum) {
enumValues = refSchema.enum as string[];
}
// Check for nested object
if (refSchema.type === "object" && refSchema.properties) {
children = parseSchema({
schema: refSchema,
schemas,
requiredFields: (refSchema.required as string[]) ?? [],
visited,
});
}
}
}
// Handle anyOf/oneOf (nullable types)
if (schema.anyOf || schema.oneOf) {
const variants = (schema.anyOf ?? schema.oneOf) as Record<
string,
unknown
>[];
const hasNull = variants.some((v) => v.type === "null");
const nonNullVariant = variants.find((v) => v.type !== "null");
if (nonNullVariant) {
const innerField = parseField({
name,
schema: nonNullVariant,
schemas,
required,
visited,
});
if (innerField) {
// Append "| null" if nullable
if (hasNull) {
innerField.type = `${innerField.type} | null`;
}
// Preserve description from parent schema if inner doesn't have one
if (!innerField.description && description) {
innerField.description = description;
}
return innerField;
}
}
return {
name,
type: hasNull ? "any | null" : "any",
description,
required,
};
}
// Handle enum
if (schema.enum) {
enumValues = schema.enum as string[];
}
// Handle nested object
if (schema.type === "object" && schema.properties) {
children = parseSchema({
schema,
schemas,
requiredFields: (schema.required as string[]) ?? [],
visited,
});
}
// Handle array
if (schema.type === "array" && schema.items) {
const items = schema.items as Record<string, unknown>;
const itemType = resolveType(items, schemas);
type = `${itemType}[]`;
// Check if array items have properties
if (items.type === "object" && items.properties) {
children = parseSchema({
schema: items,
schemas,
requiredFields: (items.required as string[]) ?? [],
visited,
});
} else if (items.$ref) {
const refPath = items.$ref as string;
const refName = refPath.replace("#/components/schemas/", "");
const refSchema = schemas[refName] as Record<string, unknown> | undefined;
if (refSchema && refSchema.type === "object" && refSchema.properties) {
children = parseSchema({
schema: refSchema,
schemas,
requiredFields: (refSchema.required as string[]) ?? [],
visited: new Set(visited),
});
}
}
}
return {
name,
type,
description,
required,
children,
enumValues,
};
}
/**
* Resolve the type string for a schema.
*/
function resolveType(
schema: Record<string, unknown>,
schemas: Record<string, unknown>,
): string {
if (schema.$ref) {
const refPath = schema.$ref as string;
const refName = refPath.replace("#/components/schemas/", "");
const refSchema = schemas[refName] as Record<string, unknown> | undefined;
if (refSchema) {
// If it's an enum, return "enum"
if (refSchema.enum) {
return "enum";
}
// Otherwise return the underlying type
return resolveType(refSchema, schemas);
}
return refName;
}
if (schema.anyOf || schema.oneOf) {
const variants = (schema.anyOf ?? schema.oneOf) as Record<
string,
unknown
>[];
const nonNullVariant = variants.find((v) => v.type !== "null");
if (nonNullVariant) {
return resolveType(nonNullVariant, schemas);
}
return "any";
}
if (schema.type === "array") {
const items = schema.items as Record<string, unknown> | undefined;
if (items) {
return `${resolveType(items, schemas)}[]`;
}
return "array";
}
return (schema.type as string) ?? "any";
}
/**
* Generate a sample JSON object from a schema for documentation examples.
* Returns a simplified sample that shows the structure without excessive nesting.
*/
export function generateSampleJson({
schema,
schemas,
visited = new Set<string>(),
depth = 0,
}: {
schema: Record<string, unknown>;
schemas: Record<string, unknown>;
visited?: Set<string>;
depth?: number;
}): unknown {
// Prevent infinite recursion and excessive depth
// For deep nesting, return placeholder to keep output manageable
if (depth > 3) {
return "...";
}
// Check for examples defined on the schema (use first example if available)
if (
schema.examples &&
Array.isArray(schema.examples) &&
schema.examples.length > 0
) {
return schema.examples[0];
}
// Check for single example
if (schema.example !== undefined) {
return schema.example;
}
// Handle $ref
if (schema.$ref) {
const refPath = schema.$ref as string;
const refName = refPath.replace("#/components/schemas/", "");
if (visited.has(refName)) {
return "..."; // Circular reference placeholder
}
const newVisited = new Set(visited);
newVisited.add(refName);
const refSchema = schemas[refName] as Record<string, unknown> | undefined;
if (refSchema) {
return generateSampleJson({
schema: refSchema,
schemas,
visited: newVisited,
depth: depth + 1,
});
}
return null;
}
// Handle anyOf/oneOf (pick non-null variant)
if (schema.anyOf || schema.oneOf) {
const variants = (schema.anyOf ?? schema.oneOf) as Record<
string,
unknown
>[];
const nonNullVariant = variants.find(
(v) => v.type !== "null" && !("const" in v && v.const === null),
);
if (nonNullVariant) {
return generateSampleJson({
schema: nonNullVariant,
schemas,
visited,
depth,
});
}
return null;
}
// Handle enum - return first value
if (schema.enum) {
const enumValues = schema.enum as unknown[];
return enumValues[0] ?? null;
}
// Handle const
if ("const" in schema) {
return schema.const;
}
// Handle object type
if (schema.type === "object") {
const properties = schema.properties as Record<string, unknown> | undefined;
if (!properties) {
return {};
}
const result: Record<string, unknown> = {};
for (const [propName, propSchema] of Object.entries(properties)) {
result[propName] = generateSampleJson({
schema: propSchema as Record<string, unknown>,
schemas,
visited: new Set(visited), // Fresh set for each property to avoid false positives
depth: depth + 1,
});
}
return result;
}
// Handle array type
if (schema.type === "array") {
const items = schema.items as Record<string, unknown> | undefined;
if (items) {
return [
generateSampleJson({
schema: items,
schemas,
visited: new Set(visited),
depth: depth + 1,
}),
];
}
return [];
}
// Handle primitive types with example values
switch (schema.type) {
case "string":
return "<string>";
case "number":
case "integer":
return 123;
case "boolean":
return true;
default:
return null;
}
}

View File

@@ -0,0 +1,178 @@
import yaml from "yaml";
/**
* Strips JSDoc tags from a description string.
* Returns content up to the first @ tag (trimmed).
*/
function stripJsDocTags(description: string): string {
// Find the first @ tag that starts a line (common JSDoc tags)
const tagPatterns = [
/@example\b/,
/@param\b/,
/@see\b/,
/@returns?\b/,
/@throws?\b/,
/@deprecated\b/,
/@since\b/,
/@version\b/,
/@author\b/,
/@link\b/,
/@type\b/,
/@typedef\b/,
/@property\b/,
/@default\b/,
];
let cutIndex = description.length;
for (const pattern of tagPatterns) {
const match = description.match(pattern);
if (match && match.index !== undefined && match.index < cutIndex) {
cutIndex = match.index;
}
}
return description.slice(0, cutIndex).trim();
}
/**
* Transforms SDK code sample from Speakeasy format to autumn-js format.
*/
function transformCodeSample(source: string): string {
// Replace import
let result = source.replace(
/import \{ Autumn \} from "@useautumn\/sdk";/g,
"import { Autumn } from 'autumn-js'"
);
// Replace initialization with simpler version
result = result.replace(
/const autumn = new Autumn\(\{[\s\S]*?\}\);/g,
"const autumn = new Autumn()"
);
// Remove async wrapper function - extract the inner content
const asyncWrapperMatch = result.match(
/async function run\(\) \{([\s\S]*?)\}\s*\n\s*run\(\);/
);
if (asyncWrapperMatch) {
const innerContent = asyncWrapperMatch[1]
.split("\n")
.map((line) => {
// Remove 2 spaces of indentation from the wrapper
if (line.startsWith(" ")) {
return line.slice(2);
}
return line;
})
.join("\n")
.trim();
result = result.replace(asyncWrapperMatch[0], innerContent);
}
// Remove console.log
result = result.replace(/\s*console\.log\(result\);?/g, "");
// Clean up extra blank lines
result = result.replace(/\n{3,}/g, "\n\n").trim();
return result;
}
/**
* Recursively walks the OpenAPI document and applies transformations.
*/
function transformNode(node: unknown, schemas?: Record<string, unknown>): void {
if (Array.isArray(node)) {
for (const item of node) {
transformNode(item, schemas);
}
return;
}
if (typeof node !== "object" || node === null) {
return;
}
const record = node as Record<string, unknown>;
// Transform descriptions to strip JSDoc tags
if (typeof record.description === "string") {
record.description = stripJsDocTags(record.description);
}
// Transform code samples
if (Array.isArray(record["x-codeSamples"])) {
for (const sample of record["x-codeSamples"]) {
if (
typeof sample === "object" &&
sample !== null &&
typeof (sample as Record<string, unknown>).source === "string"
) {
const sampleRecord = sample as Record<string, unknown>;
sampleRecord.source = transformCodeSample(sampleRecord.source as string);
}
}
}
// Copy schema examples to response content level for Mintlify
if (schemas && record.content) {
const content = record.content as Record<string, unknown>;
const jsonContent = content["application/json"] as Record<string, unknown> | undefined;
if (jsonContent?.schema && !jsonContent.example && !jsonContent.examples) {
const schema = jsonContent.schema as Record<string, unknown>;
const example = resolveSchemaExample(schema, schemas);
if (example) {
jsonContent.example = example;
}
}
}
// Recurse into nested objects
for (const value of Object.values(record)) {
transformNode(value, schemas);
}
}
/**
* Resolves an example from a schema, following $ref if needed.
*/
function resolveSchemaExample(
schema: Record<string, unknown>,
schemas: Record<string, unknown>
): unknown {
// Check for examples array
if (schema.examples && Array.isArray(schema.examples) && schema.examples.length > 0) {
return schema.examples[0];
}
// Check for single example
if (schema.example !== undefined) {
return schema.example;
}
// Follow $ref
if (schema.$ref && typeof schema.$ref === "string") {
const refName = schema.$ref.replace("#/components/schemas/", "");
const refSchema = schemas[refName] as Record<string, unknown> | undefined;
if (refSchema) {
return resolveSchemaExample(refSchema, schemas);
}
}
return undefined;
}
/**
* Transforms an OpenAPI YAML document for Mintlify consumption.
*
* - Strips JSDoc tags from descriptions
* - Transforms Speakeasy code samples to use autumn-js format
* - Copies schema examples to response content level
*/
export function transformOpenApiForMintlify(yamlContent: string): string {
const doc = yaml.parse(yamlContent) as Record<string, unknown>;
const schemas = (doc.components as Record<string, unknown>)?.schemas as Record<string, unknown> | undefined;
transformNode(doc, schemas);
return yaml.stringify(doc);
}

View File

@@ -0,0 +1,200 @@
import { JSON_SCHEMA_INPUT_REGISTRY } from "@orpc/zod/zod4";
import type { z } from "zod/v4";
import { globalRegistry } from "zod/v4/core";
/**
* Recursively walks a Zod schema and registers any schemas marked with
* `.meta({ internal: true })` in the JSON_SCHEMA_INPUT_REGISTRY with
* `x-internal: true`. This allows `removeInternalFields()` to strip them
* from the generated OpenAPI spec.
*
* Note: This approach has limitations with schema transformations like
* `.omit()`, `.extend()`, `.refine()` which create new schema instances.
* For reliable internal field removal, use the INTERNAL_FIELD_NAMES
* list in openapi2.1.ts which removes fields by name.
*/
export function registerInternalSchemas(schema: z.ZodType): void {
const visited = new WeakSet<z.ZodType>();
walkSchema(schema, visited);
}
function walkSchema(schema: z.ZodType, visited: WeakSet<z.ZodType>): void {
if (visited.has(schema)) return;
visited.add(schema);
// Check if this schema has internal: true in its metadata
const meta = globalRegistry.get(schema);
if (meta?.internal === true) {
// Register with x-internal so removeInternalFields() can find it
// biome-ignore lint/suspicious/noExplicitAny: TypeScript types are restrictive but runtime accepts arbitrary props
JSON_SCHEMA_INPUT_REGISTRY.add(schema, { "x-internal": true } as any);
}
// Get the internal Zod definition to traverse nested schemas
// biome-ignore lint/suspicious/noExplicitAny: accessing Zod internals
const def = (schema as any)._zod?.def ?? (schema as any)._def;
if (!def) return;
// Handle different Zod schema types
switch (def.type ?? def.typeName) {
case "object":
case "ZodObject": {
const shape = def.shape;
if (shape && typeof shape === "object") {
for (const fieldSchema of Object.values(shape)) {
if (isZodType(fieldSchema)) {
walkSchema(fieldSchema, visited);
}
}
}
break;
}
case "array":
case "ZodArray": {
const element = def.element ?? def.type;
if (isZodType(element)) {
walkSchema(element, visited);
}
break;
}
case "optional":
case "ZodOptional":
case "nullable":
case "ZodNullable":
case "readonly":
case "ZodReadonly": {
const innerType = def.innerType ?? def.unwrapped;
if (isZodType(innerType)) {
walkSchema(innerType, visited);
}
break;
}
case "union":
case "ZodUnion":
case "discriminatedUnion":
case "ZodDiscriminatedUnion": {
const options = def.options;
if (Array.isArray(options)) {
for (const option of options) {
if (isZodType(option)) {
walkSchema(option, visited);
}
}
}
break;
}
case "intersection":
case "ZodIntersection": {
if (isZodType(def.left)) walkSchema(def.left, visited);
if (isZodType(def.right)) walkSchema(def.right, visited);
break;
}
case "tuple":
case "ZodTuple": {
const items = def.items;
if (Array.isArray(items)) {
for (const item of items) {
if (isZodType(item)) {
walkSchema(item, visited);
}
}
}
if (isZodType(def.rest)) {
walkSchema(def.rest, visited);
}
break;
}
case "record":
case "ZodRecord": {
if (isZodType(def.keyType)) walkSchema(def.keyType, visited);
if (isZodType(def.valueType)) walkSchema(def.valueType, visited);
break;
}
case "map":
case "ZodMap": {
if (isZodType(def.keyType)) walkSchema(def.keyType, visited);
if (isZodType(def.valueType)) walkSchema(def.valueType, visited);
break;
}
case "set":
case "ZodSet": {
if (isZodType(def.valueType)) walkSchema(def.valueType, visited);
break;
}
case "lazy":
case "ZodLazy": {
// For lazy schemas, we need to get the actual schema
const getter = def.getter;
if (typeof getter === "function") {
try {
const lazySchema = getter();
if (isZodType(lazySchema)) {
walkSchema(lazySchema, visited);
}
} catch {
// Ignore errors from lazy evaluation
}
}
break;
}
case "effects":
case "ZodEffects":
case "ZodPipeline": {
const innerSchema = def.schema ?? def.in;
if (isZodType(innerSchema)) {
walkSchema(innerSchema, visited);
}
break;
}
case "default":
case "ZodDefault":
case "catch":
case "ZodCatch": {
const innerType = def.innerType;
if (isZodType(innerType)) {
walkSchema(innerType, visited);
}
break;
}
case "branded":
case "ZodBranded": {
const brandedType = def.type;
if (isZodType(brandedType)) {
walkSchema(brandedType, visited);
}
break;
}
case "promise":
case "ZodPromise": {
const promiseType = def.type;
if (isZodType(promiseType)) {
walkSchema(promiseType, visited);
}
break;
}
}
}
function isZodType(value: unknown): value is z.ZodType {
if (!value || typeof value !== "object") return false;
// Check for Zod v4 structure
// biome-ignore lint/suspicious/noExplicitAny: checking Zod internals
const v = value as any;
return (
(v._zod !== undefined && typeof v._zod === "object") ||
(v._def !== undefined && typeof v._def === "object")
);
}

View File

@@ -14,6 +14,13 @@ export const getOrCreateCustomerContract = oc
.input(
ExtCreateCustomerParamsSchema.meta({
title: "GetOrCreateCustomerParams",
examples: [
{
customer_id: "cus_123",
name: "John Doe",
email: "john@example.com",
},
],
}),
)
.output(ApiCustomerV5Schema);

View File

@@ -1,7 +1,11 @@
import { writeFileSync } from "node:fs";
import { registerInternalSchemas } from "@api/_openapi/utils/registerInternalSchemas.js";
import { AttachParamsV0Schema } from "@api/billing/attachV2/attachParamsV0.js";
import { BillingResponseSchema } from "@api/billing/common/billingResponse.js";
import { CustomerIdSchema } from "@api/common/customerId.js";
import { ApiCustomerV5Schema } from "@api/customers/apiCustomerV5.js";
import { CustomerExpandEnum } from "@api/customers/components/customerExpand/customerExpand.js";
import { ExtCreateCustomerParamsSchema } from "@api/customers/crud/createCustomerParams.js";
import { CustomerDataSchema } from "@api/models.js";
import { ApiPlanV1Schema } from "@api/products/apiPlanV1.js";
import { OpenAPIGenerator } from "@orpc/openapi";
@@ -113,6 +117,32 @@ const applySpeakeasySettings = ({
};
};
/**
* Fields that should be stripped from the public OpenAPI spec.
* These are internal fields marked with `.meta({ internal: true })` in schemas.
*/
const INTERNAL_FIELD_NAMES = new Set([
// Customer params internal fields
"entity_id",
"entity_data",
"id",
"with_autumn_id",
"internal_options",
"processors",
// Customer feature internal fields
"feature_type",
"feature",
"display",
"usage_limit",
"config",
"created_at",
"entitlement_id",
"price_id",
"price_config",
// Customer response internal field
"autumn_id",
]);
const removeInternalFields = ({
openApiDocument,
}: {
@@ -157,11 +187,15 @@ const removeInternalFields = ({
: null;
for (const [propertyName, propertySchema] of Object.entries(properties)) {
if (!isInternalNode(propertySchema)) continue;
// Remove fields marked with x-internal or internal, OR fields in the internal names list
if (
isInternalNode(propertySchema) ||
INTERNAL_FIELD_NAMES.has(propertyName)
) {
delete properties[propertyName];
requiredSet?.delete(propertyName);
}
}
if (requiredSet) {
node.required = [...requiredSet];
@@ -189,6 +223,15 @@ export const writeOpenApi_2_1_0 = async ({
}: {
outputFilePath: string;
}) => {
// Register internal schemas before generation so they get x-internal: true
// in the OpenAPI output, which removeInternalFields() will then strip
registerInternalSchemas(ExtCreateCustomerParamsSchema);
registerInternalSchemas(AttachParamsV0Schema);
registerInternalSchemas(BillingResponseSchema);
registerInternalSchemas(ApiCustomerV5Schema);
registerInternalSchemas(ApiPlanV1Schema);
registerInternalSchemas(CustomerDataSchema);
const openApiDocument = (await generator.generate(v2_1ContractRouter, {
info: {
title: "Autumn API",

View File

@@ -1,7 +1,9 @@
import { execSync } from "node:child_process";
import { mkdirSync } from "node:fs";
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { generateApiReference } from "./_openapi/utils/apiReferenceGenerator/index.js";
import { transformOpenApiForMintlify } from "./_openapi/utils/mintlifyTransform.js";
// Dynamic imports to avoid duplicate schema registration when supporting multiple versions
@@ -57,7 +59,7 @@ if (process.env.NODE_ENV !== "production") {
currentDirPath,
"../../apps/docs/mintlify/api",
);
const docsOpenApiLocalPath = path.join(docsApiDirPath, "openapi-local.yml");
const docsOpenApiPath = path.join(docsApiDirPath, "openapi.yml");
mkdirSync(outputDirPath, { recursive: true });
mkdirSync(docsApiDirPath, { recursive: true });
@@ -115,13 +117,33 @@ if (process.env.NODE_ENV !== "production") {
console.log("Applying Speakeasy code samples to OpenAPI for docs...");
execSync(
`bunx speakeasy overlay apply --schema .speakeasy/out.openapi.yaml --overlay .speakeasy/code-samples.overlay.yaml --out ${JSON.stringify(docsOpenApiLocalPath)}`,
`bunx speakeasy overlay apply --schema .speakeasy/out.openapi.yaml --overlay .speakeasy/code-samples.overlay.yaml --out ${JSON.stringify(docsOpenApiPath)}`,
{
stdio: "inherit",
cwd: speakeasySdkDirPath,
},
);
console.log(`Docs OpenAPI written to ${docsOpenApiLocalPath}`);
console.log(`Docs OpenAPI written to ${docsOpenApiPath}`);
// Transform OpenAPI for Mintlify (strip JSDoc tags, fix code samples)
console.log("Transforming OpenAPI for Mintlify docs...");
const yamlContent = readFileSync(docsOpenApiPath, "utf-8");
const transformedYaml = transformOpenApiForMintlify(yamlContent);
writeFileSync(docsOpenApiPath, transformedYaml);
console.log("Mintlify transformation complete");
// Generate API reference MDX files with dynamic parameter fields
console.log("Generating API reference MDX files...");
const manualMdxDir = path.resolve(
docsApiDirPath,
"../../api-reference-generator",
);
const outputMdxDir = path.resolve(docsApiDirPath, "../api-reference");
await generateApiReference({
openApiPath: docsOpenApiPath,
manualMdxDir,
outputDir: outputMdxDir,
});
} else {
console.log(
`Skipping Speakeasy generation for OpenAPI ${version}; only 2.1.0 is wired to SDK generation`,

View File

@@ -7,6 +7,38 @@ import {
ApiSubscriptionV1Schema,
} from "./cusPlans/apiSubscriptionV1.js";
export const API_CUSTOMER_V5_EXAMPLE = {
id: "cus_123",
created_at: 1717000000,
name: "John Doe",
email: "john@example.com",
fingerprint: "1234567890",
stripe_id: "cus_123",
env: "sandbox",
metadata: {},
subscriptions: [
{
id: "sub_123",
created_at: 1717000000,
plan_id: "plan_123",
status: "active",
quantity: 1,
interval: "month",
interval_count: 1,
},
],
purchases: [],
balances: {
balance_1: {
id: "balance_1",
amount: 100,
currency: "USD",
created_at: 1717000000,
updated_at: 1717000000,
},
},
};
// V5 base customer - uses V1 subscriptions (single array with status field) and V1 balances
export const BaseApiCustomerV5Schema = BaseApiCustomerSchema.extend({
subscriptions: z.array(ApiSubscriptionV1Schema),
@@ -16,7 +48,9 @@ export const BaseApiCustomerV5Schema = BaseApiCustomerSchema.extend({
export const ApiCustomerV5Schema = BaseApiCustomerV5Schema.extend(
ApiCusExpandSchema.shape,
);
).meta({
examples: [API_CUSTOMER_V5_EXAMPLE],
});
export type ApiCustomerV5 = z.infer<typeof ApiCustomerV5Schema>;
export type BaseApiCustomerV5 = z.infer<typeof BaseApiCustomerV5Schema>;

View File

@@ -5,15 +5,34 @@ export const BaseApiCustomerSchema = z.object({
autumn_id: z.string().optional().meta({
internal: true,
}),
id: z.string().nullable(),
name: z.string().nullable(),
email: z.string().nullable(),
created_at: z.number(),
fingerprint: z.string().nullable(),
stripe_id: z.string().nullable(),
env: z.enum(AppEnv),
metadata: z.record(z.any(), z.any()),
send_email_receipts: z.boolean(),
id: z.string().nullable().meta({
description: "Your unique identifier for the customer.",
}),
name: z.string().nullable().meta({
description: "The name of the customer.",
}),
email: z.string().nullable().meta({
description: "The email address of the customer.",
}),
created_at: z.number().meta({
description: "Timestamp of customer creation in milliseconds since epoch.",
}),
fingerprint: z.string().nullable().meta({
description:
"A unique identifier (eg. serial number) to de-duplicate customers across devices or browsers. For example: apple device ID.",
}),
stripe_id: z.string().nullable().meta({
description: "Stripe customer ID.",
}),
env: z.enum(AppEnv).meta({
description: "The environment this customer was created in.",
}),
metadata: z.record(z.any(), z.any()).meta({
description: "The metadata for the customer.",
}),
send_email_receipts: z.boolean().meta({
description: "Whether to send email receipts to the customer.",
}),
});
export type BaseApiCustomer = z.infer<typeof BaseApiCustomerSchema>;

View File

@@ -22,8 +22,9 @@ export const CreateCustomerQuerySchema = z.object({
export const ExtCreateCustomerParamsSchema = z
.object({
customer_id: CustomerIdSchema.nullable(),
...CustomerDataSchema.shape,
})
.extend(CustomerDataSchema.shape)
.extend({
expand: CustomerExpandArraySchema.optional(),

View File

@@ -50,39 +50,9 @@ components:
auto_enable_plan_id:
type: string
description: The ID of the free plan to auto-enable for the customer
processors:
anyOf:
- type: object
properties:
vercel:
type: object
properties:
installation_id:
type: string
access_token:
type: string
account_id:
type: string
custom_payment_method_id:
type: string
required:
- installation_id
- access_token
- account_id
- type: "null"
description: External processors for the customer
send_email_receipts:
type: boolean
description: Whether to send email receipts to this customer
internal_options:
type: object
properties:
default_group:
type: string
description: The group of products to attach to the customer
disable_defaults:
type: boolean
description: Whether to disable default products
title: CustomerData
description: Customer details to set when creating a customer
CustomerExpand:
@@ -100,40 +70,40 @@ components:
Customer:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
name:
anyOf:
- type: string
- type: "null"
description: The name of the customer.
email:
anyOf:
- type: string
- type: "null"
created_at:
type: number
description: The email address of the customer.
fingerprint:
anyOf:
- type: string
- type: "null"
description: "A unique identifier (eg. serial number) to de-duplicate customers
across devices or browsers. For example: apple device ID."
stripe_id:
anyOf:
- type: string
- type: "null"
description: Stripe customer ID.
env:
enum:
- sandbox
- live
description: The environment this customer was created in.
metadata:
type: object
propertyNames: {}
additionalProperties: {}
description: The metadata for the customer.
send_email_receipts:
type: boolean
description: Whether to send email receipts to the customer.
subscriptions:
type: array
items:
@@ -222,55 +192,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
name:
type: string
type:
enum:
- boolean
- metered
- credit_system
consumable:
type: boolean
event_names:
type: array
items:
type: string
credit_schema:
type: array
items:
type: object
properties:
metered_feature_id:
type: string
credit_cost:
type: number
required:
- metered_feature_id
- credit_cost
display:
type: object
properties:
singular:
anyOf:
- type: string
- type: "null"
plural:
anyOf:
- type: string
- type: "null"
archived:
type: boolean
required:
- id
- name
- type
- consumable
- archived
granted:
type: number
remaining:
@@ -295,9 +216,6 @@ components:
items:
type: object
properties:
id:
type: string
default: ""
plan_id:
anyOf:
- type: string
@@ -431,9 +349,6 @@ components:
currency:
type: string
description: The currency code for the invoice
created_at:
type: number
description: Timestamp when the invoice was created
hosted_invoice_url:
anyOf:
- type: string
@@ -445,19 +360,11 @@ components:
- status
- total
- currency
- created_at
entities:
type: array
items:
type: object
properties:
autumn_id:
type: string
id:
anyOf:
- type: string
- type: "null"
description: The unique identifier of the entity
name:
anyOf:
- type: string
@@ -473,18 +380,13 @@ components:
- type: string
- type: "null"
description: The feature ID this entity belongs to
created_at:
type: number
description: Unix timestamp when the entity was created
env:
enum:
- sandbox
- live
description: The environment (sandbox/live)
required:
- id
- name
- created_at
- env
trials_used:
type: array
@@ -511,9 +413,6 @@ components:
items:
type: object
properties:
id:
type: string
description: The unique identifier for this discount
name:
type: string
description: The name of the discount or coupon
@@ -565,7 +464,6 @@ components:
- type: "null"
description: Total amount saved from this discount
required:
- id
- name
- type
- discount_value
@@ -584,8 +482,6 @@ components:
customer:
type: object
properties:
id:
type: string
name:
anyOf:
- type: string
@@ -594,26 +490,20 @@ components:
anyOf:
- type: string
- type: "null"
required:
- id
required: []
reward_applied:
type: boolean
created_at:
type: number
required:
- program_id
- customer
- reward_applied
- created_at
payment_method:
anyOf:
- {}
- type: "null"
required:
- id
- name
- email
- created_at
- fingerprint
- stripe_id
- env
@@ -622,11 +512,34 @@ components:
- subscriptions
- purchases
- balances
examples:
- id: cus_123
created_at: 1717000000
name: John Doe
email: john@example.com
fingerprint: "1234567890"
stripe_id: cus_123
env: sandbox
metadata: {}
subscriptions:
- id: sub_123
created_at: 1717000000
plan_id: plan_123
status: active
quantity: 1
interval: month
interval_count: 1
purchases: []
balances:
balance_1:
id: balance_1
amount: 100
currency: USD
created_at: 1717000000
updated_at: 1717000000
Plan:
type: object
properties:
id:
type: string
name:
type: string
description:
@@ -659,15 +572,6 @@ components:
- year
interval_count:
type: number
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
required:
- amount
- interval
@@ -679,66 +583,6 @@ components:
properties:
feature_id:
type: string
feature:
type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like
/track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
included:
type: number
unlimited:
@@ -809,15 +653,6 @@ components:
- billing_method
- max_purchase
- type: "null"
display:
type: object
properties:
primary_text:
type: string
secondary_text:
type: string
required:
- primary_text
rollover:
type: object
properties:
@@ -872,8 +707,6 @@ components:
- duration_length
- duration_type
- card_required
created_at:
type: number
env:
enum:
- sandbox
@@ -903,7 +736,6 @@ components:
required:
- scenario
required:
- id
- name
- description
- group
@@ -912,7 +744,6 @@ components:
- auto_enable
- price
- items
- created_at
- env
- archived
- base_variant_id
@@ -995,67 +826,21 @@ paths:
auto_enable_plan_id:
type: string
description: The ID of the free plan to auto-enable for the customer
processors:
anyOf:
- type: object
properties:
vercel:
type: object
properties:
installation_id:
type: string
access_token:
type: string
account_id:
type: string
custom_payment_method_id:
type: string
required:
- installation_id
- access_token
- account_id
- type: "null"
description: External processors for the customer
send_email_receipts:
type: boolean
description: Whether to send email receipts to this customer
internal_options:
type: object
properties:
default_group:
type: string
description: The group of products to attach to the customer
disable_defaults:
type: boolean
description: Whether to disable default products
expand:
type: array
items:
$ref: "#/components/schemas/CustomerExpand"
description: Customer expand options
entity_id:
type: string
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
id:
anyOf:
- $ref: "#/components/schemas/CustomerId"
- type: "null"
with_autumn_id:
type: boolean
default: false
required:
- customer_id
title: GetOrCreateCustomerParams
examples:
- customer_id: cus_123
name: John Doe
email: john@example.com
responses:
"200":
description: OK
@@ -1106,21 +891,6 @@ paths:
schema:
type: object
properties:
entity_id:
anyOf:
- type: string
- type: "null"
entity_data:
type: object
properties:
feature_id:
type: string
description: The feature ID that this entity is associated with
name:
type: string
description: Name of the entity
required:
- feature_id
options:
anyOf:
- type: array
@@ -1176,76 +946,6 @@ paths:
- type: "null"
description: The feature ID of the product item. Should be null for fixed price
items.
feature_type:
anyOf:
- enum:
- single_use
- continuous_use
- boolean
- static
- type: "null"
feature:
anyOf:
- type: object
properties:
id:
type: string
description: The ID of the feature, used to refer to it in other API calls like
/track or /check.
name:
anyOf:
- type: string
- type: "null"
description: The name of the feature.
type:
enum:
- static
- boolean
- single_use
- continuous_use
- credit_system
description: The type of the feature
display:
anyOf:
- type: object
properties:
singular:
type: string
description: The singular display name for the feature.
plural:
type: string
description: The plural display name for the feature.
required:
- singular
- plural
- type: "null"
description: Singular and plural display names for the feature.
credit_schema:
anyOf:
- type: array
items:
type: object
properties:
metered_feature_id:
type: string
description: The ID of the metered feature (should be a single_use feature).
credit_cost:
type: number
description: The credit cost of the metered feature.
required:
- metered_feature_id
- credit_cost
- type: "null"
description: Credit cost schema for credit system features.
archived:
anyOf:
- type: boolean
- type: "null"
description: Whether or not the feature is archived.
required:
- id
- type
- type: "null"
included_usage:
anyOf:
- anyOf:
@@ -1323,80 +1023,6 @@ paths:
- type: boolean
- type: "null"
description: Whether the usage should be reset when the product is enabled.
display:
anyOf:
- type: object
properties:
primary_text:
type: string
secondary_text:
anyOf:
- type: string
- type: "null"
required:
- primary_text
- type: "null"
usage_limit:
anyOf:
- type: number
- type: "null"
config:
anyOf:
- type: object
properties:
on_increase:
anyOf:
- enum:
- bill_immediately
- prorate_immediately
- prorate_next_cycle
- bill_next_cycle
- type: "null"
on_decrease:
anyOf:
- enum:
- prorate
- prorate_immediately
- prorate_next_cycle
- none
- no_prorations
- type: "null"
rollover:
anyOf:
- type: object
properties:
max:
anyOf:
- type: number
- type: "null"
duration:
enum:
- month
- forever
default: month
length:
type: number
required:
- max
- length
- type: "null"
- type: "null"
created_at:
anyOf:
- type: number
- type: "null"
entitlement_id:
anyOf:
- type: string
- type: "null"
price_id:
anyOf:
- type: string
- type: "null"
price_config:
anyOf:
- {}
- type: "null"
product_id:
type: string
invoice:
@@ -1437,8 +1063,6 @@ paths:
properties:
customer_id:
type: string
entity_id:
type: string
invoice:
type: object
properties: