This is the full developer documentation for Lark # Quickstart > Setup your billing infrastructure in minutes. import { Callout, Accordion } from "@stainless-api/docs/components"; import { Tabs, TabItem, Steps, LinkButton } from '@astrojs/starlight/components'; import { CopyButton } from '../../components/CopyButton'; import { createSubjectOnSignupPrompt } from '../../prompts/create-subject-on-signup'; import { subscribeCustomerOnSignupPrompt } from '../../prompts/subscribe-customer-on-signup'; import { sendUsageEventsPrompt } from '../../prompts/send-usage-events'; import { exposeCustomerPortalPrompt } from '../../prompts/expose-customer-portal'; **Recommended:** Install the [Lark MCP server](https://github.com/uselark/lark-billing-typescript/tree/next/packages/mcp-server) so that your coding agents can smoothly handle the integration for you. In this guide, we'll create a hybrid (flat-fee + pay-as-you-go) pricing model, implement Lark's customer portal and checkout, and start sending usage to Lark. For this example, we'll create a monthly pricing plan for an AI chat service that costs \$29/month and includes 100 free AI chat requests (then \$0.50 per AI chat request). In Lark, we'll design this pricing model with two components: - A [rate card](/guides/rate_cards/rate_cards) with a \$29 fixed rate and a \$0.50 usage-based rate with 100 included units - A [pricing metric](/guides/pricing/defining-pricing-metrics) to track the number of AI chat requests ### Prerequisite: Install and configure the Lark SDK The [Python SDK](https://pypi.org/project/lark-billing/) and [Typescript SDK](https://www.npmjs.com/package/lark-billing) are publicly available. If you're interested in SDKs for Java, Kotlin, Go, Ruby, C#, or PHP, contact us at team@uselark.ai for access. Install the Lark SDK: `pip install lark-billing` Configure the SDK with your API key: ```python title="Configure the SDK" from lark import Lark lark_client = Lark( api_key=LARK_API_KEY, ) ``` ### Step 1: Create a test subject Subjects are how Lark represents your customers. Typically, you'll create a subject for each customer when they sign up for your service.

```python title="Create a subject" subject = lark_client.subjects.create( external_id="1234567890", # optional name="John Doe", email="john.doe@example.com", ) ``` Setting the `external_id` is optional, but recommended if you don't want to store Lark's subject ID in your system. 1. Go to the subjects page and click "New Subject". 2. Fill in the form with the following values: - Name: `John Doe` - Email: `john.doe@example.com` - (Optional) External ID: `1234567890` Setting the `external_id` is optional, but recommended if you don't want to store Lark's subject ID in your system. 3. Click "Save". ### Step 2: Build the rate card and pricing metric Create a pricing metric to track the number of AI chat requests. We'll use a `count` aggregation type to track the total number of AI chat requests. ```python title="Create pricing metric" pricing_metric = lark_client.pricing_metrics.create( name="AI chat requests", event_name="ai_chat_request", aggregation={"aggregation_type": "count"}, unit="AI chat request", ) ``` 1. Go to the pricing metrics page and click "Create pricing metric". 2. Fill in the form with the following values: - Name: `AI chat requests` - Event Name: `ai_chat_request` - Aggregation Type: `count` - Unit: `AI chat request` 3. Click "Create Metric". Test your pricing metric (optional) You can test your pricing metric by sending a usage event and then retrieving the pricing metric summary. ```python lark_client.usage_events.create( idempotency_key=uuid.uuid4().hex, timestamp=datetime.now(timezone.utc), subject_id="1234567890", event_name="ai_chat_request", data={"foo": "bar"}, ) summary = lark_client.pricing_metrics.create_summary( pricing_metric_id=pricing_metric.id, subject_id=subject.id, period=lark.Period( start=datetime.now(timezone.utc) - timedelta(days=7), end=datetime.now(timezone.utc), ), ) print(summary[0].value) # will be 1 because we sent one usage event ``` You can create a [rate card](/api/resources/rate_cards/methods/create) using the API or the dashboard. ```python title="Create a rate card" rate_card = lark_client.rate_cards.create( name="Starter plan", description="Perfect for small teams.", billing_interval="monthly", fixed_rates=[ { "name": "Base rate", "code": "base_rate", "price": { "type": "flat", "amount": "2900", "currency_code": "usd" } } ], usage_based_rates=[ { "name": "AI chat requests", "code": "ai_chat_requests", "usage_based_rate_type": "simple", "included_units": 100, "price": { "type": "flat", "amount": "50", "currency_code": "usd" }, "pricing_metric_id": pricing_metric.id } ], ) ``` 1. Go to the rate cards page and click "New Rate Card". 2. Set the name and description with the following values: - Name: `Starter plan` - Description: `Perfect for small teams.` - Billing Interval: `Monthly` 3. Add a fixed rate: - Name: `Base rate` - Code: `base_rate` - Price: `$29.00` (flat) 4. Add a usage-based rate: - Name: `AI chat requests` - Code: `ai_chat_requests` - Price: `$0.50` (flat) - Included Units: `100` - Pricing Metric: `AI chat requests` (from the dropdown) 3. Click "Save". `code` is a unique identifier for a rate that ensures quantities and discounts stay the same when a customer upgrades to a new plan or you roll out a new rate card version. ### Step 3: Subscribe customer to the rate card Create a subscription to the Starter Plan rate card. Because the subscription is for a paid plan and the subject does not have a payment method on file, the response will provide a checkout URL to redirect the customer to. You can also choose to subscribe the customer on sign up to a free plan in which case checkout will not be required. This can be useful if your pricing model involves giving every new user some free usage.

```python title="Create a subscription" subscription_response = lark_client.subscriptions.create( subject_id="1234567890", rate_card_id=rate_card.id, fixed_rate_quantities={ "base_rate": 1, }, checkout_callback_urls={ "success_url": "https://example.com/success", "cancelled_url": "https://example.com/cancelled", }, ) print(subscription_response.result.action.checkout_url) # Redirect the customer to this URL to complete the checkout process ``` You can use the following test cards to complete the checkout process: - Visa: 4242 4242 4242 4242 - Mastercard: 5555 5555 5555 4444 - American Express: 3782 822463 10005 - Discover: 6011 1111 1111 1117 - Diners Club: 3056 930902 5904 - JCB: 3530 1113 3330 0000 - UnionPay: 6200 0000 0000 0000 If you are using Adyen, you can find test cards [here](https://docs.adyen.com/development-resources/test-cards-and-credentials/test-card-numbers). Once the customer has completed the checkout, they'll be redirected back to your platform and their new subscription will be reflected in the [billing state](/api/resources/customer_access/methods/retrieve_billing_state). ```python billing_state = lark.customer_access.retrieve_billing_state( subject_id="1234567890", ) print(billing_state.has_active_subscription) # -> True ``` ### Step 4: Send usage events As the customer uses your product, you can [send usage events](/api/resources/usage_events/methods/create) to Lark to track their usage. The idempotency key is a unique identifier for the usage event to ensure the event is only processed once. It can be some identifier in your system (for example an api request id) that is 1:1 with a usage event.

```python lark_client.usage_events.create( timestamp=datetime.now(timezone.utc), idempotency_key="your-unique-idempotency-key", event_name="ai_chat_request", subject_id="1234567890", data={"value": "1"}, ) ``` Now that your customer is subscribed to a rate card and you are reporting usage, invoices will be generated automatically at the end of each billing period. ### (Optional) Expose the customer portal to your customers Lark's hosted [customer portal](/api/resources/customer_portal/methods/create_session) lets your customers view their subscriptions, usage, and invoices and manage their billing information.

```python title="Create a customer portal session" customer_portal_session = lark_client.customer_portal.create_session( subject_id="1234567890", return_url="https://example.com/return", ) print(customer_portal_session.url) # Redirect the customer to this URL to access their customer portal ``` **Want to see a live integration?** Checkout [vibes.uselark.ai](https://vibes.uselark.ai) for which we recently integrated credits based billing in a [single PR](https://github.com/uselark/lark-2025-holidays-demo/pull/1). Try it out to get a feel of the checkout and subscription management flows as an end user. **Need help?** Contact us at team@uselark.ai or [schedule a call](https://calendly.com/founders-uselark/30min). # Usage tracking > Learn how to track usage and bill customers according to their usage. import { Callout } from "@stainless-api/docs/components"; Lark supports sending usage events at a rate of up to 1,000,000 (1M) events per second. If you require higher throughput, please contact us at team@uselark.ai. ### Sending usage events To report usage events you can call the [usage events API](/api/resources/usage_events/methods/create). ```python lark_client.usage_events.create( idempotency_key="your-unique-idempotency-key", timestamp=datetime.now(timezone.utc), event_name="ai_chat_request", subject_id="user_123", data={"value": "1"}, # replace "value" with the aggregation field of your pricing metric ) ``` **Idempotency key**: This is a unique identifier for the usage event to ensure the event is only processed once. It can be some identifier in your system (for example a message id) that is 1:1 with a usage event. **Event name**: The event name of the associated [pricing metric(s)](/api/resources/pricing_metrics/methods/create). **Subject ID**: This is the ID or external ID of the [subject (customer)](/api/resources/subjects/methods/retrieve) for which the usage event is being reported. **Data**: This is the data for the usage event. It should include the aggregation field of the [associated pricing metric(s)](/api/resources/pricing_metrics/methods/create). Optionally, it can include extra key-value pairs that may be used for future pricing metrics. ### Querying usage data To view aggregated usage for a subject over a given period, fetch the [pricing metric summary](/api/resources/pricing_metrics/methods/create_summary). Read more about creating customizable [pricing metric summaries](/guides/pricing/defining-pricing-metrics/#testing-pricing-metrics). ```python summary = lark_client.pricing_metrics.create_summary( pricing_metric_id=pricing_metric.id, subject_id=subject.id, period={ "start": datetime.now(timezone.utc) - timedelta(days=30), "end": datetime.now(timezone.utc), }, ) print(summary) ''' [{ "id": "pmtr_sum_fjxpDpdaPbvA7acpWzD2U3Ax", "pricing_metric_id": "pmtr_HHCFQfe2rKd4Oa1hzX1gDwg1", "subject_id": "subj_wv8qXxM8q0FOQvrKcmikissE", "period": { "inclusive_start": true, "inclusive_end": false, "start": "2025-10-01T00:00:00Z", "end": "2025-11-01T00:00:00Z" }, "value": "27.5" }] ''' ``` # Concepts > Learn about the core concepts of Lark. Lark models your billing integration using a few key domains that work together to create flexible pricing structures. ### Quantity and Usage Events You always bill your customers for a certain quantity of something (seats, API calls, LLM tokens, etc.). This quantity can either be specified directly upfront or inferred from usage events. If you bill your customers based on how much they use your product, usage events help you track their activity. A [usage event](/api/resources/usage_events/methods/create) is a simple record representing customer usage activity. For instance, if you provide an API for an LLM that responds to messages, your usage event might look like this: ```json { "idempotency_key": "1234567890", "event_name": "message", "timestamp": "2025-01-01T00:00:00Z", "subject_id": "user_123", "data": { "input_tokens": "500", "output_tokens": "200", "model": "gpt-4", } } ``` In this example, - `event_name` defines the type of the event as `message` - `subject_id` identifies the user to attribute the usage to. This can be the user's ID in your system or the subject ID created by Lark. - `timestamp` is the time the event occurred - `idempotency_key` is a unique identifier for the event to ensure it is only processed once - `data` contains the values that are used to aggregate the usage. The fields in `data` are defined by the [pricing metrics](/api/resources/pricing_metrics/methods/create) you create. - `data.input_tokens` and `data.output_tokens` are the number of tokens the LLM processed - `data.model` is the LLM used to generate the response Reporting usage events to Lark allows you to track and bill your customers based on their usage. Learn more about [usage tracking](/guides/events/usage_tracking). ### Pricing Metric A [pricing metric](/api/resources/pricing_metrics/methods/create) defines how you aggregate usage events over a service period that gets billed to your customer. For example, you can choose to sum all usage events for a given `event_name` and bill on that total. You can also define pricing metrics using custom expressions for more complex aggregation logic. ### Price A price defines how you convert a quantity into an amount. For example, if you have a simple fee of \$1, a quantity of 10 will translate into a total price of \$10. Lark supports flat fee, tiered, and package prices. Prices can also be defined in custom units (relevant if you use custom credits). {/* ### Credits Credits can be granted to customers to offset their future bills. Credits can be defined in monetary or custom units. These can be used as part of your core pricing plan or as part of promotional campaigns / customer incentives. */} ### Rates A rate defines how your customer gets charged for specific items. Rates can either be fixed or usage-based. - **[Fixed rates](/api/resources/rate_cards/methods/create#request.body.fixed_rates)** are charged upfront in a billing cycle. The quantity is specified upfront. - For example, you can use a fixed rate to bill your customer \$10 per month for a seat. - **[Usage-based rates](/api/resources/rate_cards/methods/create#request.body.usage_based_rates)** are charged in arrears (i.e. at the end of the billing cycle) based on the quantity from a pricing metric. Usage-based rates can also specify an included quantity (i.e. the quantity that is included for free). - For example, you can use a usage-based rate to bill your customer \$0.10 per API call with 100 API calls included for free. ### Rate Card A collection of rates makes up a [rate card](/api/resources/rate_cards/methods/create). You also specify the billing interval on the rate card (monthly, yearly, etc.). ### Subscription A customer subscribes to a rate card using a subscription. The [subscription](/api/resources/subscriptions/methods/create) can have scheduled changes that make it easy to support free trials and other changes. # Introduction > Learn about Lark and how it can help you manage your customers, track usage, and manage feature access. Lark is a modern billing platform with the flexibility to support any pricing model (flat-fee, credit-based, usage-based, hybrid, dimensional, outcome-based, etc...) at any scale. Whether you're building an AI powered API service or a B2B SaaS product, Lark provides the tools you need to implement complex billing logic without the hassle. A billing platform should be more than just a rigid calculator. That's why Lark provides powerful hosted surfaces for end customers and makes it seamless to manage feature access, track usage, and handle customer credits. Lark was founded by two ex-Stripe billing engineers and is backed by [Y Combinator](https://www.ycombinator.com). # Defining pricing metrics > Learn how to configure pricing metrics to bill for usage. import { Tabs, TabItem } from '@astrojs/starlight/components'; Pricing metrics define how to aggregate usage events over a service period that is billed to your customer. ### Standard aggregation types Most pricing metrics can be modeled using standard aggregation types. - `count` - count the total number of usage events for a given event type. - Example: pricing by the number of API requests where you send a usage event for each request. - `sum` - for a given event type and a field in that event, return the sum of the field over all the events. - Example: pricing by compute time, where your usage events have a field called `duration_hours`. - `max` - for a given event type and a field in that event, return the maximum value of the field over all the events. - Example: pricing by number of concurrent database connections, where your usage events have a field called `concurrent_connections`. - `min` - for a given event type and a field in that event, return the minimum value of the field over all the events. - `mean` - for a given event type and a field in that event, return the mean value of the field over all the events. ### Custom SQL aggregation types You can also define pricing metrics using custom SQL. This can be useful for complex aggregation logic that isn't supported by the standard aggregation types. For instance, you price by total compute seconds but you track usage through heartbeat events every few seconds for each job execution. Example heartbeat usage event: ```json { "timestamp": "2025-01-01T00:00:00Z", "subject_id": "", "event_name": "job_execution_heartbeat", "data": { "job_runtime_seconds": "100.5", // total seconds running for the job execution "job_execution_id": "job_execution_123" }, "idempotency_key": "" } ``` Based on the above usage event, you can create a pricing metric with custom SQL aggregation to compute the max of the `job_runtime_seconds` field per job execution. {/* ```sql SELECT instance_type, SUM(max_seconds) / 60.0 AS usage FROM ( SELECT execution_id, instance_type, MAX(total_seconds_running) AS max_seconds FROM {{ EVENT_NAME }} WHERE event_timestamp >= {{ SERVICE_PERIOD_START }} AND event_timestamp < {{ SERVICE_PERIOD_END }} GROUP BY execution_id, instance_type ) GROUP BY instance_type; ``` */} If you're interested in using custom SQL aggregation, contact us at team@uselark.ai. ### Testing pricing metrics After you've created a pricing metric, you can test that your usage events are being aggregated correctly by creating a [pricing metric summary](/api/resources/pricing_metrics/methods/create_summary). ```python summary = lark_client.pricing_metrics.create_summary( pricing_metric_id=pricing_metric.id, subject_id=subject.id, period={ "start": datetime.now(timezone.utc) - timedelta(days=30), "end": datetime.now(timezone.utc).replace(second=0, microsecond=0), } ) ``` You can also group by day/hour granularity as well as by dimension (if applicable). ```python summary = lark_client.pricing_metrics.create_summary( pricing_metric_id=pricing_metric.id, subject_id=subject.id, period_granularity="day", dimensions=["region"], period={ "start": datetime.now(timezone.utc).date() - timedelta(days=7), "end": datetime.now(timezone.utc).date() + timedelta(days=1), }, ) ``` 1. Go to the pricing metrics page and click on the pricing metric you want to test. 2. Under "View usage", select the subject you want to view usage for. You can view usage data by day/hour granularity and by dimension (if applicable). ### Dimensional pricing metrics Dimensional pricing metrics allow you to bill for usage based with a price that varies by dimension(s). For example, if you bill for AI inference based on the model used and the region where the model is hosted the dimensions would be `model` and `region`. To create a dimensional pricing metric, you need to specify the dimensions and the aggregation type. ```python title="Create a dimensional pricing metric" pricing_metric = lark_client.pricing_metrics.create( name="Compute usage", event_name="compute_seconds", aggregation={"aggregation_type": "sum"}, dimensions=[ "region", "instance_type", ], ) ``` 1. Go to the pricing metrics page and click "Create Pricing Metric". 2. Fill in the form with the following values: - Name: `Compute usage` - Event Name: `compute_seconds` - Aggregation: `sum` - Dimensions (under "Advanced options"): `region`, `instance_type` 3. Click "Save". When creating usage events, specify the dimension values in the `data` field. ```python lark_client.usage_events.create( event_name="ai_inference", subject_id="", timestamp=datetime.now(timezone.utc), idempotency_key="", data={ "model": "gpt-5", "region": "us-east-1", "input_tokens": "100", "output_tokens": "50", }, ) ``` # Pricing models > Learn about how to configure common pricing models. ### Flat rate A flat rate is a pricing model where the customer pays a fixed amount. This is often used for software as a service (SaaS) products where the customer pays a fixed amount per billing period for a given plan. ### Tiered rate A tiered rate is a pricing model where the customer pays a different amount for different ranges of usage. ### Package rate A package rate is a pricing model where the customer pays for "packages" of units. ### Pay-as-you-go rate A pay-as-you-go rate is a pricing model where the customer pays for the exact amount of usage. # Rate cards > Learn about rate cards and how to create them. import { Tabs, TabItem } from '@astrojs/starlight/components'; A rate card is a collection of rates that your customers subscribe to for accessing your services. It is common to offer a few rate cards for your customers to choose from (like starter, pro, enterprise, etc.). ### Creating a rate card You can create a rate card [using the API](/api/resources/rate_cards/methods/create) or in the dashboard. ```python title="Create a rate card" rate_card = lark_client.rate_cards.create( name="Starter plan", description="Perfect for small teams.", billing_interval="monthly", fixed_rates=[ { "name": "Base rate", "code": "base_rate", "price": { "type": "flat", "amount": "2900", "currency_code": "usd" } } ], usage_based_rates=[ { "name": "AI chat requests", "code": "ai_chat_requests", "included_units": 100, "price": { "type": "flat", "amount": "50", "currency_code": "usd" }, "pricing_metric_id": pricing_metric.id } ], ) ``` 1. Go to the rate cards page and click "New Rate Card". 2. Set the name and description with the following values: - Name: `Starter plan` - Description: `Perfect for small teams.` - Billing Interval: `Monthly` 3. Add a fixed rate: - Name: `Base rate` - Code: `base_rate` - Price: `$29.00` (flat) 4. Add a usage-based rate: - Name: `AI chat requests` - Code: `ai_chat_requests` - Price: `$0.50` (flat) - Included Units: `100` - Pricing Metric: `AI chat requests` (from the dropdown) 3. Click "Save". #### Rates A rate card is made up of one or more rates. Each rate can be fixed or usage-based. Each rate also defines a `code` that is used to maintain quantities and discounts when customers move between rate cards. ##### Fixed rates [Fixed rates](/api/resources/rate_cards/methods/create) are charged upfront in a billing cycle. For example, the rate card might have a fixed rate of \$20/month per user. ##### Usage-based rates [Usage-based rates](/api/resources/rate_cards/methods/create) are charged in arrears (i.e. at the end of the billing cycle) based on the quantity from a pricing metric. Usage-based rates can also specify an included quantity (i.e. the quantity that is included for free). For example, the rate card might have a usage-based rate of \$0.10 per API call with 100 API calls included for free. #### Price types Each rate is linked to a price. A price defines how a quantity is converted to a amount to be charged. We support the following price types: - [Flat price](/api/resources/rate_cards/methods/create#request.body.fixed_rates.price.flat_price_input): A flat price is a price that is charged per each unit. For example, \$1 per unit. - [Package price](/api/resources/rate_cards/methods/create#request.body.usage_based_rates.price.package_price_input): A package price is a price that is charged per package of units. For example, \$10 per 1000 units. You can also specify a rounding behavior to round up or down to the nearest package unit. ### Changing a rate card Lark was designed with pricing changes in mind. You can simply create a new rate card version, set it as the latest version, and customers subscribed to the previous version will automatically be migrated to the new version. # Feature access > Learn how to determine feature access for a given user to your product. Once you have created a subject, you can use our customer access APIs to control feature access for a subject. ### Billing state You can fetch the [billing state](/api/resources/customer_access/methods/retrieve_billing_state) for a subject to check if they have an active subscription and if they have accrued overage. The latter will be true if they the customer is a subscribed to a usage based rate and their usage has exceeded the included quantity for that rate. ```python billing_state = lark_client.customer_access.retrieve_billing_state( subject_id="1234567890" ) feature_access_allowed = billing_state.has_active_subscription and not billing_state.has_overage_for_usage ``` If the subject isn't allowed access to a feature, you should show them a paywall to subscribe or upgrade their plan. # Subscribing customers > Learn how to subscribe customers to a rate card. import { Tabs, TabItem } from '@astrojs/starlight/components'; import { Callout } from "@stainless-api/docs/components"; You can subscribe a customer to a rate card in the dashboard or using the API (either directly or via a checkout flow). ### Prerequisite: Creating subjects Every customer you want to subscribe to a rate card should be represented by a [subject](/api/resources/subjects/methods/create). You should create these subjects every time a new customer signs up for your service. ```python subject = lark_client.subjects.create( external_id="customer_id_from_your_system", name="John Doe", email="john.doe@example.com", ) ``` 1. Go to the subjects page and click "Create subject". 2. Fill in the form with the following values: - Name: `John Doe` - Email: `john.doe@example.com` - (Optional) External ID: `customer_id_from_your_system` 3. Click "Done". ### Creating subscriptions You can create a subscription for a subject to a rate card using the [API](/api/resources/subscriptions/methods/create) or the dashboard. The response will either be a subscription object or a checkout URL. - If the subject does not have a payment method on file, the response will provide a checkout URL to redirect the customer to. - If the subject has a payment method on file, the subscription will be created immediately unless `create_checkout_session='always'` is specified in the request. ```python subscription = lark_client.subscriptions.create( subject_id="customer_id_from_your_system", rate_card_id="RATE_CARD_ID", fixed_rate_quantities={ "users": 1, # set the quantity for every fixed rate }, checkout_callback_urls={ "success_url": "https://example.com/success", "cancelled_url": "https://example.com/cancelled", }, ) ``` 1. Go to the subjects page and click on the subject you want to subscribe to a rate card. 2. Click on the "Subscriptions" tab. 3. Click "New Subscription". 4. Select the rate card you want to subscribe to from the dropdown. 5. Click "Save". You can use the following test cards to complete the checkout process in a sandbox account: - Visa: 4242 4242 4242 4242 - Mastercard: 5555 5555 5555 4444 - American Express: 3782 822463 10005 - Discover: 6011 1111 1111 1117 - Diners Club: 3056 930902 5904 - JCB: 3530 1113 3330 0000 - UnionPay: 6200 0000 0000 0000 If you are using Adyen, you can find test cards [here](https://docs.adyen.com/development-resources/test-cards-and-credentials/test-card-numbers). ### Discounts You can model discounts as `rate_price_multipliers` when creating or modifying a subscription. ```python subscription = lark_client.subscriptions.create( subject_id="customer_id_from_your_system", rate_card_id="RATE_CARD_ID", rate_price_multipliers=[ {"users": 0.75}, # 25% discount ], fixed_rate_quantities={ "users": 5, }, checkout_callback_urls={ "success_url": "https://example.com/success", "cancelled_url": "https://example.com/cancelled", }, ) ``` ### Fetching subscriptions If you [query subscriptions](/api/resources/subscriptions/methods/list) for the subject, you should now see a subscription with status `active`. ```python subscriptions = lark_client.subscriptions.list( subject_id="customer_id_from_your_system" ) subscription = subscriptions.subscriptions[0] ``` 1. Go to the [subscriptions](https://dashboard.uselark.ai/admin/subscriptions) page. 2. Filter by subject ID: `customer_id_from_your_system`. 3. You should see a subscription with status `active`. ### Managing subscriptions You can redirect customers to the hosted [customer portal](/api/resources/customer_portal/methods/create_session) to manage their subscriptions. ```python customer_portal_session = lark_client.customer_portal.create_session( subject_id="customer_id_from_your_system", return_url="https://example.com/return", ) ``` You should then redirect the customer to the `customer_portal_session.url`. You can also cancel a subscription using the API or the dashboard. ### Changing a subscription's rate card You can change a subscription's rate card using the [API](/api/resources/subscriptions/methods/change_rate_card). Lark supports upgrades and downgrades between rate cards. When a customer upgrades to a new rate card, their quantities and discounts will carry over automatically for rates with the same `code`. ```python subscription = lark_client.subscriptions.change_rate_card( subscription_id="subscription_id_from_your_system", rate_card_id="RATE_CARD_ID", checkout_callback_urls={ "success_url": "https://example.com/success", "cancelled_url": "https://example.com/cancelled", }, ) ``` # Enterprise billing > Learn how to model enterprise billing use cases including negotiated contracts, volume discounts, and custom pricing. import { Tabs, TabItem } from '@astrojs/starlight/components'; import { Callout } from "@stainless-api/docs/components"; import { Steps } from '@astrojs/starlight/components'; Enterprise billing comes with unique challenges: negotiated contracts, volume discounts, custom pricing terms, multi-year commitments, and complex approval workflows. Lark provides the flexibility to handle all of these scenarios while keeping your billing logic maintainable. ## What makes enterprise billing different Enterprise customers typically expect: - **Custom pricing**: Negotiated rates that differ from your standard plans - **Volume discounts**: Tiered pricing or percentage-based discounts based on commitment levels - **Contract terms**: Annual or multi-year contracts with scheduled price changes - **Seat-based licensing**: Per-user pricing with quantity commitments - **Usage commitments**: Minimum spend or usage guarantees with overage billing - **Hybrid models**: Combining flat fees with usage-based charges Lark's concepts of rate cards, discounts, and scheduled changes makes it straightforward to implement all of these patterns. ## Custom pricing with price multipliers Rather than creating a separate rate card for each enterprise customer, you can use a standard Enterprise rate card and apply `rate_price_multipliers` to give each customer their negotiated discounts. This keeps your rate card catalog manageable while supporting custom pricing. First, create a standard Enterprise rate card with your list prices: ```python title="Create a standard enterprise rate card" enterprise_rate_card = lark_client.rate_cards.create( name="Enterprise", description="Enterprise plan with annual billing.", billing_interval="yearly", fixed_rates=[ { "name": "Platform fee", "code": "platform_fee", "price": { "type": "flat", "amount": "500000", # $5,000/year list price "currency_code": "usd" } }, { "name": "Seats", "code": "seats", "price": { "type": "flat", "amount": "12000", # $120/year per seat list price "currency_code": "usd" } } ], usage_based_rates=[ { "name": "API requests", "code": "api_requests", "included_units": 1000000, # 1M requests included "price": { "type": "flat", "amount": "1", # $0.01 per request list price "currency_code": "usd" }, "pricing_metric_id": api_requests_metric.id } ], ) ``` 1. Go to the rate cards page and click "New Rate Card". 2. Fill in the details: - Name: `Enterprise` - Description: `Enterprise plan with annual billing.` - Billing Interval: `Yearly` 3. Add a fixed rate for the platform fee: - Name: `Platform fee` - Code: `platform_fee` - Price: `$5,000.00` 4. Add a fixed rate for seats: - Name: `Seats` - Code: `seats` - Price: `$120.00` 5. Add a usage-based rate for API requests: - Name: `API requests` - Code: `api_requests` - Included Units: `1000000` - Price: `$0.01` 6. Click "Save". Then, when subscribing an enterprise customer, apply their negotiated discounts using `rate_price_multipliers`: ```python title="Subscribe with negotiated enterprise pricing" subscription = lark_client.subscriptions.create( subject_id="acme_corp", rate_card_id=enterprise_rate_card.id, fixed_rate_quantities={ "seats": 250, # 250 seats }, rate_price_multipliers=[ {"platform_fee": 0.85}, # 15% discount on platform fee {"seats": 0.80}, # 20% discount on seats {"api_requests": 0.70}, # 30% discount on API usage ], ) ``` 1. Go to the subjects page and click on the enterprise customer. 2. Click on the "Subscriptions" tab. 3. Click "New Subscription". 4. Select the `Enterprise` rate card from the dropdown. 5. Set the seat quantity to `250`. 6. Add price multipliers for each rate: - `platform_fee`: `0.85` (15% discount) - `seats`: `0.80` (20% discount) - `api_requests`: `0.70` (30% discount) 7. Click "Save". This approach lets you maintain a single Enterprise rate card while applying customer-specific discounts. Each customer gets their negotiated rates, and discounts are preserved when they upgrade seats or modify their subscription. ## Seat-Based Enterprise Licensing Many enterprise contracts include a committed number of seats with the ability to add more as needed. ### Setting initial seat quantities ```python title="Subscribe with committed seats" subscription = lark_client.subscriptions.create( subject_id="enterprise_customer", rate_card_id=enterprise_rate_card.id, fixed_rate_quantities={ "seats": 100, # Committed to 100 seats }, ) ``` {/* ### Adjusting seats mid-cycle When an enterprise customer needs to add seats mid-contract, you can update the subscription: ```python title="Increase seat count" updated_subscription = lark_client.subscriptions.update( subscription_id=subscription.id, fixed_rate_quantities={ "seats": 150, # Increased from 100 to 150 seats }, ) ``` Lark will automatically prorate the charges for the additional seats based on the remaining time in the billing cycle. */} ## Usage commitments with overage billing Enterprise contracts often include usage commitments, a minimum amount of usage included in the base price, with additional charges for overages. The `included_units` field on usage-based rates makes this straightforward: ```python title="Rate card with usage commitment" enterprise_rate_card = lark_client.rate_cards.create( name="Enterprise with API Commitment", billing_interval="monthly", fixed_rates=[ { "name": "Platform access", "code": "platform_access", "price": { "type": "flat", "amount": "1000000", # $10,000/month includes usage commitment "currency_code": "usd" } } ], usage_based_rates=[ { "name": "API calls", "code": "api_calls", "included_units": 5000000, # 5M calls included in platform fee "price": { "type": "flat", "amount": "2", # $0.02 per call for overages "currency_code": "usd" }, "pricing_metric_id": api_calls_metric.id } ], ) ``` The customer pays $10,000/month and gets 5 million API calls included. Any usage beyond that is billed at $0.02 per call. ### Dynamic included units For enterprise contracts where included usage scales with other quantities (like seats), you can use `included_units_function` to define a formula. Dynamic included units are currently in private beta. Contact us at team@uselark.ai to get early access. For example, to include 100 AI chat requests per seat: ```python title="Rate card with dynamic included units" enterprise_rate_card = lark_client.rate_cards.create( name="Enterprise per-seat", billing_interval="monthly", fixed_rates=[ { "name": "Seats", "code": "seats", "price": { "type": "flat", "amount": "10000", # $100/month per seat "currency_code": "usd" } } ], usage_based_rates=[ { "name": "AI chat requests", "code": "ai_chat_requests", "included_units_function": "{{fixed_rate_quantities.seats}} * 100" # 100 AI chat requests per seat "price": { "type": "flat", "amount": "50", # $0.50 per AI chat request for overages "currency_code": "usd" }, "pricing_metric_id": ai_chat_requests_metric.id, } ], ) ``` With this configuration, a customer with 10 seats gets 10 million API calls included. If they add more seats mid-cycle, their included usage automatically increases. You can also override `included_units_function` at the subscription or contract phase level for customer-specific terms: ```python title="Override included units on a subscription" subscription = lark_client.subscriptions.create( subject_id="enterprise_customer", rate_card_id=enterprise_rate_card.id, fixed_rate_quantities={"seats": 50}, included_units_function={ "api_calls": "{{seats.quantity}} * 2000000" # 2M per seat for this customer } ) ``` ## Multi-year contracts with scheduled changes Enterprise contracts often span multiple years with pricing that changes over time. The contracts API allows you to define multiple phases with different rate cards and price multipliers for each phase. The contracts API is currently in private beta. Contact us at team@uselark.ai to get early access. ```python title="Multi-year contract with ramped pricing" contract = lark_client.contracts.create( subject_id="subj_VyX6Q96h5avMho8O7QWlKeXE", phases=[ { # Phase 1: 50% discount during onboarding "period": { "start": "2025-01-01", "end": "2025-07-01" }, "rate_card_id": "rc_AJWMxR81jxoRlli6p13uf3JB", "rate_price_multipliers": { "base_fee": 0.5 } }, { # Phase 2: 25% discount "period": { "start": "2025-07-01", "end": "2025-10-01" }, "rate_card_id": "rc_AJWMxR81jxoRlli6p13uf3JB", "rate_price_multipliers": { "base_fee": 0.75 } }, { # Phase 3: Full price "period": { "start": "2025-10-01", "end": "2026-01-01" }, "rate_card_id": "rc_AJWMxR81jxoRlli6p13uf3JB", "rate_price_multipliers": { "base_fee": 1 } } ], metadata={ "salesforce_id": "1234567890" } ) ``` Use contract phases to model ramped pricing, free trial periods, annual price increases, or mid-contract upgrades that have been negotiated in advance. ## Dimensional pricing for enterprise Enterprise customers with diverse workloads may need pricing that varies by dimension—such as region, environment, or service tier. First, create a dimensional pricing metric: ```python title="Create a dimensional pricing metric for compute" compute_metric = lark_client.pricing_metrics.create( name="Compute hours", event_name="compute_usage", aggregation={"aggregation_type": "sum", "field": "hours"}, dimensions=["region", "instance_tier"], ) ``` Then, when reporting usage, include the dimension values: ```python title="Report dimensional usage" lark_client.usage_events.create( event_name="compute_usage", subject_id="enterprise_customer", timestamp=datetime.now(timezone.utc), idempotency_key="compute_job_12345", data={ "hours": "24.5", "region": "us-east-1", "instance_tier": "high-memory", }, ) ``` This allows you to bill at different rates for different regions or instance types, which is common in infrastructure and cloud services. ## Managing enterprise customers at scale ### Organizing with subjects Create a subject for each enterprise customer with relevant metadata: ```python title="Create an enterprise subject" subject = lark_client.subjects.create( external_id="acme_corp_salesforce_id", name="Acme Corporation", email="billing@acme.com", ) ``` ### Subject hierarchies for teams and departments For large enterprises, you often need to track usage and pool credits at different organizational levels—such as by team, department, or cost center. Subject relationships are currently in private beta. Contact us at team@uselark.ai to get early access. Use `parent_subject_id` to create a hierarchy of subjects: ```python title="Create a subject hierarchy" # Create the parent enterprise account enterprise = lark_client.subjects.create( external_id="acme_corp", name="Acme Corporation", ) # Create departments under the enterprise engineering = lark_client.subjects.create( external_id="engineering_dept", name="Engineering", parent_subject_id=enterprise.id, ) # Create teams under departments backend_team = lark_client.subjects.create( external_id="team_123", name="Backend Team", parent_subject_id=engineering.id, ) ``` This hierarchy allows you to: - **Pool credits** at different levels (enterprise, department, or team) - **Track spend/usage** at each level - **Report usage** rolled up by organizational structure ### Customer portal for enterprise Enterprise customers can manage their subscriptions, view invoices, and analyze usage through the hosted customer portal: ```python title="Generate customer portal link" portal_session = lark_client.customer_portal.create_session( subject_id="acme_corp_salesforce_id", return_url="https://yourapp.com/billing", ) # Redirect customer to portal_session.url ``` ### Tracking usage across the enterprise For use-cases beyond the scope of the standard customer portal, you can use pricing metric summaries to provide enterprise customers with detailed usage reports: ```python title="Generate usage report for enterprise customer" usage_summary = lark_client.pricing_metrics.create_summary( pricing_metric_id=api_calls_metric.id, subject_id="enterprise_customer", period_granularity="day", dimensions=["region", "instance_tier"], period={ "start": "2025-01-01", "end": "2025-02-01", }, ) ``` ## Best practices - **Use consistent rate codes**: When creating custom enterprise rate cards, use the same `code` values across rate cards. This ensures quantities and discounts carry over when customers upgrade or change plans. - **Version your rate cards**: Create new rate card versions for price changes. Lark automatically migrates customers to the latest version.