# The add-on object
Source: https://getlago.com/docs/api-reference/add-ons/add-on-object
This object represents an add-on, a one-time fee that can be applied on one-off invoices.
# Create an add-on
Source: https://getlago.com/docs/api-reference/add-ons/create
POST /add_ons
This endpoint is used to create an add-on that can be then attached to a one-off invoice.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/add_ons" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"add_on": {
"name": "Setup Fee",
"code": "setup_fee",
"amount_cents": 50000,
"amount_currency": "USD",
"description": "Implementation fee for new customers.",
"tax_codes": ["french_reduced_vat"]
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import AddOn
client = Client(api_key='__YOUR_API_KEY__')
add_on = AddOn(
name='Setup Fee',
code='setup_fee',
amount_cents=50000,
amount_currency='USD',
description='Implementation fee for new customers.',
tax_codes= ['french_standard_vat']
)
try:
client.add_ons.create(add_on)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
add_on = {
name: 'Setup Fee',
code: 'setup_fee',
description: 'Implementation fee for new customers.',
amount_cents: 50000,
amount_currency: 'USD',
tax_codes: ['french_standard_vat']
}
client.add_ons.create(add_on)
```
```js Javascript theme={"dark"}
const addOnObject = {
name: "Setup Fee",
code: "setup_fee",
description: "Implementation fee for new customers.",
amount_cents: 50000,
amount_currency: "USD",
tax_codes: ["french_standard_vat"],
};
await client.addOns.createAddOn({ addOn: addOnObject });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
addOnInput := &lago.AddOnInput{
Name: "Setup Fee",
Code: "setup_fee",
AmountCents: 50000,
AmountCurrency: lago.USD,
Description: "Implementation fee for new customers.",
}
addOn, err := lagoClient.AddOn().Create(addOnInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// addOn is *lago.AddOn
fmt.Println(addOn)
}
```
# Delete an add-on
Source: https://getlago.com/docs/api-reference/add-ons/destroy
DELETE /add_ons/{code}
This endpoint is used to delete an existing add-on.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/add_ons/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.add_ons.destroy('code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.add_ons.destroy('code')
```
```js Javascript theme={"dark"}
await client.addOns.destroyAddOn('code')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
addOn, err := lagoClient.AddOn().Delete("__YOUR_ADDON_CODE__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// addOn is *lago.AddOn
fmt.Println(addOn)
}
```
# List all add-ons
Source: https://getlago.com/docs/api-reference/add-ons/get-all
GET /add_ons
This endpoint is used to list all existing add-ons.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/add_ons?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.add_ons.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.add_ons.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.addOns.findAllAddOns({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
addOnListInput := &lago.AddOnListInput{
PerPage: 1,
Page: 1,
}
addOnResult, err := lagoClient.AddOn().GetList(addOnListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// addOnResult is *lago.AddOnResult
fmt.Println(addOnResult)
}
```
# Retrieve an add-on
Source: https://getlago.com/docs/api-reference/add-ons/get-specific
GET /add_ons/{code}
This endpoint is used to retrieve a specific add-on.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/add_ons/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.add_ons.find('code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.add_ons.get('code')
```
```js Javascript theme={"dark"}
await client.addOns.findAddOn("code");
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
addOn, err := lagoClient.AddOn().Get("__YOUR_ADDON_CODE__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// addOn is *lago.AddOn
fmt.Println(addOn)
}
```
# Update an add-on
Source: https://getlago.com/docs/api-reference/add-ons/update
PUT /add_ons/{code}
This endpoint is used to update an existing add-on.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/add_ons/:code" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"add_on": {
"name": "Setup Fee",
"code": "setup_fee",
"amount_cents": 50000,
"amount_currency": "USD",
"description": "Implementation fee for new customers."
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import AddOn
client = Client(api_key='__YOUR_API_KEY__')
update_params = AddOn(name='Setup Fee')
try:
client.add_ons.update(update_params, 'setup_fee')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
update_params = {name: 'Setup Fee'}
client.add_ons.update(update_params, 'setup_fee')
```
```js Javascript theme={"dark"}
await client.addOns.updateAddOn("code", {
add_on: { name: "Setup Fee", code: "setup_fee" },
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
addOnInput := &lago.AddOnInput{
Name: "Setup Fee",
Code: "setup_fee",
AmountCents: 50000,
AmountCurrency: lago.USD,
Description: "Implementation fee for new customers.",
}
addOn, err := lagoClient.AddOn().Update(addOnInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// addOn is *lago.AddOn
fmt.Println(addOn)
}
```
# The alert object
Source: https://getlago.com/docs/api-reference/alerts/alert-object
This object represents an alert to monitor your subscriptions' usage and billing by firing notifications when certain conditions are met.
# Create an alert
Source: https://getlago.com/docs/api-reference/alerts/create
POST /subscriptions/{external_id}/alerts
This endpoint allows you to create a new alert for a subscription.
# Delete an alert
Source: https://getlago.com/docs/api-reference/alerts/delete
DELETE /subscriptions/{external_id}/alerts/{code}
This endpoint allows you to delete an existing alert for a subscription.
# List all alerts
Source: https://getlago.com/docs/api-reference/alerts/get-all
GET /subscriptions/{external_id}/alerts
This endpoint allows you to retrieve all alerts for a subscription.
# Retrieve an alert
Source: https://getlago.com/docs/api-reference/alerts/get-specific
GET /subscriptions/{external_id}/alerts/{code}
This endpoint allows you to retrieve a specific alert for a subscription.
# Update an alert
Source: https://getlago.com/docs/api-reference/alerts/update
PUT /subscriptions/{external_id}/alerts/{code}
This endpoint allows you to update an existing alert for a subscription.
# API standards
Source: https://getlago.com/docs/api-reference/api-standards
Lago API endpoints follow common RESTful standards.
## Authentication
Authentication is required for most endpoints, via an API key provided in the `Authorization` header as:
```http theme={"dark"}
Authorization: Bearer
```
## HTTP status codes
HTTP status codes communicate the outcome of each API request. For example, a successful request returns `200 OK`, while a malformed request returns `400 Bad Request`. More information about error codes can be found in the [Errors](./errors) section.
## Request and response body
Unless otherwise noted, both requests and responses use a JSON body, and the `Content-Type` header is expected to be set to `application/json`.
## Query parameters
Query parameters allow you to filter, search, and paginate API results. The Lago API supports several types of query parameters, described below.
### Simple parameters
Simple query parameters are sent as key-value pairs. These parameters are used for pagination or to filter results by a single value:
```http List subscriptions theme={"dark"}
GET /api/v1/subscriptions?page=1&per_page=20&external_customer_id=123
```
In this case, the parameter will be described in the API reference as:
The customer external unique identifier (provided by your own application)
Example: `"5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba"`
### Array parameters
Array parameters are sent as multiple entries of the same key, always ending with square brackets (`[]`). These parameters are used to filter results by multiple values:
```http List applied coupons theme={"dark"}
GET /api/v1/applied_coupons?coupon_code[]=10_OFF&coupon_code[]=20_OFF
```
In this case, the parameter will be described in the API reference as:
The coupon codes to filter the applied coupons by.
# The activity log object
Source: https://getlago.com/docs/api-reference/audit-logs/activity-logs-object
This object represents an activity log entry of any actions performed on application resources.
# The API log object
Source: https://getlago.com/docs/api-reference/audit-logs/api-logs-object
This object represents an API log entry of any actions performed through the API endpoints.
# List all activity logs
Source: https://getlago.com/docs/api-reference/audit-logs/get-all-activity-logs
GET /activity_logs
This endpoint retrieves all existing activity logs that represent actions performed on application resources.
# List all API logs
Source: https://getlago.com/docs/api-reference/audit-logs/get-all-api-logs
GET /api_logs
This endpoint retrieves all existing api logs that represent requests performed to Lago's API.
# Retrieve an activity log
Source: https://getlago.com/docs/api-reference/audit-logs/get-specific-activity-log
GET /activity_logs/{activity_id}
This endpoint retrieves an existing activity log that represents an action performed on some resource. The activity log is identified by its unique activity_id.
# Retrieve an API log
Source: https://getlago.com/docs/api-reference/audit-logs/get-specific-api-log
GET /api_logs/{request_id}
This endpoint retrieves an existing api log that represents a request made to the API. The api log is identified by its unique request_id.
# Create a billable metric
Source: https://getlago.com/docs/api-reference/billable-metrics/create
POST /billable_metrics
This endpoint creates a new billable metric representing a pricing component of your application.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Storage",
"code": "storage",
"description": "GB of storage used in my application",
"aggregation_type": "sum_agg",
"recurring": false,
"field_name": "gb",
"weighted_interval": "seconds",
"filters": [
{
"key": "region",
"values": ["us-east-1", "us-east-2", "eu-west-1"]
}
]
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import BillableMetricFilter, BillableMetric
client = Client(api_key='__YOUR_API_KEY__')
filter = BillableMetricFilter(
key='region',
values=['us-east-1', 'us-east-2', 'eu-west-1']
)
billable_metric = BillableMetric(
name='Storage',
code='storage',
recurring=false,
description='GB of storage used in my application',
aggregation_type='sum_agg',
field_name='gb',
weighted_interval= 'seconds',
filters=[filter]
)
try:
client.billable_metrics.create(billable_metric)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.billable_metrics.create({
name: 'Storage',
code: 'storage',
description: 'GB of storage used in my application',
aggregation_type: 'sum_agg',
recurring: false,
field_name: 'gb',
weighted_interval: 'seconds',
filters: [
{
key: 'region',
values: %w[us-east-1 us-east-2 eu-west-1]
}
]
})
```
```js Javascript theme={"dark"}
await client.billableMetrics.createBillableMetric({
billable_metric: {
name: "Storage",
code: "storage",
aggregation_type: "sum_agg",
recurring: false,
field_name: "gb",
weighted_interval: "seconds",
filters: [
{
key: "region",
values: ["us-east-1", "us-east-2", "eu-west-1"],
}
]
},
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
bmInput := &lago.BillableMetricInput{
Name: "Storage",
Code: "storage",
Description: "GB of storage used in my application"
AggregationType: lago.SumAggregation,
FieldName: "gb",
WeightedInterval:"seconds",
Recurring: false,
Filters: [1]map[string]interface{}{
"key": "region",
"values": [3]string{"us-east-1", "us-east-2", "eu-west-1"},
},
}
billableMetric, err := lagoClient.BillableMetric().Create(bmInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// billableMetric is *lago.BillableMetric
fmt.Println(billableMetric)
}
```
# Delete a billable metric
Source: https://getlago.com/docs/api-reference/billable-metrics/destroy
DELETE /billable_metrics/{code}
This endpoint deletes an existing billable metric representing a pricing component of your application.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/billable_metrics/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.billable_metrics.destroy('code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.billable_metrics.destroy('code')
```
```js Javascript theme={"dark"}
await client.billableMetrics.destroyBillableMetric('code')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
billableMetric, err := lagoClient.BillableMetric().Delete("__YOUR_BILLABLE_METRIC_CODE__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// billableMetric is *lago.BillableMetric
fmt.Println(billableMetric)
}
```
# List all billable metrics
Source: https://getlago.com/docs/api-reference/billable-metrics/get-all
GET /billable_metrics
This endpoint retrieves all existing billable metrics that represent pricing components of your application.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/billable_metrics?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.billable_metrics.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.billable_metrics.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.billableMetrics.findAllBillableMetrics({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
bmListInput := &lago.BillableMetricListInput{
PerPage: 10,
Page: 1,
}
billableMetricResult, err := lagoClient.BillableMetric().GetList(bmListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// billableMetric is *lago.BillableMetricResult
fmt.Println(billableMetricResult)
}
```
# Retrieve a billable metric
Source: https://getlago.com/docs/api-reference/billable-metrics/get-specific
GET /billable_metrics/{code}
This endpoint retrieves an existing billable metric that represents a pricing component of your application. The billable metric is identified by its unique code.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/billable_metrics/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.billable_metrics.find('code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.billable_metrics.get('code')
```
```js Javascript theme={"dark"}
await client.billableMetrics.findBillableMetric('code');
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
billableMetric, err := lagoClient.BillableMetric().Get("__BILLABLE_METRIC_CODE__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// billableMetric is *lago.BillableMetric
fmt.Println(billableMetric)
}
```
# The billable metric object
Source: https://getlago.com/docs/api-reference/billable-metrics/object
This object represents a billable metric used to define how incoming events are aggregated in order to measure consumption.
# Update a billable metric
Source: https://getlago.com/docs/api-reference/billable-metrics/update
PUT /billable_metrics/{code}
This endpoint updates an existing billable metric representing a pricing component of your application.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/billable_metrics/:code" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Storage",
"code": "storage",
"description": "GB of storage used in my application",
"aggregation_type": "sum_agg",
"recurring": false,
"field_name": "gb",
"weighted_interval": "seconds",
"filters": [
{
"key": "provider",
"values": ["us-east-1", "us-east-2", "eu-west-1"]
}
]
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import BillableMetricFilter, BillableMetric
client = Client(api_key='__YOUR_API_KEY__')
filter = BillableMetricFilter(
key='region',
values=['us-east-1', 'us-east-2', 'eu-west-1']
)
billable_metric = BillableMetric(
name='Storage',
code='storage',
description='GB of storage used in my application',
aggregation_type='sum_agg',
recurring=false,
field_name='gb',
weighted_interval= 'seconds',
filters=[filter]
)
try:
client.billable_metrics.update(billable_metric, 'code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.billable_metrics.update({
name: 'Storage',
code: 'storage',
description: 'GB of storage used in my application',
aggregation_type: 'sum_agg',
recurring: false,
field_name: 'gb',
weighted_interval: 'seconds',
filters: [
{
key: 'region',
values: %w[us-east-1 us-east-2 eu-west-1]
}
]
}, 'code')
```
```js Javascript theme={"dark"}
const newBillableMetricObject = {
name: "Storage",
code: "storage",
recurring: false,
aggregation_type: "sum_agg",
weighted_interval: "seconds",
field_name: "gb",
};
await client.billableMetrics.updateBillableMetric("code", {
billableMetric: newBillableMetricObject,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
bmInput := &lago.BillableMetricInput{
Name: "Storage",
Code: "storage",
Description: "GB of storage used in my application"
AggregationType: lago.SumAggregation,
FieldName: "gb",
Recurring: false,
WeightedInterval: "seconds",
Filters: [1]map[string]interface{}{
"key": "region",
"values": [3]string{"us-east-1", "us-east-2", "eu-west-1"},
},
}
billableMetric, err := lagoClient.BillableMetric().Update(bmInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// billableMetric is *lago.BillableMetric
fmt.Println(billableMetric)
}
```
# Create a billing entity
Source: https://getlago.com/docs/api-reference/billing-entities/create
POST /billing_entities
This endpoint is used to create a new billing entity
# List all billing entities
Source: https://getlago.com/docs/api-reference/billing-entities/get-all
GET /billing_entities
This endpoint returns a list of all billing entities in the organization
# Retrieve a billing entity
Source: https://getlago.com/docs/api-reference/billing-entities/get-specific
GET /billing_entities/{code}
This endpoint returns a specific billing entity by its code
# The billing entity object
Source: https://getlago.com/docs/api-reference/billing-entities/object
This object represents a billing entity used to generate invoices.
# Update a billing entity
Source: https://getlago.com/docs/api-reference/billing-entities/update
PUT /billing_entities/{code}
This endpoint is used to update an existing billing entity
# The applied coupon object
Source: https://getlago.com/docs/api-reference/coupons/applied-coupon-object
This object represents a coupon applied to a customer. It can override the initial values of a coupon.
```json The applied coupon object theme={"dark"}
{
"applied_coupon": {
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"lago_coupon_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"coupon_code": "startup_deal",
"coupon_name": "Startup Deal",
"lago_customer_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"status": "active",
"amount_cents": 2000,
"amount_cents_remaining": 50,
"amount_currency": "EUR",
"percentage_rate": "string",
"frequency": "recurring",
"frequency_duration": 3,
"frequency_duration_remaining": 1,
"expiration_at": "2022-04-29T08:59:51Z",
"created_at": "2022-04-29T08:59:51Z",
"terminated_at": "2022-04-29T08:59:51Z"
}
}
```
## Attributes
Unique identifier of the applied coupon, created by Lago.
Unique identifier of the coupon, created by Lago.
The name of the coupon.
Unique code used to identify the coupon.
The customer external unique identifier (provided by your own application)
Unique identifier of the customer, created by Lago.
The status of the coupon. Can be either `active` or `terminated`.
The amount of the coupon in cents. This field is required only for coupon with `fixed_amount` type.
The remaining amount in cents for a `fixed_amount` coupon with a frequency set to `once`.
This field indicates the remaining balance or value that can still be utilized from the coupon.
The currency of the coupon. This field is required only for coupon with `fixed_amount` type.
The expiration date and time of the coupon. This field is required only for coupons with `expiration` set to `time_limit`.
The expiration date and time should be specified in UTC format according to the ISO 8601 datetime standard.
It indicates the exact moment when the coupon will expire and is no longer valid.
The type of frequency for the coupon. It can have three possible values: `once`, `recurring`, or `forever`.
* If set to `once`, the coupon is applicable only for a single use.
* If set to `recurring`, the coupon can be used multiple times for recurring billing periods.
* If set to `forever`, the coupon has unlimited usage and can be applied indefinitely.
Specifies the number of billing periods to which the coupon applies. This field is required only for coupons
with a `recurring` frequency type
The remaining number of billing periods to which the coupon is applicable. This field determines the remaining
usage or availability of the coupon based on the remaining billing periods.
The percentage rate of the coupon. This field is required only for coupons with a `percentage` coupon type.
The date and time when the coupon was assigned to a customer. It is expressed in UTC format according to the ISO 8601 datetime standard.
This field indicates the specific moment when the coupon amount is fully utilized or when the coupon is removed from the customer's coupon list. It is expressed in UTC format according to the ISO 8601 datetime standard.
# Apply a coupon
Source: https://getlago.com/docs/api-reference/coupons/apply
POST /applied_coupons
This endpoint is used to apply a specific coupon to a customer, before or during a subscription.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/applied_coupons" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"applied_coupon": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"coupon_code": "startup_deal",
"amount_cents": 2500,
"amount_currency": "EUR",
"frequency": "recurring",
"frequency_duration": 3
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import AppliedCoupon
client = Client(api_key='__YOUR_API_KEY__')
applied_coupon = AppliedCoupon(
external_customer_id="5eb02857-a71e-4ea2-bcf9-57d8885990ba",
coupon_code="startup_deal",
amount_cents=2500,
amount_currency="EUR",
frequency="recurring",
frequency_duration=3
)
try:
client.applied_coupons.create(applied_coupon)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.applied_coupons.create(
external_customer_id: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
coupon_code: "startup_deal",
amount_cents: 2500,
amount_currency: "EUR",
frequency: "recurring",
frequency_duration: 3
)
```
```js Javascript theme={"dark"}
const appliedCouponObject = {
external_customer_id: "5eb02857-a71e-4ea2-bcf9-57d8885990ba",
coupon_code: "startup_deal",
amount_cents: 2500,
amount_currency: "EUR",
frequency: "recurring" as AppliedCouponObject["frequency"],
frequency_duration: 3,
};
await client.appliedCoupons.applyCoupon({
appliedCoupon: appliedCouponObject,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
applyCouponInput := &lago.ApplyCouponInput{
ExternalCustomerID: "5eb02857-a71e-4ea2-bcf9-57d8885990ba",
CouponCode: "startup_deal",
Frequency: lago.CouponFrequencyRecurring,
FrequencyDuration: 3
}
appliedCoupon, err := lagoClient.Coupon().ApplyToCustomer(applyCouponInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// appliedCoupon is *lago.AppliedCoupon
fmt.Println(appliedCoupon)
}
```
# The coupon object
Source: https://getlago.com/docs/api-reference/coupons/coupon-object
This object represents a coupon used to applies discount on customer next invoices. This coupon can be applied to a customer with overriden values.
# Create a coupon
Source: https://getlago.com/docs/api-reference/coupons/create
POST /coupons
This endpoint is used to create a coupon that can be then attached to a customer to create a discount.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/coupons" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"coupon": {
"name": "Startup Deal",
"code": "startup_deal",
"amount_cents": 5000,
"amount_currency": "USD",
"coupon_type": "fixed_amount",
"reusable": true,
"frequency": "recurring",
"frequency_duration": 6,
"expiration": "time_limit",
"expiration_at": "2022-08-08T23:59:59Z",
"applies_to": {
"plan_codes": ["startup_plan"],
"billable_metric_codes": []
}
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Coupon
client = Client(api_key='__YOUR_API_KEY__')
coupon = Coupon(
name='Startup Deal',
code='startup_deal',
amount_cents=5000,
amount_currency='USD',
coupon_type='fixed_amount',
frequency='recurring',
frequency_duration=6,
reusable=True
expiration='time_limit',
expiration_at='2022-08-08T23:59:59Z',
applies_to=LimitationConfiguration(plan_codes=['startup_plan'])
)
try:
client.coupons.create(coupon)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
coupon = {
name: 'Startup Deal',
code: 'startup_deal',
expiration: 'time_limit',
expiration_at: '2022-08-08T23:59:59Z',
amount_cents: 5000,
amount_currency: 'USD',
coupon_type: 'fixed_amount',
reusable: true,
frequency: 'recurring',
frequency_duration: 6,
applies_to: {
plan_codes: ['startup_plan']
}
}
client.coupons.create(coupon)
```
```js Javascript theme={"dark"}
const couponObject = {
name: "Startup Deal",
code: "startup_deal",
expiration: "time_limit" as CouponObject["expiration"],
expiration_at: "2022-08-08T23:59:59Z",
amount_cents: 5000,
amount_currency: "USD",
coupon_type: "fixed_amount" as CouponObject["couponType"],
reusable: true,
frequency: "recurring" as CouponObject["frequency"],
frequency_duration: 6,
applies_to: {
plan_codes: ["startup_plan"],
},
};
await client.coupons.createCoupon({ coupon: couponObject });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
limitationInput := &lago.LimitationInput{
PlanCodes: []string{"startup_plan"}
}
expirationAt := time.Date(2022, 8, 8, 23, 59, 59, 0, time.UTC)
couponInput := &lago.CouponInput{
Name: "Startup Deal",
Code: "startup_deal",
AmountCents: 5000,
AmountCurrency: lago.USD,
Reusable: true,
Expiration: lago.CouponExpirationTimeLimit,
ExpirationAt: &expirationAt,
CouponType: lago.CouponTypeFixedAmount,
Frequency: lago.CouponFrequencyRecurring,
FrequencyDuration: 6,
AppliesTo limitationInput
}
coupon, err := lagoClient.Coupon().Create(couponInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// coupon is *lago.Coupon
fmt.Println(coupon)
}
```
# Delete a coupon
Source: https://getlago.com/docs/api-reference/coupons/destroy
DELETE /coupons/{code}
This endpoint is used to delete a coupon.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/coupons/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.coupons.destroy('code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.coupons.destroy('code')
```
```js Javascript theme={"dark"}
await client.coupons.destroyCoupon('code');
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
coupon, err := lagoClient.Coupon().Delete("__YOUR_COUPON_CODE__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// coupon is *lago.Coupon
fmt.Println(coupon)
}
```
# Delete an applied coupon
Source: https://getlago.com/docs/api-reference/coupons/destroy-applied-coupon
DELETE /customers/{external_customer_id}/applied_coupons/{applied_coupon_id}
This endpoint is used to delete a specific coupon that has been applied to a customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/customers/:external_customer_id/applied_coupons/:applied_coupon_id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.applied_coupons.destroy('external_customer_id', 'applied_coupon_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.applied_coupons.destroy('external_customer_id', 'applied_coupon_id')
```
```js Javascript theme={"dark"}
await client.customers.deleteAppliedCoupon(
"external_customer_id",
"applied_coupon_id"
);
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
appliedCoupon, err := lagoClient.Coupon().AppliedCouponDelete('external_customer_id', 'applied_coupon_id')
if err != nil {
// Error is *lago.Error
panic(err)
}
// appliedCoupon is *lago.AppliedCoupon
fmt.Println(appliedCoupon)
}
```
# List all coupons
Source: https://getlago.com/docs/api-reference/coupons/get-all
GET /coupons
This endpoint is used to list all existing coupons.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/coupons?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.coupons.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.coupons.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.coupons.findAllCoupons({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
couponListInput := &lago.CouponListInput{
PerPage: 1,
Page: 1,
}
couponResult, err := lagoClient.Coupon().GetList(couponListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// couponResult is *lago.CouponResult
fmt.Println(couponResult)
}
```
# List all applied coupons
Source: https://getlago.com/docs/api-reference/coupons/get-all-applied
GET /applied_coupons
This endpoint is used to list all applied coupons. You can filter by coupon status and by customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/applied_coupons?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.applied_coupons.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.applied_coupons.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.appliedCoupons.findAllAppliedCoupons({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
couponListInput := &lago.AppliedCouponListInput{
PerPage: 1,
Page: 1,
}
couponResult, err := lagoClient.AppliedCoupon().GetList(couponListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// couponResult is *lago.CouponResult
fmt.Println(couponResult)
}
```
# Retrieve a coupon
Source: https://getlago.com/docs/api-reference/coupons/get-specific
GET /coupons/{code}
This endpoint is used to retrieve a specific coupon.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/coupons/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.coupons.find('code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.coupons.get('code')
```
```js Javascript theme={"dark"}
await client.coupons.findCoupon('code')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
coupon, err := lagoClient.Coupon().Get("__YOUR_COUPON_CODE__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// coupon is *lago.Coupon
fmt.Println(coupon)
}
```
# Update a coupon
Source: https://getlago.com/docs/api-reference/coupons/update
PUT /coupons/{code}
This endpoint is used to update a coupon that can be then attached to a customer to create a discount.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/coupons/:code" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"coupon": {
"name": "Startup Deal",
"code": "startup_deal",
"amount_cents": 5000,
"amount_currency": "USD",
"coupon_type": "fixed_amount",
"frequency": "recurring",
"frequency_duration": 6,
"reusable": true,
"expiration": "time_limit",
"expiration_at": "2022-08-08T23:59:59Z"
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Coupon
client = Client(api_key='__YOUR_API_KEY__')
update_params = Coupon(name='new name')
try:
client.coupons.update(update_params, 'code')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
update_params = {name: 'new name'}
client.coupons.update(update_params, 'code_bm')
```
```js Javascript theme={"dark"}
await client.coupons.updateCoupon("code", { coupon: { name: "new name" } });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
expirationAt := time.Date(2022, 8, 8, 23, 59, 59, 0, time.UTC)
couponInput := &lago.CouponInput{
Name: "Coupon",
Code: "coupon",
AmountCents: 1500,
AmountCurrency: lago.EUR,
Expiration: lago.CouponExpirationTimeLimit,
ExpirationAt: &expirationAt,
}
coupon := lagoClient.Coupon().Update(couponInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// coupon is *lago.Coupon
fmt.Println(coupon)
}
```
# Create a credit note
Source: https://getlago.com/docs/api-reference/credit-notes/create
POST /credit_notes
This endpoint creates a new credit note.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/credit_notes" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"credit_note": {
"invoice_id": "__LAGO_INVOICE_ID__",
"reason": "duplicated_charge",
"credit_amount_cents": 10,
"refund_amount_cents": 5,
"items": [
{
"fee_id": "__LAGO_FEE_ID__",
"amount_cents": 10
},
{
"fee_id": "__LAGO_FEE_ID__",
"amount_cents": 5
}
]
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models.credit_note import Item, Items, CreditNote
client = Client(api_key='__YOUR_API_KEY__')
item1 = Item(
fee_id="__LAGO_FEE_ID__",
amount_cents=10
)
item2 = Item(
fee="__LAGO_FEE_ID__",
amount_cents=5,
)
credit_note = CreditNote(
lago_id="__LAGO_INVOICE_ID__",
reason="other",
credit_amount_cents=10,
refund_amount_cents=5,
items= Items(__root__=[item1, item2])
)
try:
client.credit_notes.create(credit_note)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
credit_note = {
invoice_id: '__LAGO_INVOICE_ID__',
reason: 'duplicated_charge',
credit_amount_cents: 10,
refund_amount_cents: 5,
items: [
{
fee_id: '__LAGO_FEE_ID__',
amount_cents: 10
},
{
fee_id: '__LAGO_FEE_ID__',
amount_cents: 5
}
]
}
client.credit_notes.create(credit_note)
```
```js Javascript theme={"dark"}
import { CreditNoteObject } from "lago-javascript-client";
const creditNoteObject = {
invoice_id: "__LAGO_INVOICE_ID__",
reason: "other" as CreditNoteObject["reason"],
credit_amount_cents: 10,
refund_amount_cents: 5,
items: [
{
fee_id: "__LAGO_FEE_ID__",
amount_cents: 10,
},
{
fee_id: "__LAGO_FEE_ID__",
amount_cents: 5,
},
],
};
await client.creditNotes.createCreditNote({ creditNote: creditNoteObject });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
creditNoteInput := &lago.CreditNoteInput{
LagoInvoiceID: "__LAGO_INVOICE_ID__",
Reason: lago.CreditNoteReasonDuplicatedCharge,
CreditAmountCents 10,
RefundAmountCents 5,
Items: []lago.CreditNoteItemInput{
{
LagoFeeID "__LAGO_FEE_ID__",
AmountCents 10,
},
{
LagoFeeID "__LAGO_FEE_ID__",
AmountCents 5,
},
},
}
creditNote, err := lagoClient.CreditNote().Create(creditNoteInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
fmt.Println(creditNote)
}
```
# The credit note object
Source: https://getlago.com/docs/api-reference/credit-notes/credit-note-object
This object represents a credit note, used to refund or credit back a customer for a fee or an invoice.
# Download a credit note
Source: https://getlago.com/docs/api-reference/credit-notes/download
POST /credit_notes/{lago_id}/download
This endpoint downloads the PDF of an existing credit note.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
CREDIT_NOTE_ID="__CREDIT_NOTE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/credit_notes/$CREDIT_NOTE_ID/download" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
invoice = None
try:
invoice = client.credit_notes.download('__CREDIT_NOTE_ID__')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.credit_notes.download('__CREDIT_NOTE_ID__')
```
```js Javascript theme={"dark"}
await client.creditNotes.downloadCreditNote('credit-note-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
credit_note, err := lagoClient.CreditNote().Download("__CREDIT_NOTE_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// credit_note is *lago.CreditNote
fmt.Println(credit_note)
// If the credit note has to be generated, the response is empty
// And you will get a webhook `credit_note.generated`
}
```
# Estimate a credit note
Source: https://getlago.com/docs/api-reference/credit-notes/estimate
POST /credit_notes/estimate
This endpoint allows you to retrieve amounts for a new credit note creation.
# List all credit notes
Source: https://getlago.com/docs/api-reference/credit-notes/get-all
GET /credit_notes
This endpoint list all existing credit notes.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/credit_notes?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.credit_notes.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.credit_notes.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.creditNotes.findAllCreditNotes({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
creditNoteListInput := &lago.CreditNoteListInput{
PerPage: 1,
Page: 1,
ExternalCustomerID: "cus_1234",
}
creditNoteResult, err := lagoClient.CreditNote().GetList(creditNoteListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// creditNoteResult is *lago.CreditNoteResult
fmt.Println(creditNoteResult)
}
```
# Retrieve a credit note
Source: https://getlago.com/docs/api-reference/credit-notes/get-specific
GET /credit_notes/{lago_id}
This endpoint retrieves an existing credit note.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
CREDIT_NOTE_ID="__CREDIT_NOTE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/credit_notes/$CREDIT_NOTE_ID" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.credit_notes.find('__CREDIT_NOTE_ID__')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.credit_notes.get('__CREDIT_NOTE_ID__')
```
```js Javascript theme={"dark"}
await client.creditNotes.findCreditNote('credit-note-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
creditNote, err := lagoClient.CreditNotes().Get("__CREDIT_NOTE_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// credit note is *lago.CreditNote
fmt.Println(creditNote)
}
```
# Replace all metadata
Source: https://getlago.com/docs/api-reference/credit-notes/metadata/create-metadata-cn
POST /credit_notes/{lago_id}/metadata
This endpoint replaces all existing metadata on a credit note with the provided key-value pairs.
Any existing metadata keys not included in the request will be removed.
# Delete a metadata
Source: https://getlago.com/docs/api-reference/credit-notes/metadata/delete-a-metadata-cn
DELETE /credit_notes/{lago_id}/metadata/{key}
This endpoint removes a single metadata key from a credit note.
# Delete all metadata
Source: https://getlago.com/docs/api-reference/credit-notes/metadata/delete-all-metadata-cn
DELETE /credit_notes/{lago_id}/metadata
This endpoint removes all metadata from a credit note.
# Udpate metadata
Source: https://getlago.com/docs/api-reference/credit-notes/metadata/update-metadata-cn
PATCH /credit_notes/{lago_id}/metadata
This endpoint merges the provided metadata with existing metadata on the credit note.
Existing keys not in the request are preserved. New keys are added, existing keys are updated.
# Update a credit note
Source: https://getlago.com/docs/api-reference/credit-notes/update
PUT /credit_notes/{lago_id}
This endpoint updates an existing credit note.
# Void available credit
Source: https://getlago.com/docs/api-reference/credit-notes/void
PUT /credit_notes/{lago_id}/void
This endpoint voids the available credit linked to a specific credit note.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
CREDIT_NOTE_ID="__CREDIT_NOTE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/credit_notes/$CREDIT_NOTE_ID/void" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
try:
client.credit_notes.void("__CREDIT_NOTE_ID__")
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.credit_note.void('__CREDIT_NOTE_ID__')
```
```js Javascript theme={"dark"}
await client.creditNotes.voidCreditNote('credit-node-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
creditNote, err := lagoClient.CreditNote().Void("__CREDIT_NOTE_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// creditNote is *lago.CreditNote
fmt.Println(creditNote)
}
```
# The customer usage object
Source: https://getlago.com/docs/api-reference/customer-usage/customer-usage-object
This object represents the usage-based charges associated with one of your customers for a defined billing period. It allows you to monitor customer usage throughout the period.
# Retrieve current usage
Source: https://getlago.com/docs/api-reference/customer-usage/get-current
GET /customers/{external_customer_id}/current_usage
Retrieve real-time customer usage data for the current open billing period.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_CUSTOMER_ID="__EXTERNAL_CUSTOMER_ID__"
EXTERNAL_SUBSCRIPTION_ID="__EXTERNAL_SUBSCRIPTION_ID__"
curl --location --request GET "$LAGO_URL/api/v1/customers/$EXTERNAL_CUSTOMER_ID/current_usage?external_subscription_id=$EXTERNAL_SUBSCRIPTION_ID" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
customer_usage = None
try:
customer_usage = client.customers.current_usage('external_customer_id', 'external_subscription_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
customer_usage = client.customer.current_usage(
'external_customer_id', 'external_subscription_id'
)
```
```js Javascript theme={"dark"}
await client.customers.findCustomerCurrentUsage(
"customer_external_id",
{ external_subscription_id: "external_subscription_id" }
);
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customerUsage, err := lagoClient.Customer().CurrentUsage("__YOUR_CUSTOMER_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// customerUsage is *lago.CustomerUsage
fmt.Println(customerUsage)
}
```
# Retrieve past usage
Source: https://getlago.com/docs/api-reference/customer-usage/get-past
GET /customers/{external_customer_id}/past_usage
Fetch historical customer usage data for closed billing periods.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_CUSTOMER_ID="__EXTERNAL_CUSTOMER_ID__"
EXTERNAL_SUBSCRIPTION_ID="__EXTERNAL_SUBSCRIPTION_ID__"
curl --location --request GET "$LAGO_URL/api/v1/customers/$EXTERNAL_CUSTOMER_ID/past_usage?external_subscription_id=$EXTERNAL_SUBSCRIPTION_ID" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
customer_usage = None
try:
customer_usage = client.customers.past_usage('external_customer_id', 'external_subscription_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
customer_usage = client.customer.past_usage(
'external_customer_id', 'external_subscription_id'
)
```
```js Javascript theme={"dark"}
await client.customers.findCustomerPastUsage(
"customer_external_id",
{ external_subscription_id: "external_subscription_id" }
);
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customerUsage, err := lagoClient.Customer().PastUsage("__YOUR_CUSTOMER_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// customerUsage is *lago.CustomerUsage
fmt.Println(customerUsage)
}
```
# Retrieve projected usage
Source: https://getlago.com/docs/api-reference/customer-usage/get-projected
GET /customers/{external_customer_id}/projected_usage
Retrieve real-time projected usage data for the current open billing period.
# Create a customer
Source: https://getlago.com/docs/api-reference/customers/create
POST /customers
This endpoint creates a new customer.
This endpoint performs an upsert operation.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"address_line2": "",
"city": "Woodland Hills",
"country": "US",
"currency": "USD",
"email": "dinesh@piedpiper.test",
"legal_name": "Coleman-Blair",
"legal_number": "49-008-2965",
"tax_identification_number": "EU123456789",
"logo_url": "http://hooli.com/logo.png",
"name": "Gavin Belson",
"phone": "1-171-883-3711 x245",
"state": "CA",
"timezone": "Europe/Paris",
"url": "http://hooli.com",
"zipcode": "91364",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"document_locale": "fr",
"provider_payment_methods": ["card", "sepa_debit", "us_bank_account", "bacs_debit", "link"]
},
"metadata": [
{
"key": "Purchase Order",
"value": "123456789",
"display_in_invoice": true
}
],
"tax_codes": ["french_standard_vat"]
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Customer, CustomerBillingConfiguration
client = Client(api_key='__YOUR_API_KEY__')
metadata_object = Metadata(
display_in_invoice=True,
key='Purchase Order',
value='123456789'
)
customer = Customer(
external_id="5eb02857-a71e-4ea2-bcf9-57d8885990ba",
address_line1="5230 Penfield Ave",
address_line2=None,
city="Woodland Hills",
currency="USD",
country="US",
email="test@example.com",
legal_name="Coleman-Blair",
legal_number="49-008-2965",
tax_identification_number="EU123456789",
logo_url="http://hooli.com/logo.png",
name="Test Name",
phone="1-171-883-3711 x245",
state="CA",
timezone="Europe/Paris",
url="http://hooli.com",
zipcode="91364",
billing_configuration=CustomerBillingConfiguration(
invoice_grace_period=3,
payment_provider="stripe",
provider_customer_id="cus_12345",
sync=true,
sync_with_provider=true,
document_locale="fr"
),
metadata=MetadataList(__root__=[metadata_object])
)
try:
client.customers.create(customer)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.customers.create(
external_id: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
address_line1: "5230 Penfield Ave",
address_line2: nil,
city: "Woodland Hills",
country: "US",
currency: "USD",
email: "dinesh@piedpiper.test",
legal_name: "Coleman-Blair",
legal_number: "49-008-2965",
tax_identification_number: "EU123456789",
logo_url: "http://hooli.com/logo.png",
name: "Gavin Belson",
phone: "1-171-883-3711 x245",
state: "CA",
timezone: "Europe/Paris",
url: "http://hooli.com",
zipcode: "91364",
billing_configuration: {
invoice_grace_period: 3,
payment_provider: "stripe",
provider_customer_id: "cus_12345",
sync: true,
sync_with_provider: true,
document_locale: "fr",
provider_payment_methods: ["card", "sepa_debit", "us_bank_account", "bacs_debit", "link"]
},
metadata: [
{
key: 'Purchase Order',
value: '123456789',
display_in_invoice: true
}
],
tax_codes: ["french_standard_vat"]
)
```
```js Javascript theme={"dark"}
import { BillingConfigurationCustomer } from "lago-javascript-client";
const customerObject = {
external_id: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
address_line1: "5230 Penfield Ave",
city: "Woodland Hills",
currency: "EUR",
country: "US",
email: "dinesh@piedpiper.test",
legal_name: "Coleman-Blair",
legal_number: "49-008-2965",
tax_identification_number: "EU123456789",
logo_url: "http://hooli.com/logo.png",
name: "Gavin Belson",
phone: "1-171-883-3711 x245",
state: "CA",
timezone: "Europe/Paris",
url: "http://hooli.com",
zipcode: "91364",
billing_configuration: {
invoice_grace_period: 3,
paymentProvider:
"stripe" as BillingConfigurationCustomer["paymentProvider"],
provider_customer_id: "cus_12345",
sync: true,
sync_with_provider: true,
document_locale: "fr"
},
metadata: [
{
key: "Purchase Order",
value: "123456789",
display_in_invoice: true,
},
],
};
await client.customers.createCustomer({ customer: customerObject });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customerInput := &lago.CustomerInput{
ExternalID: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
Name: "Gavin Belson",
Email: "dinesh@piedpiper.test",
AddressLine1: "5230 Penfield Ave",
AddressLine2: "",
City: "Woodland Hills",
Country: "US",
Currency: "USD",
State: "CA",
Zipcode: "75001",
LegalName: "Coleman-Blair",
LegalNumber: "49-008-2965",
TaxIdentificationNumber: "EU123456789",
Phone: "+330100000000",
Timezone: "Europe/Paris",
URL: "http://hooli.com",
BillingConfiguration: &CustomerBillingConfigurationInput{
InvoiceGracePeriod: 3,
PaymentProvider: lago.PaymentProviderStripe,
ProviderCustomerID: "cus_123456789",
SyncWithProvider: true,
DocumentLocale: "fr"
},
Metadata: [
&CustomerMetadataInput{
Key: "Purchase Order",
Value: "123456789",
DisplayInInvoice: true
}
]
}
customer, err := lagoClient.Customer().Create(customerInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// You can use the same input to update the customer
customer, err := lagoClient.Customer().Update(customerInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// customer is *lago.Customer
fmt.Println(customer)
}
```
# Retrieve customer portal URL
Source: https://getlago.com/docs/api-reference/customers/customer-portal
GET /customers/{external_customer_id}/portal_url
Retrieves an embeddable link for displaying a customer portal.
This endpoint allows you to fetch the URL that can be embedded to provide customers access to a dedicated portal
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/customers/:external_id/portal_url" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.customers.portal_url('external_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.customers.portal_url('external_id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customer, err := lagoClient.Customer().PortalUrl("__EXTERNAL_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// customer is *lago.Customer
fmt.Println(customer)
}
```
# Delete a customer
Source: https://getlago.com/docs/api-reference/customers/delete
DELETE /customers/{external_customer_id}
This endpoint deletes an existing customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/customers/:external_id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.customers.destroy('external_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.customers.destroy('external_id')
```
```js Javascript theme={"dark"}
await client.customers.deleteCustomer('external_id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customer, err := lagoClient.Customer().Delete("external_id")
if err != nil {
// Error is *lago.Error
panic(err)
}
// customer is *lago.Customer
fmt.Println(customer)
}
```
# List all customers
Source: https://getlago.com/docs/api-reference/customers/get-all
GET /customers
This endpoint retrieves all existing customers.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/customers?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.customers.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.customers.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.customers.findAllCustomers({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customerListInput := &lago.CustomerListInput{
PerPage: 1,
Page: 1,
}
customerResult, err := lagoClient.Customer().GetList(customerListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// customerResult is *lago.CustomerResult
fmt.Println(customerResult)
}
```
# Retrieve a customer
Source: https://getlago.com/docs/api-reference/customers/get-specific
GET /customers/{external_customer_id}
This endpoint retrieves an existing customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/customers/:external_id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.customers.find('external_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.customers.get('external_id')
```
```js Javascript theme={"dark"}
await client.customers.findCustomer('external_id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customer, err := lagoClient.Customer().Get("__EXTERNAL_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// customer is *lago.Customer
fmt.Println(customer)
}
```
# The customer object
Source: https://getlago.com/docs/api-reference/customers/object
This object represents a customer of your business. It lets you create or update a customer, but also track usage and create invoices for the same customer.
# Regenerate checkout URL
Source: https://getlago.com/docs/api-reference/customers/psp-checkout-url
POST /customers/{external_customer_id}/checkout_url
This endpoint regenerates the Payment Provider Checkout URL of a Customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers/:external_id/checkout_url" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.customers.checkout_url('external_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.customers.checkout_url('external_id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customer, err := lagoClient.Customer().CheckoutUrl("__EXTERNAL_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// customer is *lago.Customer
fmt.Println(customer)
}
```
# Update a customer
Source: https://getlago.com/docs/api-reference/customers/update
POST /customers
This endpoint creates a new customer.
This endpoint performs an upsert operation.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"address_line2": "",
"city": "Woodland Hills",
"country": "US",
"currency": "USD",
"email": "dinesh@piedpiper.test",
"legal_name": "Coleman-Blair",
"legal_number": "49-008-2965",
"tax_identification_number": "EU123456789",
"logo_url": "http://hooli.com/logo.png",
"name": "Gavin Belson",
"phone": "1-171-883-3711 x245",
"state": "CA",
"timezone": "Europe/Paris",
"url": "http://hooli.com",
"zipcode": "91364",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"document_locale": "fr",
"provider_payment_methods": ["card", "sepa_debit", "us_bank_account", "bacs_debit", "link"]
},
"metadata": [
{
"key": "Purchase Order",
"value": "123456789",
"display_in_invoice": true
}
],
"tax_codes": ["french_standard_vat"]
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Customer, CustomerBillingConfiguration
client = Client(api_key='__YOUR_API_KEY__')
metadata_object = Metadata(
display_in_invoice=True,
key='Purchase Order',
value='123456789'
)
customer = Customer(
external_id="5eb02857-a71e-4ea2-bcf9-57d8885990ba",
address_line1="5230 Penfield Ave",
address_line2=None,
city="Woodland Hills",
currency="USD",
country="US",
email="test@example.com",
legal_name="Coleman-Blair",
legal_number="49-008-2965",
tax_identification_number="EU123456789",
logo_url="http://hooli.com/logo.png",
name="Test Name",
phone="1-171-883-3711 x245",
state="CA",
timezone="Europe/Paris",
url="http://hooli.com",
zipcode="91364",
billing_configuration=CustomerBillingConfiguration(
invoice_grace_period=3,
payment_provider="stripe",
provider_customer_id="cus_12345",
sync=true,
sync_with_provider=true,
document_locale="fr"
),
metadata=MetadataList(__root__=[metadata_object])
)
try:
client.customers.create(customer)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.customers.create(
external_id: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
address_line1: "5230 Penfield Ave",
address_line2: nil,
city: "Woodland Hills",
country: "US",
currency: "USD",
email: "dinesh@piedpiper.test",
legal_name: "Coleman-Blair",
legal_number: "49-008-2965",
tax_identification_number: "EU123456789",
logo_url: "http://hooli.com/logo.png",
name: "Gavin Belson",
phone: "1-171-883-3711 x245",
state: "CA",
timezone: "Europe/Paris",
url: "http://hooli.com",
zipcode: "91364",
billing_configuration: {
invoice_grace_period: 3,
payment_provider: "stripe",
provider_customer_id: "cus_12345",
sync: true,
sync_with_provider: true,
document_locale: "fr",
provider_payment_methods: ["card", "sepa_debit", "us_bank_account", "bacs_debit", "link"]
},
metadata: [
{
key: 'Purchas Order',
value: '123456789',
display_in_invoice: true
}
],
tax_codes: ["french_standard_vat"]
)
```
```js Node.js theme={"dark"}
import { BillingConfigurationCustomer } from "lago-javascript-client";
const customerObject = {
externalId: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
addressLine1: "5230 Penfield Ave",
city: "Woodland Hills",
currency: "EUR",
country: "US",
email: "dinesh@piedpiper.test",
legalName: "Coleman-Blair",
legalNumber: "49-008-2965",
taxIdentificationNumber: "EU123456789",
logoUrl: "http://hooli.com/logo.png",
name: "Gavin Belson",
phone: "1-171-883-3711 x245",
state: "CA",
timezone: "Europe/Paris",
url: "http://hooli.com",
zipcode: "91364",
billingConfiguration: {
invoiceGracePeriod: 3,
paymentProvider:
"stripe" as BillingConfigurationCustomer["paymentProvider"],
providerCustomerId: "cus_12345",
sync: true,
syncWithProvider: true,
documentLocale: "fr"
},
metadata: [
{
key: "Purchase Order",
value: "123456789",
displayInInvoice: true,
},
],
};
await client.customers.createCustomer({ customer: customerObject });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
customerInput := &lago.CustomerInput{
ExternalID: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
Name: "Gavin Belson",
Email: "dinesh@piedpiper.test",
AddressLine1: "5230 Penfield Ave",
AddressLine2: "",
City: "Woodland Hills",
Country: "US",
Currency: "USD",
State: "CA",
Zipcode: "75001",
LegalName: "Coleman-Blair",
LegalNumber: "49-008-2965",
TaxIdentificationNumber: "EU123456789",
Phone: "+330100000000",
Timezone: "Europe/Paris",
URL: "http://hooli.com",
BillingConfiguration: &CustomerBillingConfigurationInput{
InvoiceGracePeriod: 3,
PaymentProvider: lago.PaymentProviderStripe,
ProviderCustomerID: "cus_123456789",
SyncWithProvider: true,
DocumentLocale: "fr"
},
Metadata: [
&CustomerMetadataInput{
Key: "Purchase Order",
Value: "123456789",
DisplayInInvoice: true
}
]
}
customer, err := lagoClient.Customer().Create(customerInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// You can use the same input to update the customer
customer, err := lagoClient.Customer().Update(customerInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// customer is *lago.Customer
fmt.Println(customer)
}
```
# Create a feature
Source: https://getlago.com/docs/api-reference/entitlements/features/create-feature
POST /features
This endpoint creates a new feature representing an entitlement component of your application.
# Delete a feature
Source: https://getlago.com/docs/api-reference/entitlements/features/delete-feature
DELETE /features/{code}
This endpoint deletes an existing feature representing an entitlement component of your application. Deleting a feature will remove it from all plans and subscriptions.
# Delete a feature privilege
Source: https://getlago.com/docs/api-reference/entitlements/features/delete-privilege
DELETE /features/{code}/privileges/{privilege_code}
Delete privilege from feature. Deleting a privilege removes it from all plans and subscriptions.
# The feature object
Source: https://getlago.com/docs/api-reference/entitlements/features/feature-object
This object represents a feature of your business, that can be entitled to a customer through a plan or a subscription.
# List all features
Source: https://getlago.com/docs/api-reference/entitlements/features/get-all-features
GET /features
This endpoint retrieves all existing features that represent entitlement components of your application.
# Retrieve a feature
Source: https://getlago.com/docs/api-reference/entitlements/features/get-feature
GET /features/{code}
This endpoint retrieves an existing feature that represents an entitlement component of your application. The feature is identified by its unique code.
# Update a feature
Source: https://getlago.com/docs/api-reference/entitlements/features/update-feature
PUT /features/{code}
This endpoint updates an existing feature representing an entitlement component of your application.
# Create plan entitlements
Source: https://getlago.com/docs/api-reference/entitlements/plan-entitlements/create-plan-entitlement
POST /plans/{code}/entitlements
This endpoint creates new entitlements by adding features to a plan. Note that all existing entitlements will be deleted and replaced by the ones provided. To add a new entitlement without removing the existing ones, use PATCH. The feature must exist and all privileges must be valid for the feature.
# Delete a plan entitlement
Source: https://getlago.com/docs/api-reference/entitlements/plan-entitlements/delete-plan-entitlement
DELETE /plans/{code}/entitlements/{feature_code}
This endpoint deletes an existing entitlement by removing the feature from the plan.
# Delete a plan entitlement privilege
Source: https://getlago.com/docs/api-reference/entitlements/plan-entitlements/delete-plan-entitlement-privilege
DELETE /plans/{code}/entitlements/{feature_code}/privileges/{privilege_code}
This endpoint removes a specific privilege and its value from an entitlement. The privilege remains untouched on the original feature.
# List plan entitlements
Source: https://getlago.com/docs/api-reference/entitlements/plan-entitlements/get-all-plan-entitlements
GET /plans/{code}/entitlements
This endpoint retrieves all entitlements for a specific plan.
# Retrieve a plan entitlement
Source: https://getlago.com/docs/api-reference/entitlements/plan-entitlements/get-specific-plan-entitlement
GET /plans/{code}/entitlements/{feature_code}
This endpoint retrieves a specific entitlement for a plan.
# The plan entitlement object
Source: https://getlago.com/docs/api-reference/entitlements/plan-entitlements/plan-entitlement-object
This object represents entitlements belonging to a plan.
# Update plan entitlements
Source: https://getlago.com/docs/api-reference/entitlements/plan-entitlements/update-plan-entitlement
PATCH /plans/{code}/entitlements
This accepts a list of entitlements to update. If the feature isn't part of the plan yet, it's added with all the privileges from the payload. If the feature is already part of the plan, the privilege and values are updated or added. All privileges must be valid for the feature. All features and privileges not part of the payload are left untouched. To remove privileges or features, use the DELETE endpoints.
# Delete a subscription entitlement
Source: https://getlago.com/docs/api-reference/entitlements/subscription-entitlements/delete-subscription-entitlement
DELETE /subscriptions/{external_id}/entitlements/{feature_code}
This endpoint removes a specific feature entitlement from a subscription. The entitlement remains available from the plan.
# Delete a subscription entitlement privilege
Source: https://getlago.com/docs/api-reference/entitlements/subscription-entitlements/delete-subscription-entitlement-privilege
DELETE /subscriptions/{external_id}/entitlements/{feature_code}/privileges/{privilege_code}
This endpoint removes a specific privilege from a subscription entitlement. The privilege entitlement remains available from the plan.
# List subscription entitlements
Source: https://getlago.com/docs/api-reference/entitlements/subscription-entitlements/get-all-subscription-entitlements
GET /subscriptions/{external_id}/entitlements
This endpoint retrieves all entitlements for a specific subscription, including both plan entitlements and any subscription-specific overrides.
# The subscription entitlement object
Source: https://getlago.com/docs/api-reference/entitlements/subscription-entitlements/subscription-entitlement-object
This object represents entitlements belonging to a subscription.
# Update subscription entitlements
Source: https://getlago.com/docs/api-reference/entitlements/subscription-entitlements/update-subscription-entitlement
PATCH /subscriptions/{external_id}/entitlements
This accepts a list of entitlements to update. If the feature isn't part of the subscription yet, it's added with all the privileges from the payload. If the feature is already part of the subscription (via plan or via override), the privilege and values are updated or added. All privileges must be valid for the feature. All features and privileges not part of the payload are left untouched. To remove privileges or features, use the DELETE endpoints.
# Errors
Source: https://getlago.com/docs/api-reference/errors
The Lago API uses standard HTTP response codes to clearly indicate the result of each API request:
* **2xx**: Success - The request was processed successfully.
* **4xx**: Client Error - There was an issue with the request, such as missing parameters, invalid input, or unauthorized access.
* **5xx**: Server Error - An error occurred on Lago's side while processing the request.
For some 4xx errors, the response body will include additional information to help you understand and resolve the specific problem.
```json Validation errors theme={"dark"}
{
"status": 422,
"error": "Unprocessable Entity",
"code": "validation_errors",
"error_details": {
"code": [
"value_is_mandatory"
]
}
}
```
```json Not found theme={"dark"}
{
"status": 404,
"error": "Not Found",
"code": "subscription_not_found"
}
```
```json Forbidden theme={"dark"}
{
"status": 403,
"error": "Forbidden",
"code": "feature_unavailable"
}
```
```json Unauthorized theme={"dark"}
{
"status": 401,
"error": "Unauthorized"
}
```
## Error fields
The HTTP status code.
A generic error message.
A generic error code representing the type of error.
The code of the payment provider that caused the error when applicable.
An object containing the error details. It usually maps the field names that caused the error to an array of
error messages/codes.
For specific errors, such as a payment provider error, the `error_details` may include other fields.
## Error codes
### bad\_request\_error
```json theme={"dark"}
{ "status": 400, "error": "BadRequest: [error.message]" }
```
**Examples:**
* `coupons_must_be_an_array`
* `subscriptions_must_be_an_object`
### unauthorized\_error
```json theme={"dark"}
{ "status": 401, "error": "[message]" }
```
**Examples:**
* `Unauthorized`
* `expired_jwt_token`
### forbidden\_error
```json theme={"dark"}
{ "status": 403, "error": "Forbidden", "code": "[error_code]" }
```
**Examples:**
* `feature_unavailable`
* `feature_not_available`
* `[mode]_action_not_allowed_for_[resource_name]`
### not\_found\_error
```json theme={"dark"}
{ "status": 404, "error": "Not Found", "code": "[resource]_not_found" }
```
**Examples:**
* `invoice_not_found`
* `customer_not_found`
* `subscription_not_found`
* `billing_entity_not_found`
* `plan_not_found`
* `add_on_not_found`
* `coupon_not_found`
* `tax_not_found`
* `feature_not_found`
* `privilege_not_found`
* `billable_metric_not_found`
* `webhook_endpoint_not_found`
* `api_log_not_found`
* `activity_log_not_found`
* `payment_not_found`
* `payment_receipt_not_found`
* `fee_not_found`
* `event_not_found`
* `credit_note_not_found`
* `wallet_not_found`
* `wallet_transaction_not_found`
* `lifetime_usage_not_found`
* `alert_not_found`
* `entitlement_not_found`
### method\_not\_allowed\_error
```json theme={"dark"}
{ "status": 405, "error": "Method Not Allowed", "code": "[error_code]" }
```
**Examples:**
* `feature_not_supported`
* `invalid_type_or_status`
* `credit_note_voided`
* `no_voidable_amount`
* `invoices_not_overdue`
* `invoices_have_different_currencies`
* `invoices_not_ready_for_payment_processing`
* `premium_integration_missing`
* `metadata_on_draft_invoice`
* `payment_status_update_on_draft_invoice`
* `not_voidable`
* `is_draft`
* `invalid_status`
* `last_admin`
* `cannot_revoke_own_membership`
* `enabled_authentication_methods_required`
* `signup_disabled`
* `plan_overlapping`
* `wallet_not_active`
* `is_succeeded`
* `no_active_subscription`
* `status_not_voided`
* `invoice_not_finalized`
* `invoice_payment_already_succeeded`
* `invoice_due_date_in_future`
* `invoice_dispute_lost`
* `payment_processor_is_currently_handling_payment`
* `invoiced_fee`
* `eu_tax_not_applicable`
* `not_disputable`
* `only_one_limitation_type_per_coupon_allowed`
### validation\_errors
```json theme={"dark"}
{ "status": 422, "error": "Unprocessable Entity", "code": "validation_errors", "error_details": [validation_errors] }
```
### provider\_error
```json theme={"dark"}
{ "status": 422, "error": "Unprocessable Entity", "code": "provider_error", "provider": { "code": "[provider_code]" }, "error_details": [serialized_error] }
```
### third\_party\_error
```json theme={"dark"}
{ "status": 422, "error": "Unprocessable Entity", "code": "third_party_error", "error_details": { "third_party": "[third_party]", "thirdparty_error": "[error_message]" } }
```
### stripe\_required\_error
```json theme={"dark"}
{ "status": 422, "error": "Unprocessable Entity", "code": "stripe_required", "message": "Only Stripe is supported for authorization" }
```
### too\_many\_provider\_requests\_error
```json theme={"dark"}
{ "status": 429, "error": "Too Many Provider Requests", "code": "too_many_provider_requests", "error_details": { "provider_name": "[provider_name]", "message": "[message]" } }
```
### internal\_server\_error
```json theme={"dark"}
{ "status": 500, "errors": [{ "message": "[error_message]", "backtrace": [backtrace] }], "data": {} }
```
### health\_check\_error
```json theme={"dark"}
{ "version": "[version]", "github_url": "[url]", "message": "Unhealthy", "details": "[error_message]" }
```
# Batch usage events
Source: https://getlago.com/docs/api-reference/events/batch
POST /events/batch
This endpoint can be used to send a batch of usage records. Each request may include up to 100 events.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/events/batch" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"events": [
{
"transaction_id": "__UNIQUE_ID__",
"external_subscription_id": "__YOUR_SUBSCRIPTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"timestamp": $(date +%s),
"properties": {
"custom_field": 12
}
}
]
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import BatchEvent
client = Client(api_key='__YOUR_API_KEY__')
# Create a list of events
batch_event = BatchEvent(events=[
Event(
transaction_id="__UNIQUE_ID_1__",
external_subscription_id="__SUBSCRIPTION_ID_1__",
code="__BILLABLE_METRIC_CODE__",
timestamp=1650893379,
properties={"custom_field": "custom"}
),
Event(
transaction_id="__UNIQUE_ID_2__",
external_subscription_id="__SUBSCRIPTION_ID_2__",
code="__BILLABLE_METRIC_CODE__",
timestamp=1650893380,
properties={"custom_field": "custom"}
)
# Add more events as needed
])
try:
client.events.batch_create(batch_event)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
# Create an array of event hashes
events = [
{
transaction_id: "__UNIQUE_ID_1__",
external_subscription_id: "__SUBSCRIPTION_ID_1__",
code: "__BILLABLE_METRIC_CODE__",
timestamp: Time.now.to_i,
properties: {
custom_field: "custom value 1"
}
},
{
transaction_id: "__UNIQUE_ID_2__",
external_subscription_id: "__SUBSCRIPTION_ID_2__",
code: "__BILLABLE_METRIC_CODE__",
timestamp: Time.now.to_i,
properties: {
custom_field: "custom value 2"
}
}
# Add more events as needed
]
client.events.batch_create(events)
```
```js Javascript theme={"dark"}
const batchEvent = [
{
transaction_id: "__UNIQUE_TRANSACTION_ID_1__",
external_subscription_id: "__SUBSCRIPTION_ID_1__",
code: "__BILLABLE_METRIC_CODE__",
timestamp: 1650893379,
properties: { customField: "custom1" },
},
{
transaction_id: "__UNIQUE_TRANSACTION_ID_2__",
external_subscription_id: "__SUBSCRIPTION_ID_2__",
code: "__BILLABLE_METRIC_CODE__",
timestamp: 1650893380,
properties: { customField: "custom2" },
},
// Add more events as needed
];
await client.events.createBatchEvents({ events: batchEvent });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
ctx := context.Background()
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
event := lago.EventInput{
TransactionID: "__UNIQUE_TRANSACTION_ID__",
ExternalSubscriptionID: "__UNIQUE_SUBSCRIPTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
Timestamp: strconv.FormatInt(time.Now().Unix(), 10),
Properties: map[string]interface{}{
"nbusers": "12",
},
}
batchInput := make([]lago.EventInput, 1)
batchInput[0] = event
res, err := lagoClient.Event().Batch(ctx, &batchInput)
}
```
# Estimate an upcoming fee
Source: https://getlago.com/docs/api-reference/events/estimated-fee
POST /events/estimate_fees
Estimate the fees that would be created after reception of an event for a billable metric attached to one or multiple pay in advance charges.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/events/estimate_fees" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"external_subscription_id": "__YOUR_SUBSCRIPTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"properties": {
"custom_field": 12,
}
}
}'
```
```python Python theme={"dark"}
from lago_python_client.models import Event
event = Event(
external_subscription_id="__YOUR_SUBSCRIPTION_ID__",
code="__BILLABLE_METRIC_CODE__",
)
client.events.estimate_fees(event)
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.events.estimate_fees(
external_subscription_id: "__YOUR_SUBSCRIPTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
properties: {
custom_field: 12,
}
)
```
```js Javascript theme={"dark"}
import { Client, getLagoError } from 'lago-javascript-client';
const lagoClient = Client('__YOUR_API_KEY__');
try {
const { data } = await lagoClient.events.eventEstimateFees(estimateEvent);
} catch (error) {
const lagoError = await getLagoError(error);
}
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
eventEstimateInput := &lago.EventEstimateFeesInput{
ExternalSubscriptionID: "__YOUR_SUBSCRIPTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
Properties: map[string]string{
"custom_field": "12",
},
}
err := lagoClient.Event().EstimateFees(eventEstimateInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
}
```
# The event object
Source: https://getlago.com/docs/api-reference/events/event-object
Events represents usage measurement sent to lago application that will then be aggregated into invoice line items.
# Retrieve an event
Source: https://getlago.com/docs/api-reference/events/get-specific
GET /events/{transaction_id}
This endpoint is used for retrieving a specific usage measurement event that has been sent to a customer or a subscription.
Note that transaction_id is unique per external_subscription_id so multiple subscriptions can share the same transaction_id. This endpoint will only return the first event found with the given transaction_id.
WARNING: If your Lago organization is configured to use the Clickhouse-based event pipeline, multiple events can share the same `transaction_id` (with different timestamps). This endpoint will only return the first event found.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/events/:transaction_id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.events.find("transaction_id")
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.events.get('transaction_id')
```
```js Javascript theme={"dark"}
await client.events.findEvent("__UNIQUE_TRANSACTION_ID__");
```
# List all events
Source: https://getlago.com/docs/api-reference/events/list-events
GET /events
This endpoint is used for retrieving all events.
# Send usage event
Source: https://getlago.com/docs/api-reference/events/usage
POST /events
This endpoint is used for transmitting usage measurement events to either a designated customer or a specific subscription.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__UNIQUE_ID__",
"external_subscription_id": "__YOUR_SUBSCRIPTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"timestamp": $(date +%s),
"properties": {
"custom_field": 12
}
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Event
client = Client(api_key='__YOUR_API_KEY__')
event = Event(
transaction_id="__UNIQUE_ID__",
external_subscription_id="__UNIQUE_ID__",
code="__BILLABLE_METRIC_CODE__",
timestamp=1650893379,
properties={"custom_field": "custom"}
)
try:
client.events.create(event)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.events.create(
transaction_id: "__UNIQUE_ID__",
external_subscription_id: "__SUBSCRIPTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
timestamp: Time.now.to_i,
properties: {
custom_field: 12
}
)
```
```js Javascript theme={"dark"}
await client.events.createEvent({
event: {
transaction_id: "__UNIQUE_TRANSACTION_ID__",
external_subscription_id: "__UNIQUE_SUBSCRIPTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
timestamp: 1650893379,
properties: { customField: "custom" },
},
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
ctx := context.Background()
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
eventInput := &lago.EventInput{
TransactionID: "__UNIQUE_TRANSACTION_ID__",
ExternalSubscriptionID: "__UNIQUE_SUBSCRIPTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
Timestamp: strconv.FormatInt(time.Now().Unix(), 10),
Properties: map[string]interface{}{
"nbusers": "12",
},
}
res, err := lagoClient.Event().Create(ctx, eventInput)
if err != nil {
// err is *lago.Error
panic(err)
}
// res is *lago.Event
fmt.Println(*res)
}
```
# Delete a fee
Source: https://getlago.com/docs/api-reference/fees/destroy-fee
DELETE /fees/{lago_id}
This endpoint is used for deleting a specific fee that has not yet been invoiced
# The fee object
Source: https://getlago.com/docs/api-reference/fees/fee-object
This object represents a line item of an invoice, handling amount, billed units and item description.
# List all fees
Source: https://getlago.com/docs/api-reference/fees/list-fees
GET /fees
This endpoint is used for retrieving all fees that has been issued.
```bash cURL theme={"dark"}
curl --location --request GET "$LAGO_URL/api/v1/fees?page=2&per_page=20&external_customer_id=hooli_1234" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client.fees.find_all({'per_page': 2, 'page': 1})
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client.fees.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.fees.findAllFees({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
feeListInput := &lago.FeeListInput{
PerPage: 1,
Page: 1,
CreatedAtFrom: "2022-01-01T00:00:00Z",
CreatedAtTo: "2022-01-01T00:00:00Z",
}
feeResult, err := lagoClient.Fee().GetList(feeListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// feeResult is *lago.FeeResult
fmt.Println(feeResult)
```
# Retrieve a fee
Source: https://getlago.com/docs/api-reference/fees/retrieve-fee
GET /fees/{lago_id}
This endpoint is used for retrieving a specific fee that has been issued.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
FEE_ID="__YOUR_FEE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/fees/$FEE_ID" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.fees.find('id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.fees.get('id')
```
```js Javascript theme={"dark"}
await client.fees.findFee('fee-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
fee, err := lagoClient.Fees().Get("id")
if err != nil {
// Error is *lago.Error
panic(err)
}
// credit note is *lago.Fee
fmt.Println(fee)
}
```
# Update a fee
Source: https://getlago.com/docs/api-reference/fees/update-fee
PUT /fees/{lago_id}
This endpoint is used for updating a specific fee that has been issued.
```bash cURL theme={"dark"}
curl --location --request PUT "$LAGO_URL/api/v1/fees/1a901a90-1a90-1a90-1a90-1a901a901a90" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"fee": {
"payment_status": "succeeded"
}
}'
```
```python Python theme={"dark"}
from lago_python_client.models import Fee
fee_update = Fee(
payment_status="succeeded",
)
client.fees.update(fee_update, "1a901a90-1a90-1a90-1a90-1a901a901a90")
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client.fees.update({
lago_id: "1a901a90-1a90-1a90-1a90-1a901a901a90",
payment_status: "succeeded",
})
```
```js Javascript theme={"dark"}
const feeObject = {
payment_status: "succeeded" as FeeObject["payment_status"],
};
await client.fees.updateFee("1a901a90-1a90-1a90-1a90-1a901a901a90", {
fee: feeObject,
});
```
```go Go theme={"dark"}
feeId, _ := uuid.Parse("1a901a90-1a90-1a90-1a90-1a901a901a90")
feeInput := &lago.FeeInput{
LagoID: invoiceId,
PaymentStatus: lago.FeePaymentStatusSucceeded,
}
fee, err := lagoClient.Fee().Update(feeInput)
if err != nil {
panic(err)
}
// fee is *lago.Fee
fmt.Println(fee)
}
```
# Introduction
Source: https://getlago.com/docs/api-reference/intro
Lago API allows your application to push customer information and metrics (events) from your application to the billing application.
To integrate it into your application, you can use the JSON HTTP API or one of
the Lago libraries (depending on your programming language or framework).
You must retrieve your API key from your account.
## Configuration[](#configuration "Direct link to heading")
```shell theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/..." \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '...'
```
**Install package with pip**
```bash theme={"dark"}
pip install lago-python-client
```
**Usage**
```python theme={"dark"}
from lago_python_client import Client
# By default, this connects to Lago's hosted servers in the US region.
client = Client(api_key='__YOUR_API_KEY__')
# If you are self-hosting Lago or using a different server region,
# specify the API URL to connect to the correct instance.
# Replace '__YOUR_LAGO_URL__' with the appropriate URL for your Lago server.
# Example: 'https://api.eu.getlago.com/' for the EU region.
# client = Client(api_key='__YOUR_API_KEY__', api_url='__YOUR_LAGO_URL__')
```
**Add the gem in your Gemfile**
```bash theme={"dark"}
bundle add lago-ruby-client
```
Or if bundler is not being used to manage dependencies, install the gem by
executing:
```bash theme={"dark"}
gem install lago-ruby-client
```
**Usage**
```ruby theme={"dark"}
require 'lago-ruby-client'
# By default, this will connect to the US region of Lago's hosted servers.
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
# If you are self-hosting Lago or using Lago in a different region (e.g., Europe),
# you need to specify the API URL to connect to the correct server.
# For example, you can provide the base URL for your specific Lago instance.
# This example shows how to specify a different Lago server when needed.
#
# Replace '__YOUR_LAGO_URL__' with the appropriate URL of your Lago instance.
# Example: 'https://api.eu.getlago.com/' for the EU region.
#
# client = Lago::Api::Client.new(
# api_key: '__YOUR_API_KEY__',
# api_url: '__YOUR_LAGO_URL__'
# )
```
**Install package with npm**
```bash theme={"dark"}
npm install lago-javascript-client
```
**Usage**
```js theme={"dark"}
import { Client } from 'lago-javascript-client'
// By default, this will connect to Lago's hosted servers in the US region.
const client = Client('__YOUR_API_KEY__')
// If you are self-hosting Lago or using a different region (e.g., EU),
// you need to specify the base URL to connect to the correct Lago instance.
// Replace '__YOUR_LAGO_URL__' with the appropriate URL for your Lago instance.
// Example: 'https://api.eu.getlago.com/' for the EU region.
// const client = Client('__YOUR_API_KEY__', { baseUrl: '__YOUR_LAGO_URL__' })
```
**Install package**
```bash theme={"dark"}
go get github.com/getlago/lago-go-client@v1
```
**Usage**
```go theme={"dark"}
import "github.com/getlago/lago-go-client"
func main() {
// By default, this will connect to Lago's hosted servers in the US region.
lagoClient := lago.New().SetApiKey("__YOU_API_KEY__")
// If you are self-hosting Lago or using a different region (e.g., EU),
// you need to specify the base URL to connect to the correct Lago instance.
// Replace '__YOUR_LAGO_URL__' with the appropriate URL for your Lago instance.
// Example: 'https://api.eu.getlago.com/' for the EU region.
// lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__").SetBaseURL("__YOUR_LAGO_URL__")
}
```
# Create a one-off invoice
Source: https://getlago.com/docs/api-reference/invoices/create-oneoff
POST /invoices
This endpoint is used for issuing a one-off invoice.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"invoice": {
"external_customer_id": "hooli_1234",
"currency": "USD",
"fees": [
{
"add_on_code": "setup_fee",
"units": 2.5,
"unit_amount_cents": 1200,
"description": "This is a description.",
"tax_codes": ["french_standard_vat]
}
]
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import InvoiceFee, OneOffInvoice, InvoiceFeesList
client = Client(api_key='__YOUR_API_KEY__')
fee_object = InvoiceFee(
add_on_code='setup_fee',
units=2.5,
unit_amount_cents=1200,
description='This is a description.'
)
invoice_create = OneOffInvoice(
external_customer_id="hooli_1234",
currency="USD",
fees=InvoiceFeesList(__root__=[fee_object])
)
try:
client.invoices.create(invoice_create)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.create({
external_customer_id: "hooli_1234",
currency: 'USD',
fees: [
{
add_on_code: 'setup_fee',
units: 2.5,
unit_amount_cents: 1200,
description: 'This is a description.'
}
]
})
```
```js Javascript theme={"dark"}
const invoiceObject = {
external_customer_id: "hooli_1234",
currency: "USD",
fees: [
{
add_on_code: "setup_fee",
description: "This is a description.",
units: 2.5,
unit_amount_cents: 1200,
},
],
};
await client.invoices.createInvoice({
invoice: invoiceObject,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoiceInput := &lago.OneOffInput{
ExternalCustomerId: custID,
currency: "USD",
Fees: [
&InvoiceFeesInput{
AddOnCode: "setup_fee",
Description: "This is a description.",
Units: 2.5,
UnitAmountCents: 1200
}
]
}
invoice, err := lagoClient.Invoice().Create(invoiceInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoice is *lago.Invoice
fmt.Println(invoice)
}
```
# Download an invoice
Source: https://getlago.com/docs/api-reference/invoices/download
POST /invoices/{lago_id}/download
This endpoint is used for downloading a specific invoice PDF document.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOUR_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/$INVOICE_ID/download" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
invoice = None
try:
invoice = client.invoices.download('__YOUR_INVOICE_ID__') # Invoice ID
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.download('__YOUR_INVOICE_ID__') // Invoice ID
```
```js Javascript theme={"dark"}
await client.invoices.downloadInvoice('invoice-id');
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoice, err := lagoClient.Invoice().Download("__YOUR_INVOICE_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoice is *lago.Invoice
fmt.Println(invoice)
// If the invoice has to be generated, the response is empty
// And you will get a webhook `invoice.generated`
}
```
# Finalize an invoice
Source: https://getlago.com/docs/api-reference/invoices/finalize
PUT /invoices/{lago_id}/finalize
This endpoint is used for finalizing a draft invoice.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/invoices/:lago_invoice_id/finalize" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.invoices.finalize('__INVOICE_ID__') # Invoice ID
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.finalize('__INVOICE_ID__') // Invoice ID
```
```js Javascript theme={"dark"}
await client.invoices.finalizeInvoice("invoice-id");
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoice, err := lagoClient.Invoice().Finalize("__YOUR_INVOICE_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoice is *lago.Invoice
fmt.Println(invoice)
}
```
# List all invoices
Source: https://getlago.com/docs/api-reference/invoices/get-all
GET /invoices
This endpoint is used for retrieving all invoices.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/invoices?page=2&per_page=20&external_customer_id=hooli_1234" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.invoices.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.invoices.findAllInvoices({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoiceListInput := &lago.InvoiceListInput{
PerPage: 1,
Page: 1,
IssuingDateFrom: "2022-01-01",
IssuingDateTo: "2022-01-01",
}
invoiceResult, err := lagoClient.Invoice().GetList(invoiceListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoiceResult is *lago.InvoiceResult
fmt.Println(invoiceResult)
}
```
# Retrieve an invoice
Source: https://getlago.com/docs/api-reference/invoices/get-specific
GET /invoices/{lago_id}
This endpoint is used for retrieving a specific invoice that has been issued.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/invoices/:lago_id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.invoices.find('lago_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.get('lago_id')
```
```js Javascript theme={"dark"}
await client.invoices.findInvoice('lago-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoice, err := lagoClient.Invoice().Get("lago_id")
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoice is *lago.Invoice
fmt.Println(invoice)
}
```
# The invoice object
Source: https://getlago.com/docs/api-reference/invoices/invoice-object
This object represents an invoice generated by Lago for a specific customer. This invoice summarizes the fees generated by a subscription, usage-based charges, prepaid credit purchases, or one-off invoices.
# Generate a payment URL
Source: https://getlago.com/docs/api-reference/invoices/payment-url
POST /invoices/{lago_id}/payment_url
This endpoint generates a checkout link for a specific invoice.
# Preview an invoice
Source: https://getlago.com/docs/api-reference/invoices/preview
POST /invoices/preview
This endpoint is used for generating invoice preview.
# Refresh an invoice
Source: https://getlago.com/docs/api-reference/invoices/refresh
PUT /invoices/{lago_id}/refresh
This endpoint is used for refreshing a draft invoice.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/invoices/:lago_invoice_id/refresh" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.invoices.refresh('__INVOICE_ID__') # Invoice ID
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.refresh('__INVOICE_ID__') // Invoice ID
```
```js Javascript theme={"dark"}
await client.invoices.refreshInvoice('invoice-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoice, err := lagoClient.Invoice().Refresh("__INVOICE_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoice is *lago.Invoice
fmt.Println(invoice)
}
```
# Retry an invoice payment
Source: https://getlago.com/docs/api-reference/invoices/retry
POST /invoices/{lago_id}/retry_payment
This endpoint resends an invoice for collection and retry a payment.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/$INVOICE_ID/retry_payment" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
invoice = None
try:
invoice = client.invoices.retry_payment('__INVOICE_ID__') # Invoice ID
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.retry_payment('__INVOICE_ID__') // Invoice ID
```
```js Javascript theme={"dark"}
await client.invoices.retryPayment("invoice-id");
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoice, err := lagoClient.Invoice().RetryPayment("__INVOICE_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoice is *lago.Invoice
fmt.Println(invoice)
// If the invoice has to be generated, the response is empty
// And you will get a webhook `invoice.generated`
}
```
# Retry an invoice finalization
Source: https://getlago.com/docs/api-reference/invoices/retry_finalization
POST /invoices/{lago_id}/retry
This endpoint is used for retrying to generate a failed invoice.
# Update an invoice
Source: https://getlago.com/docs/api-reference/invoices/update
PUT /invoices/{lago_id}
This endpoint is used for updating an existing invoice.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/invoices/:lago_id" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"invoice": {
"payment_status": "succeeded",
"metadata": [
{
"id": "__METADATA_ID__",
"key": "digital_ref_id",
"value": "INV-0123456-98765"
}
]
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import InvoicePaymentStatusChange
client = Client(api_key='__YOUR_API_KEY__')
metadata_object = InvoiceMetadata(
key='key',
value='value'
)
invoice_update = Invoice(
payment_status="succeeded",
metadata=InvoiceMetadataList(__root__=[metadata_object])
)
try:
client.invoices.update(invoice_update, "__INVOICE_ID__")
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
# Deprecated
payment_status_change = InvoicePaymentStatusChange(
payment_status="succeeded"
)
try:
client.invoices.update(payment_status_change, "__INVOICE_ID__")
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.invoices.update({
lago_id: "__INVOICE_ID__",
payment_status: "succeeded",
metadata: [
{
key: 'key',
value: 'value'
}
]
})
```
```js Javascript theme={"dark"}
const invoiceObject = {
payment_status: "succeeded" as InvoiceObject["payment_status"],
metadata: [
{
key: "key",
value: "value",
},
],
};
await client.invoices.updateInvoice("invoice-id", {
invoice: invoiceObject,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
invoiceId, _ := uuid.Parse("__YOUR_INVOICE_ID__")
invoiceInput := &lago.InvoiceInput{
LagoID: invoiceId,
PaymentStatus: lago.InvoicePaymentStatusSucceeded,
Metadata: [
&InvoiceMetadataInput{
Key: "Key",
Value: "Value"
}
]
}
invoice, err := lagoClient.Invoice().Update(invoiceInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// invoice is *lago.Invoice
fmt.Println(invoice)
}
```
# Void an invoice
Source: https://getlago.com/docs/api-reference/invoices/void
POST /invoices/{lago_id}/void
This endpoint is used for voiding an invoice.
• When no body parameters are provided, the invoice can be voided only if it is in a `finalized` status and its payment status is NOT `succeeded`.
• When `generate_credit_note` is provided (optionally with `refund_amount` and/or `credit_amount`), this validation is bypassed: the invoice is forcibly voided and a credit note is generated. If the specified refund/credit amounts do not cover the full invoice total, the remainder is issued on a second credit note that is created and immediately voided.
# The organization object
Source: https://getlago.com/docs/api-reference/organizations/organization-object
This object represents your organization. You can define all invoicing details and settings within it.
# Update organization (deprecated)
Source: https://getlago.com/docs/api-reference/organizations/update
PUT /organizations
This endpoint is used to update your own organization's settings.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/organizations" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"organization": {
"webhook_url": "https://webhook.brex.com",
"country": "US",
"address_line1": "100 Brex Street",
"address_line2": null,
"state": "NYC",
"zipcode": "10000",
"email": "brex@brex.com",
"city": "New York",
"legal_name": null,
"legal_number": null,
"net_payment_term": 30,
"tax_identification_number": "US123456789",
"timezone": "America/New_York",
"default_currency": "USD",
"document_numbering": "per_customer",
"document_number_prefix": "LAGO-INV",
"email_settings": [
"invoice.finalized",
"credit_note.created"
],
"billing_configuration": {
"invoice_footer": "This is my customer footer",
"invoice_grace_period": 3,
"document_locale": "en",
"vat_rate": 12.5
}
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Organization, OrganizationBillingConfiguration
client = Client(api_key='__YOUR_API_KEY__')
params = Organization(
timezone="America/New_York",
webhook_url="https://webhook.brex.com",
email_settings=["invoice.finalized"],
tax_identification_number="US123456789",
default_currency="USD",
document_numbering= "per_customer",
document_number_prefix= "LAGO-INV",
billing_configuration=OrganizationBillingConfiguration(
invoice_footer="This is my customer footer",
invoice_grace_period=3,
document_locale="en",
vat_rate=12.5
)
)
try:
client.organizations.update(params)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
update_params = {
timezone: 'America/New_York',
webhook_url: 'https://webhook.brex.com',
email_settings: ['invoice.finalized'],
tax_identification_number: "US123456789",
default_currency: "USD",
document_numbering: 'per_customer',
document_number_prefix: 'LAGO-INV',
billing_configuration: {
invoice_footer="This is my customer footer",
invoice_grace_period=3,
document_locale: "en",
vat_rate: 12.5
}
}
client.organizations.update(update_params)
```
```js Javascript theme={"dark"}
await client.organizations.updateOrganization({
organization: {
timezone: "America/New_York",
webhook_url: "https://webhook.brex.com",
email_settings: ["invoice.finalized"],
tax_identification_number: "US123456789",
default_currency: "USD",
document_numbering: "per_customer",
document_number_prefix: "LAGO-INV",
billing_configuration: {
invoice_footer: "This is my customer footer",
invoice_grace_period: 3,
document_locale: "en",
vat_rate: 12.5,
},
},
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
organizationInput := &lago.OrganizationInput{
LegalName: "Legal Name",
Timezone: "America/New_York",
EmailSettings: ["invoice.finalized"],
TaxIdentificationNumber: "US123456789",
DefaultCurrency: "USD",
BillingConfiguration: &OrganizationBillingConfigurationInput{
InvoiceFooter: "This is my customer foote",
InvoiceGracePeriod: 3,
DocumentLocale: "en",
VatRate: 12.5,
}
}
organization, err := lagoClient.Organization().Update(organizationInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// organization is *lago.Organization
fmt.Println(organization)
}
```
# Pagination
Source: https://getlago.com/docs/api-reference/pagination
Many API endpoints that return lists of resources support pagination, enabling you to manage large result sets efficiently. You can control which results are returned by specifying the `page` and `per_page` query parameters.
Paginated responses include a `meta` object that provides detailed pagination information, such as:
* `current_page`: The current page number.
* `next_page`: The next page number, if available.
* `prev_page`: The previous page number, if available.
* `total_pages`: The total number of pages.
* `total_count`: The total number of records available.
```json theme={"dark"}
{
"coupons": [
// ...
],
"meta": {
"current_page": 1,
"next_page": 2,
"prev_page": 1,
"total_pages": 10,
"total_count": 100
}
```
### Parameters
The page number to return.
The number of results per page. In most cases, the default value is `100`.
### List response
The current page number.
The next page number.
The previous page number.
The total number of pages.
The total number of records.
# Delete a payment method from a customer
Source: https://getlago.com/docs/api-reference/payment-methods/delete
DELETE /customers/{external_customer_id}/payment_methods/{lago_id}
This endpoint deletes a specific payment method for a customer.
# List all payment methods for a customer
Source: https://getlago.com/docs/api-reference/payment-methods/get-all
GET /customers/{external_customer_id}/payment_methods
This endpoint retrieves all payment methods of a Customer.
# The payment method object
Source: https://getlago.com/docs/api-reference/payment-methods/payment-method-object
This object represents a payment method stored on a customer
# Update a payment method
Source: https://getlago.com/docs/api-reference/payment-methods/update
PUT /customers/{external_customer_id}/payment_methods/{lago_id}/set_as_default
Use the payment method as default when not selected a payment method
# List all payment receipts
Source: https://getlago.com/docs/api-reference/payment-receipts/get-all
GET /payment_receipts
This endpoint is used to list all existing payment receipts.
# Retrieve a payment receipt
Source: https://getlago.com/docs/api-reference/payment-receipts/get-specific
GET /payment_receipts/{lago_id}
This endpoint retrieves a specific payment receipt.
# The payment receipt object
Source: https://getlago.com/docs/api-reference/payment-receipts/payment-receipt-object
This object represents a receipt generated by Lago for the payment of one or multiple invoices.
# Create a payment request
Source: https://getlago.com/docs/api-reference/payment-requests/create
POST /payment_requests
This endpoint is used to create a payment request to collect payments of overdue invoices of a given customer
# List all payment requests
Source: https://getlago.com/docs/api-reference/payment-requests/get-all
GET /payment_requests
This endpoint is used to list all existing payment requests.
# The payment request object
Source: https://getlago.com/docs/api-reference/payment-requests/payment-request-object
This object represents payment request of a group of overdue invoices for which a payment intent can be created, to settle the overdue balance.
# Create a payment
Source: https://getlago.com/docs/api-reference/payments/create
POST /payments
This endpoint is used to create a manual payment
# List all payments
Source: https://getlago.com/docs/api-reference/payments/get-all
GET /payments
This endpoint is used to list all payments
# Retrieve a payment
Source: https://getlago.com/docs/api-reference/payments/get-specific
GET /payments/{lago_id}
This endpoint retrieves a specific payment by its ID.
# The payment object
Source: https://getlago.com/docs/api-reference/payments/payment-object
This object represents a payment generated by Lago for one or multiple invoices.
# Create a charge
Source: https://getlago.com/docs/api-reference/plans/charges/create
POST /plans/{code}/charges
This endpoint creates a new charge for a specific plan.
# Delete a charge
Source: https://getlago.com/docs/api-reference/plans/charges/destroy
DELETE /plans/{code}/charges/{charge_code}
This endpoint deletes a specific charge from a plan.
# Create a charge filter
Source: https://getlago.com/docs/api-reference/plans/charges/filters/create
POST /plans/{code}/charges/{charge_code}/filters
This endpoint creates a new filter for a specific charge.
# Delete a charge filter
Source: https://getlago.com/docs/api-reference/plans/charges/filters/destroy
DELETE /plans/{code}/charges/{charge_code}/filters/{filter_id}
This endpoint deletes a specific filter from a charge.
# List all charge filters
Source: https://getlago.com/docs/api-reference/plans/charges/filters/get-all
GET /plans/{code}/charges/{charge_code}/filters
This endpoint retrieves all filters for a specific charge.
# Retrieve a charge filter
Source: https://getlago.com/docs/api-reference/plans/charges/filters/get-specific
GET /plans/{code}/charges/{charge_code}/filters/{filter_id}
This endpoint retrieves a specific filter for a charge.
# The charge filter object
Source: https://getlago.com/docs/api-reference/plans/charges/filters/object
This object represents a charge filter. Filters allow differentiated pricing to be applied based on additional event properties.
# Update a charge filter
Source: https://getlago.com/docs/api-reference/plans/charges/filters/update
PUT /plans/{code}/charges/{charge_code}/filters/{filter_id}
This endpoint updates a specific filter for a charge.
# List all charges
Source: https://getlago.com/docs/api-reference/plans/charges/get-all
GET /plans/{code}/charges
This endpoint retrieves all charges for a specific plan.
# Retrieve a charge
Source: https://getlago.com/docs/api-reference/plans/charges/get-specific
GET /plans/{code}/charges/{charge_code}
This endpoint retrieves a specific charge for a plan.
# The charge object
Source: https://getlago.com/docs/api-reference/plans/charges/object
This object represents a charge associated with a plan. Charges define the pricing for usage-based billable metrics.
# Update a charge
Source: https://getlago.com/docs/api-reference/plans/charges/update
PUT /plans/{code}/charges/{charge_code}
This endpoint updates a specific charge for a plan.
# Create a plan
Source: https://getlago.com/docs/api-reference/plans/create
POST /plans
This endpoint creates a plan with subscription and usage-based charges. It supports flexible billing cadence (in-advance or in-arrears) and allows for both recurring and metered charges.
# Delete a plan
Source: https://getlago.com/docs/api-reference/plans/destroy
DELETE /plans/{code}
This endpoint deletes a specific plan. Note that this plan could be associated with active subscriptions.
# Create a fixed charge
Source: https://getlago.com/docs/api-reference/plans/fixed-charges/create
POST /plans/{code}/fixed_charges
This endpoint creates a new fixed charge for a specific plan.
# Delete a fixed charge
Source: https://getlago.com/docs/api-reference/plans/fixed-charges/destroy
DELETE /plans/{code}/fixed_charges/{fixed_charge_code}
This endpoint deletes a specific fixed charge from a plan.
# List all fixed charges
Source: https://getlago.com/docs/api-reference/plans/fixed-charges/get-all
GET /plans/{code}/fixed_charges
This endpoint retrieves all fixed charges for a specific plan.
# Retrieve a fixed charge
Source: https://getlago.com/docs/api-reference/plans/fixed-charges/get-specific
GET /plans/{code}/fixed_charges/{fixed_charge_code}
This endpoint retrieves a specific fixed charge for a plan.
# The fixed charge object
Source: https://getlago.com/docs/api-reference/plans/fixed-charges/object
This object represents a fixed charge associated with a plan. Fixed charges are based on add-ons and support standard, graduated, and volume charge models.
# Update a fixed charge
Source: https://getlago.com/docs/api-reference/plans/fixed-charges/update
PUT /plans/{code}/fixed_charges/{fixed_charge_code}
This endpoint updates a specific fixed charge for a plan.
# List all plans
Source: https://getlago.com/docs/api-reference/plans/get-all-plans
GET /plans
This endpoint retrieves all existing plans.
# Retrieve a plan
Source: https://getlago.com/docs/api-reference/plans/get-specific
GET /plans/{code}
This endpoint retrieves a specific plan.
# The plan object
Source: https://getlago.com/docs/api-reference/plans/object
This object represents a plan. This plan can then be assigned to a customer.
# Update a plan
Source: https://getlago.com/docs/api-reference/plans/update
PUT /plans/{code}
This endpoint updates a specific plan with subscription and usage-based charges. It supports flexible billing cadence (in-advance or in-arrears) and allows for both recurring and metered charges.
# Currencies
Source: https://getlago.com/docs/api-reference/resources/currencies
List of accepted currencies (ISO 4217).
| Code | Currency name |
| ----- | ----------------------------------------- |
| `AED` | `United Arab Emirates Dirham` |
| `AFN` | `Afghan Afghani` |
| `ALL` | `Albanian Lek` |
| `AMD` | `Armenian Dram` |
| `ANG` | `Netherlands Antillean Gulden` |
| `AOA` | `Angolan Kwanza` |
| `ARS` | `Argentine Peso` |
| `AUD` | `Australian Dollar` |
| `AWG` | `Aruban Florin` |
| `AZN` | `Azerbaijani Manat` |
| `BAM` | `Bosnia and Herzegovina Convertible Mark` |
| `BBD` | `Barbadian Dollar` |
| `BDT` | `Bangladeshi Taka` |
| `BGN` | `Bulgarian Lev` |
| `BIF` | `Burundian Franc` |
| `BMD` | `Bermudian Dollar` |
| `BND` | `Brunei Dollar` |
| `BOB` | `Bolivian Boliviano` |
| `BRL` | `Brazilian Real` |
| `BSD` | `Bahamian Dollar` |
| `BWP` | `Botswana Pula` |
| `BYN` | `Belarusian Ruble` |
| `BZD` | `Belize Dollar` |
| `CAD` | `Canadian Dollar` |
| `CDF` | `Congolese Franc` |
| `CHF` | `Swiss Franc` |
| `CLF` | `Unidad de Fomento` |
| `CLP` | `Chilean Peso` |
| `CNY` | `Chinese Renminbi Yuan` |
| `COP` | `Colombian Peso` |
| `CRC` | `Costa Rican Colón` |
| `CVE` | `Cape Verdean Escudo` |
| `CZK` | `Czech Koruna` |
| `DJF` | `Djiboutian Franc` |
| `DKK` | `Danish Krone` |
| `DOP` | `Dominican Peso` |
| `DZD` | `Algerian Dinar` |
| `EGP` | `Egyptian Pound` |
| `ETB` | `Ethiopian Birr` |
| `EUR` | `Euro` |
| `FJD` | `Fijian Dollar` |
| `FKP` | `Falkland Pound` |
| `GBP` | `British Pound` |
| `GEL` | `Georgian Lari` |
| `GHS` | `Ghanaian Cedi` |
| `GIP` | `Gibraltar Pound` |
| `GMD` | `Gambian Dalasi` |
| `GNF` | `Guinean Franc` |
| `GTQ` | `Guatemalan Quetzal` |
| `GYD` | `Guyanese Dollar` |
| `HKD` | `Hong Kong Dollar` |
| `HNL` | `Honduran Lempira` |
| `HRK` | `Croatian Kuna` |
| `HTG` | `Haitian Gourde` |
| `HUF` | `Hungarian Forint` |
| `IDR` | `Indonesian Rupiah` |
| `ILS` | `Israeli New Sheqel` |
| `INR` | `Indian Rupee` |
| `ISK` | `Icelandic Króna` |
| `JMD` | `Jamaican Dollar` |
| `JPY` | `Japanese Yen` |
| `KES` | `Kenyan Shilling` |
| `KGS` | `Kyrgyzstani Som` |
| `KHR` | `Cambodian Riel` |
| `KMF` | `Comorian Franc` |
| `KRW` | `South Korean Won` |
| `KYD` | `Cayman Islands Dollar` |
| `KZT` | `Kazakhstani Tenge` |
| `LAK` | `Lao Kip` |
| `LBP` | `Lebanese Pound` |
| `LKR` | `Sri Lankan Rupee` |
| `LRD` | `Liberian Dollar` |
| `LSL` | `Lesotho Loti` |
| `MAD` | `Moroccan Dirham` |
| `MDL` | `Moldovan Leu` |
| `MGA` | `Malagasy Ariary` |
| `MKD` | `Macedonian Denar` |
| `MMK` | `Myanmar Kyat` |
| `MNT` | `Mongolian Tögrög` |
| `MOP` | `Macanese Pataca` |
| `MRO` | `Mauritanian Ouguiya` |
| `MUR` | `Mauritian Rupee` |
| `MVR` | `Maldivian Rufiyaa` |
| `MWK` | `Malawian Kwacha` |
| `MXN` | `Mexican Peso` |
| `MYR` | `Malaysian Ringgit` |
| `MZN` | `Mozambican Metical` |
| `NAD` | `Namibian Dollar` |
| `NGN` | `Nigerian Naira` |
| `NIO` | `Nicaraguan Córdoba` |
| `NOK` | `Norwegian Krone` |
| `NPR` | `Nepalese Rupee` |
| `NZD` | `New Zealand Dollar` |
| `PAB` | `Panamanian Balboa` |
| `PEN` | `Peruvian Sol` |
| `PGK` | `Papua New Guinean Kina` |
| `PHP` | `Philippine Peso` |
| `PKR` | `Pakistani Rupee` |
| `PLN` | `Polish Złoty` |
| `PYG` | `Paraguayan Guaraní` |
| `QAR` | `Qatari Riyal` |
| `RON` | `Romanian Leu` |
| `RSD` | `Serbian Dinar` |
| `RUB` | `Russian Ruble` |
| `RWF` | `Rwandan Franc` |
| `SAR` | `Saudi Riyal` |
| `SBD` | `Solomon Islands Dollar` |
| `SCR` | `Seychellois Rupee` |
| `SEK` | `Swedish Krona` |
| `SGD` | `Singapore Dollar` |
| `SHP` | `Saint Helenian Pound` |
| `SLL` | `Sierra Leonean Leone` |
| `SOS` | `Somali Shilling` |
| `SRD` | `Surinamese Dollar` |
| `STD` | `São Tomé and Príncipe Dobra` |
| `SZL` | `Swazi Lilangeni` |
| `THB` | `Thai Baht` |
| `TJS` | `Tajikistani Somoni` |
| `TOP` | `Tongan Paʻanga` |
| `TRY` | `Turkish Lira` |
| `TTD` | `Trinidad and Tobago Dollar` |
| `TWD` | `New Taiwan Dollar` |
| `TZS` | `Tanzanian Shilling` |
| `UAH` | `Ukrainian Hryvnia` |
| `UGX` | `Ugandan Shilling` |
| `USD` | `United States Dollar` |
| `UYU` | `Uruguayan Peso` |
| `UZS` | `Uzbekistan Som` |
| `VND` | `Vietnamese Đồng` |
| `VUV` | `Vanuatu Vatu` |
| `WST` | `Samoan Tala` |
| `XAF` | `Central African Cfa Franc` |
| `XCD` | `East Caribbean Dollar` |
| `XOF` | `West African Cfa Franc` |
| `XPF` | `Cfp Franc` |
| `YER` | `Yemeni Rial` |
| `ZAR` | `South African Rand` |
| `ZMW` | `Zambian Kwacha` |
# Document locales
Source: https://getlago.com/docs/api-reference/resources/locales
## Document locales supported
List of accepted locales for documents (ISO 639-1).
| Document language | Code |
| ------------------- | ------- |
| German | `de` |
| English | `en` |
| French | `fr` |
| Italian | `it` |
| Norwegian (Bokmål) | `nb` |
| Portuguese (Brazil) | `pt-BR` |
| Spanish | `es` |
| Swedish | `sv` |
## How to add a new language
You can contribute to Lago's open-source project by helping us translate documents. The new language will then be added to the list of supported locales and available to the entire Lago Community.
The document template includes translation keys for:
* Invoices related to subscriptions, add-ons and prepaid credits;
* Credit notes;
* Data formatting (e.g. amounts and dates); and
* Syntax (i.e. sentence structure).
The names of your billable metrics, plans, add-ons, coupons and wallets are defined in the app. There are no keys to translate them.
To add a new language:
1. [Download the document template](http://d376nw0erossg9.cloudfront.net/doc-locales-template-copies.pdf) to see where each key is located;
2. Use the text file below to provide translations for the new language; and
3. Send the new text file to [hello@getlago.com](mailto:hello@getlago.com), so that we can review it and add it to the codebase.
Thanks for your time and support!
```json theme={"dark"}
en:
money:
//[AA] format: $4,500.00
format: '%u%n'
decimal_mark: '.'
thousands_separator: ','
date:
formats:
//[AB] format: Dec. 01, 2022
default: '%b. %d, %Y'
abbr_day_names:
- Sun
- Mon
- Tue
- Wed
- Thu
- Fri
- Sat
abbr_month_names:
- Jan
- Feb
- Mar
- Apr
- May
- Jun
- Jul
- Aug
- Sep
- Oct
- Nov
- Dec
day_names:
- Sunday
- Monday
- Tuesday
- Wednesday
- Thursday
- Friday
- Saturday
month_names:
- January
- February
- March
- April
- May
- June
- July
- August
- September
- October
- November
- December
order:
- :year
- :month
- :day
=====================================================================
en:
invoice:
[1.1] document_name: "Invoice"
[1.2] invoice_number: "Invoice number"
[1.3] issue_date: "Issue date"
[1.4] payment_term: "Payment term"
[1.5] payment_term_days: "%{net_payment_term} days"
[1.6] bill_from: "From"
[1.7] bill_to: "Bill to"
[1.8] tax_identification_number: "Tax ID: %{tax_identification_number}"
[1.9] due_date: "Due %{date}"
[1.10] item: "Item"
[1.11] unit: "Unit"
[1.12] unit_price: "Unit price"
[1.13] tax_rate: "Tax rate"
[1.14] amount: "Amount (excl. tax)"
[1.15] sub_total_without_tax: "Sub total (excl. tax)"
[1.16] tax_name: "%{name} (%{rate}% on %{amount})"
[1.17] sub_total_with_tax: "Sub total (incl. tax)"
[1.18] credit_notes: "Credit notes"
[1.19] prepaid_credits: "Prepaid credits"
[1.20] total_due: "Total due"
[1.21] powered_by: "Powered by"
[AA] total_amount: "Total amount"
[AC] details: "%{resource} details"
[2.1] date_from: "Fees from"
[2.2] date_to: "to"
[AD] subscription_interval: "%{plan_interval} subscription fee - %{plan_name}"
[2.3] weekly: "Weekly"
[2.4] monthly: "Monthly"
[2.5] quarterly: "Quarterly"
[2.6] yearly: "Yearly"
graduated & graduated percentage:
[2.7] fee_per_unit_for_the_first: "Fee per unit for the first %{to}"
[2.8] fee_per_unit_for_the_next: "Fee per unit for the next %{from} to %{to}"
[2.9] fee_per_unit_for_the_last: "Fee per unit for %{from} and above"
[2.10] flat_fee_for_the_first: "Flat fee for first %{to}"
[2.11] flat_fee_for_the_next: "Flat fee for next %{from} to %{to}"
[2.12] flat_fee_for_the_last: "Flat fee for %{from} and above"
[2.13] sub_total: "Subtotal"
[2.14] fee_prorated: "The fee is prorated on days of usage, the displayed unit price is an average"
package:
[2.15] free_units_for_the_first: "Fee per unit for the first %{count}"
[2.16] fee_per_package: "Fee per package"
[2.17] fee_per_package_unit_price: "%{amount} per %{package_size}"
percentage:
[2.18] total_event: "Total events: %{total_events} transactions"
[2.19] free_units_per_transaction:
one: "Free units for 1 transaction"
other: "Free units for %{count} transactions"
[2.20] percentage_rate_on_amount: "Fee on the amount"
[2.21] fee_per_transaction: "Fee per transaction"
[2.22] adjustment_per_transaction: "Adjustment for min/ max per transaction"
[2.23] true_up_metric: "%{metric} • True up"
[2.24] true_up_details: "Minimum spend of %{min_amount} prorated on days of usage"
volume:
[2.25] fee_per_unit: "Fee per unit"
[2.26] flat_fee_for_all_units: "Flat fee for all units"
[2.27] units_prorated_per_period: "Units prorated per second per %{period}"
[2.28] week: "week"
[2.29] month: "month"
[2.30] quarter: "quarter"
[2.31] year: "year"
[2.32] total: "Total"
[3.1] breakdown: "Breakdown"
[3.2] breakdown_of: "Breakdown of %{fee_filter_display_name}"
[3.3] breakdown_for_days: "Used %{breakdown_duration} out of %{breakdown_total_duration} days"
[3.4] notice_prorated: "Regardless of when an event is received, the unit is not prorated, we charge the full price."
[3.5] notice_full: "If a unit is added or removed during the monthly plan, we calculate the prorated price based on the ratio of days remaining or used to the total number of days in the plan. For instance, if 15 days are left in the plan, we multiply the price by 15/31, and if a unit was used for 10 days, we multiply the price by 10/31."
[4.1] prepaid_credits_with_value: "Prepaid credits - %{wallet_name}"
//For invoices with old versions
total_credits_with_value: "Total credits amount: %{credit_amount} credits"
all_subscriptions: "All subscriptions"
all_usage_based_fees: "All consumption fees"
tax: "Taxes"
fees_from_to_date: "Consumption fees from %{from_date} to %{to_date}"
tax_name_with_details: "%{name} (%{rate}%)"
subscription: "Subscription"
sub_total: "Subtotal"
usage_based_fees: "Consumption fees"
list_of_charges: "List of consumption fees from %{from} to %{to}"
see_breakdown: "See breakdown below"
total_unit_interval: "Total number of units: %{events_count} event(s) for %{units}"
total_unit: "Total number of units: %{units}"
amount_with_tax: "Amount (incl. tax)"
amount_without_tax: "Amount (excl. tax)"
=====================================================================
en:
credit_note:
[5.1] document_name: "Credit note"
[5.2] credit_note_number: "Credit note number"
[5.3] invoice_number: "Invoice number"
[5.4] issue_date: "Issue date"
[5.5] credit_from: "From"
[5.6] credit_to: "Bill to"
[5.7] tax_identification_number: "Tax ID: %{tax_identification_number}"
[5.8] refunded_notice: "Refunded on %{issuing_date}"
[5.9] credited_notice: "Credited on customer balance on %{issuing_date}"
[5.10] credited_refunded_notice: "Credited on customer balance and refunded on %{issuing_date}"
[5.11] item: "Item"
[5.12] tax_rate: "Tax rate"
[5.13] amount: "Amount (excl. tax)"
[5.14] subscription: "Subscription - %{plan_name}"
[5.15] true_up_metric: "%{metric} • True up"
[5.16] coupon_adjustment: "Coupons"
[5.17] sub_total_without_tax: "Sub total (excl. tax)"
[5.18] tax: "Sales tax (%{rate}% on %{amount})"
[5.19] credited_on_customer_balance: "Credited on customer balance"
[5.20] refunded: "Refunded"
[5.21] total: "Total"
[5.22] powered_by: "Powered by"
=====================================================================
en:
email:
invoice:
finalized:
[6.1] subject: "Your invoice from %{organization_name} #%{invoice_number}"
[6.2] invoice_from: "Invoice from %{organization_name}"
[6.3] due_date: "Due %{date}"
[6.4] invoice_number: "Invoice number"
[6.5] issue_date: "Issue date"
[6.6] download: "Download invoice for details"
credit_note:
created:
[6.7] subject: "Your credit note from from %{organization_name} #%{credit_note_number}"
[6.8] credit_note_from: "Credit note from from %{organization_name}"
[6.9] refunded_notice: "Refunded on %{date}"
[6.10] credited_notice: "Credited on customer balance on %{date}"
[6.11] credited_refunded_notice: "Credited on customer balance and refunded on %{date}"
[6.12] credit_note_number: "Credit note number"
[6.13] invoice_number: "Invoice number"
[6.14] issue_date: "Issue date"
[6.15] download: "Download credit note for details"
[6.98] questions: "Questions? Contact us at"
[6.99] powered_by_lago: "Powered by"
=====================================================================
en:
customer_portal:
[7.1] page_title: "Manage your plans & billing"
[7.2] wallet: "Wallet"
[7.3] wallet_name_balance: "%{wallet_name} - Balance"
[7.4] wallet_credits_count: "%{credits_count} credit"
[7.5] wallet_credits_used: "Total credits used"
[7.6] top_up_wallet: "Top up wallet"
[7.7] wallet_expiry_date: "Expiry date"
[7.8] plans: "Plans"
[7.9] plan_name: "%{plan_name}"
[7.10] plan_price: "%{amount} (excl. tax) per %{interval}"
[7.11] plan_renews_on: "Your plan renews on %{date}"
[7.12] view_usage: "View usage"
[7.13] customer_information: "Customer information"
[7.14] edit_information: "Edit information"
[7.15] name: "Name"
[7.16] billing_email: "Billing email"
[7.17] legal_name: "Legal name"
[7.18] billing_address: "Billing address"
[7.19] legal_number: "Legal number"
[7.20] shipping_address: "Shipping address"
[7.21] address_not_provided: "Address not provided"
[7.22] invoice_history: "Invoice history"
[7.23] total_invoiced: "Total invoiced"
[7.24] total_overdue: "Total overdue"
[7.25] invoices_search: "Search"
[7.26] issuing_date: "Issuing date"
[7.27] invoice_type: "Type"
[7.28] invoice_number: "Invoice number"
[7.29] amount: "Amount"
[7.30] payment: "Payment"
[7.31] credits: "Credits"
[7.32] one_off_invoice: "One off invoice"
[7.33] advance_charges: "Advance charges"
[7.34] overdue: "Overdue"
[7.35] progressive_billing: "Progressive billing"
[7.36] subscription: "Subscription"
[7.37] unpaid: "Unpaid"
[7.38] load_more: "Load more"
edit_customer:
[8.1] page_title: "Edit Customer Information"
[8.2] general_information: "General information"
[8.3] customer_type: "Customer type"
[8.4] customer_type_placeholder: "Search or select a customer type"
[8.5] customer_name: "Customer name"
[8.6] customer_name_placeholder: "Type a customer name"
[8.7] first_name: "First name"
[8.8] last_name: "Last name"
[8.9] first_name_placeholder: "Type a first name"
[8.10] last_name_placeholder: "Type a last name"
[8.11] legal_name: "Legal name"
[8.12] legal_name_placeholder: "Type a legal name"
[8.13] tax_identification_number: "Tax identification number"
[8.14] tax_identification_number_placeholder: "Type a tax identification number"
[8.15] email: "Email"
[8.16] email_placeholder: "Type an email"
[8.17] billing_address: "Billing address"
[8.18] address: "Address"
[8.19] address_line_1: "Address line 1"
[8.20] address_line_2: "Address line 2"
[8.21] zip_code: "Zip code"
[8.22] city: "City"
[8.23] state: "State"
[8.24] country: "Country"
[8.25] shipping_address: "Shipping address (optional)"
[8.26] use_billing_address: "Use the same information from the billing address"
[8.27] shipping_address_label: "Address"
[8.28] shipping_address_line_1: "Address line 1"
[8.29] shipping_address_line_2: "Address line 2"
[8.30] shipping_zip_code: "Zip code"
[8.31] shipping_city: "City"
[8.32] shipping_state: "State"
[8.33] shipping_country: "Country"
[8.34] save_information: "Save information"
usage:
[9.1] page_title: "Usage"
[9.2] plan: "Plan"
[9.3] plan_price: "%{amount} (excl. tax) per %{interval}"
[9.4] plan_renews_on: "Your plan renews on %{date}"
[9.5] lifetime_usage: "Lifetime usage"
[9.6] lifetime_usage_period: "From %{from_date} to %{to_date}"
[9.7] total_lifetime_usage: "Total lifetime usage"
[9.8] last_threshold: "Last threshold: %{amount}"
[9.9] next_threshold: "Next threshold not set"
current_usage:
[10.1] page_title: "Usage"
[10.2] usage_period: "From %{from_date} to %{to_date}"
[10.3] current_usage_tab: "Current usage"
[10.4] projected_usage_tab: "Projected usage"
[10.5] total_current_usage: "Total current usage (excl. tax)"
[10.6] charge_name: "Charge name"
[10.7] current_units: "Current units"
[10.8] current_amount: "Current amount"
projected_usage:
[11.1] total_projected_usage: "Total projected usage (excl. tax)"
[11.2] projected_units: "Projected units"
[11.3] projected_amount: "Projected amount"
top_up_wallet:
[12.1] page_title: "Top-Up Wallet"
[12.2] credits_to_purchase: "Credits to purchase"
[12.3] credits_unit: "credits"
[12.4] purchase_amount: "You will purchase %{amount}"
[12.5] top_up_credits: "Top up credits"
misc:
[13.1] total_overdue_tooltip: "Total from past due invoices. This is the amount you owe."
[13.2] company: "Company"
[13.3] individual: "Individual"
[13.4] download_pdf: "Download PDF"
```
# Timezones
Source: https://getlago.com/docs/api-reference/resources/timezones
List of accepted timezones (TZ database).
* `UTC`
* `Africa/Algiers`
* `Africa/Cairo`
* `Africa/Casablanca`
* `Africa/Harare`
* `Africa/Johannesburg`
* `Africa/Monrovia`
* `Africa/Nairobi`
* `America/Argentina/Buenos_Aires`
* `America/Bogota`
* `America/Caracas`
* `America/Chicago`
* `America/Chihuahua`
* `America/Denver`
* `America/Guatemala`
* `America/Guyana`
* `America/Halifax`
* `America/Indiana/Indianapolis`
* `America/Juneau`
* `America/La_Paz`
* `America/Lima`
* `America/Los_Angeles`
* `America/Mazatlan`
* `America/Mexico_City`
* `America/Monterrey`
* `America/Montevideo`
* `America/New_York`
* `America/Nuuk`
* `America/Phoenix`
* `America/Puerto_Rico`
* `America/Regina`
* `America/Santiago`
* `America/Sao_Paulo`
* `America/St_Johns`
* `America/Tijuana`
* `Asia/Almaty`
* `Asia/Baghdad`
* `Asia/Baku`
* `Asia/Bangkok`
* `Asia/Chongqing`
* `Asia/Colombo`
* `Asia/Dhaka`
* `Asia/Hong_Kong`
* `Asia/Irkutsk`
* `Asia/Jakarta`
* `Asia/Jerusalem`
* `Asia/Kabul`
* `Asia/Kamchatka`
* `Asia/Karachi`
* `Asia/Kathmandu`
* `Asia/Kolkata`
* `Asia/Krasnoyarsk`
* `Asia/Kuala_Lumpur`
* `Asia/Kuwait`
* `Asia/Magadan`
* `Asia/Muscat`
* `Asia/Novosibirsk`
* `Asia/Riyadh`
* `Asia/Seoul`
* `Asia/Shanghai`
* `Asia/Singapore`
* `Asia/Srednekolymsk`
* `Asia/Taipei`
* `Asia/Tashkent`
* `Asia/Tbilisi`
* `Asia/Tehran`
* `Asia/Tokyo`
* `Asia/Ulaanbaatar`
* `Asia/Urumqi`
* `Asia/Vladivostok`
* `Asia/Yakutsk`
* `Asia/Yangon`
* `Asia/Yekaterinburg`
* `Asia/Yerevan`
* `Atlantic/Azores`
* `Atlantic/Cape_Verde`
* `Atlantic/South_Georgia`
* `Australia/Adelaide`
* `Australia/Brisbane`
* `Australia/Darwin`
* `Australia/Hobart`
* `Australia/Melbourne`
* `Australia/Perth`
* `Australia/Sydney`
* `Europe/Amsterdam`
* `Europe/Athens`
* `Europe/Belgrade`
* `Europe/Berlin`
* `Europe/Bratislava`
* `Europe/Brussels`
* `Europe/Bucharest`
* `Europe/Budapest`
* `Europe/Copenhagen`
* `Europe/Dublin`
* `Europe/Helsinki`
* `Europe/Istanbul`
* `Europe/Kaliningrad`
* `Europe/Kyiv`
* `Europe/Lisbon`
* `Europe/Ljubljana`
* `Europe/London`
* `Europe/Madrid`
* `Europe/Minsk`
* `Europe/Moscow`
* `Europe/Paris`
* `Europe/Prague`
* `Europe/Riga`
* `Europe/Rome`
* `Europe/Samara`
* `Europe/Sarajevo`
* `Europe/Skopje`
* `Europe/Sofia`
* `Europe/Stockholm`
* `Europe/Tallinn`
* `Europe/Vienna`
* `Europe/Vilnius`
* `Europe/Volgograd`
* `Europe/Warsaw`
* `Europe/Zagreb`
* `Europe/Zurich`
* `GMT+12`
* `Pacific/Apia`
* `Pacific/Auckland`
* `Pacific/Chatham`
* `Pacific/Fakaofo`
* `Pacific/Fiji`
* `Pacific/Guadalcanal`
* `Pacific/Guam`
* `Pacific/Honolulu`
* `Pacific/Majuro`
* `Pacific/Midway`
* `Pacific/Noumea`
* `Pacific/Pago_Pago`
* `Pacific/Port_Moresby`
* `Pacific/Tongatapu`
# Create a subscription
Source: https://getlago.com/docs/api-reference/subscriptions/assign-plan
POST /subscriptions
This endpoint assigns a plan to a customer, creating or modifying a subscription. Ideal for initial subscriptions or plan changes (upgrades/downgrades).
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"plan_code": "premium",
"name": "Repository A",
"external_id": "my_sub_1234567890",
"billing_time": "anniversary",
"ending_at": "2022-10-08T00:00:00Z",
"subscription_at": "2022-08-08T00:00:00Z",
"plan_overrides": {
"amount_cents": 10000,
"amount_currency": "USD",
"description": "Plan for early stage startups.",
"invoice_display_name": "Startup plan",
"name": "Startup",
"tax_codes": [
"french_standard_vat"
],
"trial_period": 5,
"charges": [
{
"id": "cha_12345",
"billable_metric_id": "bm_12345",
"invoice_display_name": "Setup",
"min_amount_cents": 0,
"tax_codes": [
"standard_vat"
],
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10,
"flat_amount": "10",
"per_unit_amount": "0.5"
}
]
}
},
{
"id": "cha_67890",
"billable_metric_id": "bm_67890",
"invoice_display_name": "FX Transfer",
"min_amount_cents": 0,
"properties": {
"graduated_percentage_ranges": [
{
"from_value": 0,
"to_value": 10,
"rate": "1",
"flat_amount": "10"
}
]
}
},
{
"id": "cha_111213",
"billable_metric_id": "bm_111213",
"invoice_display_name": "API calls",
"min_amount_cents": 0,
"properties": {
"amount": "30",
"free_units": 100,
"package_size": 1000
}
},
{
"id": "cha_141516",
"billable_metric_id": "bm_141516",
"invoice_display_name": "Interchange",
"min_amount_cents": 0,
"properties": {
"rate": "1",
"fixed_amount": "0.5",
"free_units_per_events": 5,
"free_units_per_total_aggregation": "500",
"per_transaction_max_amount": "3.75",
"per_transaction_min_amount": "1.75"
}
},
{
"id": "cha_171819",
"billable_metric_id": "bm_171819",
"invoice_display_name": "Seats",
"min_amount_cents": 0,
"properties": {
"volume_ranges": [
{
"from_value": 0,
"to_value": 10,
"flat_amount": "10",
"per_unit_amount": "0.5"
}
]
}
},
{
"id": "cha_202122",
"billable_metric_id": "bm_202122",
"invoice_display_name": "Interchange",
"min_amount_cents": 0,
"filters": [
{
"values": {
"cloud": ["aws"],
"region": ["us-east-1"]
},
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10,
"flat_amount": "10",
"per_unit_amount": "0.5"
}
]
}
}
]
}
]
}
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Subscription
client = Client(api_key='__YOUR_API_KEY__')
subscription = Subscription(
external_customer_id="5eb02857-a71e-4ea2-bcf9-57d8885990ba",
plan_code="startup_plan",
external_id="sub_id_123456789",
name="Repository A",
subscription_at="2022-08-08T00:00:00Z",
ending_at= "2023-08-08T00:00:00Z",
billing_time="anniversary"
)
try:
client.subscriptions.create(subscription)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.subscriptions.create(
external_customer_id: "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
plan_code: "startup_plan",
external_id: "sub_id_123456789",
name: "Repository A",
subscription_at: "2022-08-08T00:00:00Z",
ending_at: "2023-08-08T00:00:00Z",
billing_time: "anniversary"
)
```
```js Javascript theme={"dark"}
import { Client, SubscriptionObject } from "lago-javascript-client";
const subscriptionObject = {
external_customer_id: "5eb02857-a71e-4ea2-bcf9-57d8885990ba",
plan_code: "statup_plan",
external_id: "sub_id_123456789",
name: "Repository A",
subscription_at: "2022-08-08T00:00:00Z",
ending_at: "2023-08-08T00:00:00Z",
billing_time: "anniversary" as SubscriptionObject["billingTime"],
};
await client.subscriptions.createSubscription({
subscription: subscriptionObject,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
subscriptionAt := time.Date(2022, 8, 8, 0, 0, 0, 0, time.UTC)
endingAt := time.Date(2023, 8, 8, 0, 0, 0, 0, time.UTC)
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "5eb02857-a71e-4ea2-bcf9-57d8885990ba",
PlanCode: "startup_plan",
SubscriptionAt: &subscriptionAt,
EndingAt: &endingAt,
BillingTime: lago.Anniversary,
}
subscription, err := lagoClient.Subscription().Create(subscriptionInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// subscription is *lago.Subscription
fmt.Println(subscription)
}
```
# Create a charge filter
Source: https://getlago.com/docs/api-reference/subscriptions/charges/filters/create
POST /subscriptions/{external_id}/charges/{charge_code}/filters
This endpoint creates a new filter for a specific charge on a subscription.
# Delete a charge filter
Source: https://getlago.com/docs/api-reference/subscriptions/charges/filters/destroy
DELETE /subscriptions/{external_id}/charges/{charge_code}/filters/{filter_id}
This endpoint deletes a specific filter from a charge on a subscription.
# List all charge filters
Source: https://getlago.com/docs/api-reference/subscriptions/charges/filters/get-all
GET /subscriptions/{external_id}/charges/{charge_code}/filters
This endpoint retrieves all filters for a specific charge on a subscription.
# Retrieve a charge filter
Source: https://getlago.com/docs/api-reference/subscriptions/charges/filters/get-specific
GET /subscriptions/{external_id}/charges/{charge_code}/filters/{filter_id}
This endpoint retrieves a specific filter for a charge on a subscription.
# The charge filter object
Source: https://getlago.com/docs/api-reference/subscriptions/charges/filters/object
This object represents a charge filter. Filters allow differentiated pricing to be applied based on additional event properties.
# Update a charge filter
Source: https://getlago.com/docs/api-reference/subscriptions/charges/filters/update
PUT /subscriptions/{external_id}/charges/{charge_code}/filters/{filter_id}
This endpoint updates a specific filter for a charge on a subscription.
# List all charges
Source: https://getlago.com/docs/api-reference/subscriptions/charges/get-all
GET /subscriptions/{external_id}/charges
This endpoint retrieves all effective charges for a specific subscription.
If the subscription has plan overrides with charge overrides, the overridden charges are returned.
# Retrieve a charge
Source: https://getlago.com/docs/api-reference/subscriptions/charges/get-specific
GET /subscriptions/{external_id}/charges/{charge_code}
This endpoint retrieves a specific effective charge for a subscription.
If the subscription has a plan override with a charge override, the overridden charge is returned.
# The charge object
Source: https://getlago.com/docs/api-reference/subscriptions/charges/object
This object represents a charge associated with a subscription. Charges define the pricing for usage-based billable metrics.
# Update a charge
Source: https://getlago.com/docs/api-reference/subscriptions/charges/update
PUT /subscriptions/{external_id}/charges/{charge_code}
This endpoint creates or updates a charge override for a specific subscription.
If the subscription does not have a plan override yet, one will be created automatically.
The charge override allows customizing specific charge properties (invoice_display_name, min_amount_cents, properties, filters, taxes, applied_pricing_unit) without affecting the original plan charge.
This is a premium feature.
# List all fixed charges
Source: https://getlago.com/docs/api-reference/subscriptions/fixed-charges/get-all
GET /subscriptions/{external_id}/fixed_charges
This endpoint retrieves all effective fixed charges for a specific subscription.
If the subscription has plan overrides with fixed charge overrides, the overridden fixed charges are returned.
# Retrieve a fixed charge
Source: https://getlago.com/docs/api-reference/subscriptions/fixed-charges/get-specific
GET /subscriptions/{external_id}/fixed_charges/{fixed_charge_code}
This endpoint retrieves a specific effective fixed charge for a subscription.
If the subscription has a plan override with a fixed charge override, the overridden fixed charge is returned.
# The fixed charge object
Source: https://getlago.com/docs/api-reference/subscriptions/fixed-charges/object
This object represents a fixed charge associated with a subscription. Fixed charges are based on add-ons and support standard, graduated, and volume charge models.
# Update a fixed charge
Source: https://getlago.com/docs/api-reference/subscriptions/fixed-charges/update
PUT /subscriptions/{external_id}/fixed_charges/{fixed_charge_code}
This endpoint creates or updates a fixed charge override for a specific subscription.
If the subscription does not have a plan override yet, one will be created automatically.
The fixed charge override allows customizing specific fixed charge properties (invoice_display_name, units, properties, taxes) without affecting the original plan fixed charge.
This is a premium feature.
# List all subscriptions
Source: https://getlago.com/docs/api-reference/subscriptions/get-all
GET /subscriptions
This endpoint retrieves all active subscriptions.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/subscriptions?external_customer_id=123&plan_code=starter&status[]=pending" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.subscriptions.find_all({'external_customer_id': '123'})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.subscriptions.get_all({ external_customer_id: '123'})
```
```js Javascript theme={"dark"}
await client.subscriptions.findAllSubscriptions({
external_customer_id: "123",
page: 1,
});
```
# Retrieve subscription lifetime usage
Source: https://getlago.com/docs/api-reference/subscriptions/get-lifetime-usage
GET /subscriptions/{external_id}/lifetime_usage
This endpoint allows you to retrieve the total lifetime usage of a subscription.
# Retrieve a subscription
Source: https://getlago.com/docs/api-reference/subscriptions/get-specific
GET /subscriptions/{external_id}
This endpoint retrieves a specific subscription.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/subscriptions/:external_id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.subscriptions.find('externalId')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.subscriptions.get('external_id')
```
```js Javascript theme={"dark"}
await client.subscriptions.findSubscription("external_id");
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
subscriptionResult, err := lagoClient.Subscription().Get("__YOUR_SUBSCRIPTION_EXTERNAL_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// subscription is *lago.Subscription
fmt.Println(subscription)
}
```
# The lifetime usage object
Source: https://getlago.com/docs/api-reference/subscriptions/lifetime-usage-object
This object represents the total lifetime usage of a subscription, particularly useful for progressive billing.
# The subscription object
Source: https://getlago.com/docs/api-reference/subscriptions/subscription-object
This object represents the assignation of plan to one of the customer of your business.
# Terminate a subscription
Source: https://getlago.com/docs/api-reference/subscriptions/terminate
DELETE /subscriptions/{external_id}
This endpoint allows you to terminate a subscription.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_ID="__YOUR_SUBSCRIPTION_ID__"
curl --location --request DELETE "$LAGO_URL/api/v1/subscriptions/$EXTERNAL_ID?status=pending" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.subscriptions.destroy('external_id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.subscriptions.destroy("5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba")
```
```js Javascript theme={"dark"}
await client.subscriptions.destroySubscription("external_id");
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
subscription, err := lagoClient.Subscription().Terminate("__EXTERNAL_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// subscription is *lago.Subscription
fmt.Println(subscription)
}
```
# Update a subscription
Source: https://getlago.com/docs/api-reference/subscriptions/update
PUT /subscriptions/{external_id}
This endpoint allows you to update a subscription.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/subscriptions/:id" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"name": "Repository B",
"ending_at": "2022-10-08T00:00:00Z",
"subscription_at": "2022-08-08T00:00:00Z",
"plan_overrides": {
"amount_cents": 10000,
"amount_currency": "USD",
"description": "Plan for early stage startups.",
"invoice_display_name": "Startup plan",
"name": "Startup",
"tax_codes": [
"french_standard_vat"
],
"trial_period": 5,
"charges": [
{
"id": "cha_12345",
"billable_metric_id": "bm_12345",
"invoice_display_name": "Setup",
"min_amount_cents": 0,
"tax_codes": [
"standard_vat"
],
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10,
"flat_amount": "10",
"per_unit_amount": "0.5"
}
]
}
},
{
"id": "cha_67890",
"billable_metric_id": "bm_67890",
"invoice_display_name": "FX Transfer",
"min_amount_cents": 0,
"properties": {
"graduated_percentage_ranges": [
{
"from_value": 0,
"to_value": 10,
"rate": "1",
"flat_amount": "10"
}
]
}
},
{
"id": "cha_111213",
"billable_metric_id": "bm_111213",
"invoice_display_name": "API calls",
"min_amount_cents": 0,
"properties": {
"amount": "30",
"free_units": 100,
"package_size": 1000
}
},
{
"id": "cha_141516",
"billable_metric_id": "bm_141516",
"invoice_display_name": "Interchange",
"min_amount_cents": 0,
"properties": {
"rate": "1",
"fixed_amount": "0.5",
"free_units_per_events": 5,
"free_units_per_total_aggregation": "500",
"per_transaction_max_amount": "3.75",
"per_transaction_min_amount": "1.75"
}
},
{
"id": "cha_171819",
"billable_metric_id": "bm_171819",
"invoice_display_name": "Seats",
"min_amount_cents": 0,
"properties": {
"volume_ranges": [
{
"from_value": 0,
"to_value": 10,
"flat_amount": "10",
"per_unit_amount": "0.5"
}
]
}
},
{
"id": "cha_202122",
"billable_metric_id": "bm_202122",
"invoice_display_name": "Interchange",
"min_amount_cents": 0,
"filters": [
{
"values": {
"cloud": ["aws"],
"region": ["us-east-1"]
},
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10,
"flat_amount": "10",
"per_unit_amount": "0.5"
}
]
}
}
]
}
]
}
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Subscription
client = Client(api_key='__YOUR_API_KEY__')
update_params = Subscription(name='new name', subscription_at='2022-08-08T00:00:00Z', ending_at= '2023-08-08T00:00:00Z')
try:
client.subscriptions.update(update_params, 'id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
update_params = { name: 'new name', subscription_at: '2022-08-08T00:00:00Z', ending_at: '2022-08-08T00:00:00Z' }
client.subscriptions.update(update_params, 'id')
```
```js Javascript theme={"dark"}
await client.subscriptions.updateSubscription("external_id", {
subscription: {
name: "new name",
subscription_at: "2022-08-08T00:00:00Z",
ending_at: "2023-08-08T00:00:00Z",
},
});
```
# Update subscription lifetime usage
Source: https://getlago.com/docs/api-reference/subscriptions/update-lifetime-usage
PUT /subscriptions/{external_id}/lifetime_usage
This endpoint allows you to update the total lifetime usage of a subscription for migration purposes.
# Create a tax rate
Source: https://getlago.com/docs/api-reference/taxes/create
POST /taxes
This endpoint creates a new tax representing a customizable tax rate applicable to either the organization or a specific customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/taxes" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"tax": {
"name": "TVA",
"code": "french_standard_vat",
"rate": "20.0",
"description": "French standard VAT",
"applied_to_organization": false
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Tax
client = Client(api_key='__YOUR_API_KEY__')
tax = Tax(
name="TVA",
code="french_standard_vat",
rate="20.0",
description="French standard VAT",
applied_to_organization=false
)
try:
client.taxes.create(tax)
except LagoApiError as e:
# do something on error or raise your own exception
repair_broken_state(e)
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
tax = {
name: "TVA",
code: "french_standard_vat",
rate: "20.0",
description: "French standard VAT",
applied_to_organization: false
}
client.taxes.create(tax)
```
```js Javascript theme={"dark"}
const taxObject = {
name: "TVA",
code: "french_standard_vat",
rate: "20.0",
description: "French standard VAT",
applied_to_organization: false,
};
await client.taxes.createTax({ tax: taxObject });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
taxInput := &lago.TaxInput{
Name: "TVA",
Code: "french_standard_vat",
Rate: "20.0",
Description: "French standard VAT",
AppliedToOrganization: false,
}
tax, err := lagoClient.Tax().Create(taxInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// tax is *lago.Tax
fmt.Println(tax)
}
```
# Delete a tax rate
Source: https://getlago.com/docs/api-reference/taxes/destroy
DELETE /taxes/{code}
This endpoint is used to delete a tax.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/taxes/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.taxes.destroy('code')
except LagoApiError as e:
repair_broken_state(e)
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.taxes.destroy('code')
```
```js Javascript theme={"dark"}
await client.taxes.destroyTax('code')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
tax, err := lagoClient.Tax().Delete("__YOUR_TAX_CODE__")
if err != nil {
panic(err)
}
fmt.Println(tax)
}
```
# List all tax rates
Source: https://getlago.com/docs/api-reference/taxes/get-all
GET /taxes
This endpoint retrieves all existing taxes representing a customizable tax rate applicable to either the organization or a specific customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/taxes?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.taxes.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e)
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.taxes.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.taxes.findAllTaxes({ per_page: 2, page: 3 });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
taxListInput := &lago.TaxListInput{
PerPage: 1,
Page: 1,
}
taxResult, err := lagoClient.Tax().GetList(taxListInput)
if err != nil {
panic(err)
}
fmt.Println(taxResult)
}
```
# Retrieve a tax rate
Source: https://getlago.com/docs/api-reference/taxes/get-specific
GET /taxes/{code}
This endpoint retrieves an existing tax representing a customizable tax rate applicable to either the organization or a specific customer. The tax is identified by its unique code.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/taxes/:code" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.taxes.find('code')
except LagoApiError as e:
repair_broken_state(e)
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.taxes.get('code')
```
```js Javascript theme={"dark"}
await client.taxes.findTax("code");
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
tax, err := lagoClient.Tax().Get("__YOUR_TAX_CODE__")
if err != nil {
panic(err)
}
fmt.Println(tax)
}
```
# The tax object
Source: https://getlago.com/docs/api-reference/taxes/tax-object
This object represents a customizable tax rate applicable to either the organization or a specific customer.
# Update a tax rate
Source: https://getlago.com/docs/api-reference/taxes/update
PUT /taxes/{code}
This endpoint updates an existing tax representing a customizable tax rate applicable to either the organization or a specific customer.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/taxes" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"tax": {
"name": "french vat",
"code": "french_vat_2",
"rate": 20.00,
"description": "Standard VAT",
"applied_to_organization": false
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Tax
client = Client(api_key='__YOUR_API_KEY__')
tax = Tax(
name="TVA",
code="french_standard_vat",
rate="20.0",
description="French standard VAT",
applied_to_organization=false
)
try:
client.taxes.update(tax, "french_standard_vat")
except LagoApiError as e:
# do something on error or raise your own exception
repair_broken_state(e)
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
tax = {
name: "TVA",
code: "french_standard_vat",
rate: "20.0",
description: "French standard VAT",
applied_to_organization: false
}
client.taxes.update(tax, "french_standard_vat")
```
```js Javascript theme={"dark"}
const taxObject = {
name: "TVA",
code: "french_standard_vat",
rate: "20.0",
description: "French standard VAT",
applied_to_organization: false,
};
await client.taxes.updateTax("french_standard_vat", { tax: taxObject });
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
taxInput := &lago.TaxInput{
Name: "TVA",
Code: "french_standard_vat",
Rate: "20.0",
Description: "French standard VAT",
AppliedToOrganization: false,
}
tax, err := lagoClient.Tax().Update(taxInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// tax is *lago.Tax
fmt.Println(tax)
}
```
# Create a wallet
Source: https://getlago.com/docs/api-reference/wallets/create
POST /wallets
This endpoint is used to create a wallet with prepaid credits.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": {
"name": "Prepaid",
"rate_amount": "1.5",
"paid_credits": "20.0",
"granted_credits": "10.0",
"currency": "USD",
"expiration_at": "2022-07-07",
"external_customer_id": "hooli_1234"
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Wallet
client = Client(api_key='__YOUR_API_KEY__')
wallet = Wallet(
name='Prepaid',
rate_amount='1.5',
paid_credits='20.0',
granted_credits='10.0',
currency='USD',
expiration_at='2022-07-07T23:59:59Z',
external_customer_id='hooli_1234'
)
try:
client.wallets.create(wallet)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.wallets.create({
name: 'Prepaid',
rate_amount: '1.5',
paid_credits: '20.0',
granted_credits: '10.0',
currency: 'USD',
expiration_at: '2022-07-07T23:59:59Z',
external_customer_id: 'hooli_1234'
})
```
```js Javascript theme={"dark"}
await client.wallets.createWallet({
wallet: {
name: "Prepaid",
currency: "USD",
rate_amount: 1.5,
paid_credits: 20.0,
granted_credits: 10.0,
expiration_at: "2022-07-07T23:59:59Z",
external_customer_id: "hooli_1234",
},
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
expirationAt := time.Date(2022, 7, 7, 23, 59, 59, 0, time.UTC)
walletInput := &lago.WalletInput{
Name: "Prepaid",
RateAmount: "1.5",
PaidCredits: "20.0"
GrantedCredits: "10.0",
Currency: "USD",
ExpirationAt: &expirationAt,
ExternalCustomerID: "hooli_1234",
}
wallet, err := lagoClient.Wallet().Create(walletInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// wallet is *lago.Wallet
fmt.Println(wallet)
}
```
# List all wallets
Source: https://getlago.com/docs/api-reference/wallets/get-all
GET /wallets
This endpoint is used to list all wallets with prepaid credits.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/wallets?external_customer_id&per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.wallets.find_all({'external_customer_id': hooli_1234, 'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.wallets.get_all({ external_customer_id: hooli_1234, per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.wallets.findAllWallets({
external_customer_id: "hooli_1234",
per_page: 2,
page: 3,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
walletListInput := &lago.WalletListInput{
PerPage: 10,
Page: 1,
ExternalCustomerID: hooli_1234
}
walletResult, err := lagoClient.Wallet().GetList(walletListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// wallet is *lago.WalletResult
fmt.Println(walletResult)
}
```
# List all wallet transactions
Source: https://getlago.com/docs/api-reference/wallets/get-all-transactions
GET /wallets/{lago_id}/wallet_transactions
This endpoint is used to list all wallet transactions.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/wallets/:id/wallet_transactions?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.wallet_transactions.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.wallet_transactions.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.wallets.findAllWalletTransactions("wallet-id", {
per_page: 2,
page: 3,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
walletTransactionListInput := &lago.WalletTransactionListInput{
PerPage: 1,
Page: 1,
WalletId: 12345,
}
walletTransactionResult, err := lagoClient.WalletTransaction().GetList(walletTransactionListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// walletTransactionResult is *lago.WalletTransactionResult
fmt.Println(walletTransactionResult)
}
```
# Retrieve a wallet
Source: https://getlago.com/docs/api-reference/wallets/get-specific
GET /wallets/{lago_id}
This endpoint is used to retrieve an existing wallet with prepaid credits.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/wallets/:id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.wallets.find('id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.wallets.get('id')
```
```js Javascript theme={"dark"}
await client.wallets.findWallet('wallet-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
wallet, err := lagoClient.Wallet().Get("__ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// wallet is *lago.Wallet
fmt.Println(wallet)
}
```
# Retrieve a transaction
Source: https://getlago.com/docs/api-reference/wallets/get-specific-transaction
GET /wallet_transactions/{lago_id}
This endpoint is used to retrieve a specific wallet transactions.
# Terminate a wallet
Source: https://getlago.com/docs/api-reference/wallets/terminate
DELETE /wallets/{lago_id}
This endpoint is used to terminate an existing wallet with prepaid credits.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/wallets/:wallet_id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.wallets.destroy('id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.wallets.destroy('id')
```
```js Javascript theme={"dark"}
await client.wallets.destroyWallet('wallet-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
wallet, err := lagoClient.Wallet().Delete("__ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// wallet is *lago.Wallet
fmt.Println(wallet)
}
```
# Top-up a wallet
Source: https://getlago.com/docs/api-reference/wallets/top-up
POST /wallet_transactions
This endpoint is used to top-up an active wallet.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallet_transactions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet_transaction": {
"wallet_id": "wallet_1234",
"paid_credits": "20.0",
"granted_credits": "10.0"
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import WalletTransaction
client = Client(api_key='__YOUR_API_KEY__')
transaction = WalletTransaction(
wallet_id='wallet_1234',
paid_credits='20.0',
granted_credits='10.0'
)
try:
client.wallet_transactions.create(transaction)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.wallet_transactions.create({
wallet_id: 'wallet_1234',
paid_credits: '20.0',
granted_credits: '10.0'
})
```
```js Javascript theme={"dark"}
await client.walletTransactions.createWalletTransaction({
wallet_transaction: {
wallet_id: "wallet_1234",
paid_credits: 20.0,
granted_credits: 10.0,
},
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
walletTransactionInput := &lago.WalletTransactionInput{
WalletId: "wallet_1234",
PaidCredits: "20.0"
GrantedCredits: "10.0",
}
transactions, err := lagoClient.WalletTransaction().Create(walletTransactionInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// wallet is *lago.Wallet
fmt.Println(transactions)
}
```
# Update a wallet
Source: https://getlago.com/docs/api-reference/wallets/update
PUT /wallets/{lago_id}
This endpoint is used to update an existing wallet with prepaid credits.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/wallets/:lago_id" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": {
"name": "Prepaid Credits",
"expiration_at": "2022-07-07T23:59:59Z"
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Wallet
client = Client(api_key='__YOUR_API_KEY__')
wallet = Wallet(
name='Prepaid Credits',
expiration_at='2022-07-07T23:59:59Z'
)
try:
client.wallets.update(wallet, '__WALLET_ID__')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.wallets.update({
name: 'Prepaid Credits',
expiration_at: '2022-07-07T23:59:59Z',
}, '__WALLET_ID__')
```
```js Javascript theme={"dark"}
await client.wallets.updateWallet("wallet-id", {
wallet: { name: "Prepaid Credits", expiration_at: "2022-07-07T23:59:59Z" },
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
expirationAt := time.Date(2022, 7, 7, 23, 59, 59, 0, time.UTC)
walletInput := &lago.WalletInput{
Name: "Prepaid Credits",
ExpirationAt: &expirationAt,
}
wallet, err := lagoClient.Wallet().Update(walletInput, "__WALLET_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// wallet is *lago.Wallet
fmt.Println(wallet)
}
```
# The wallet object
Source: https://getlago.com/docs/api-reference/wallets/wallet-object
This object represents a wallet, holding free or prepaid credits.
# The wallet transaction object
Source: https://getlago.com/docs/api-reference/wallets/wallet-transaction-object
This object represents a wallet transaction. It is used for topping up or voiding prepaid credits.
# Generate a payment URL
Source: https://getlago.com/docs/api-reference/wallets/wallet-transaction-payment-url
POST /wallet_transactions/{lago_id}/payment_url
This endpoint generates a checkout link for a specific wallet transaction.
# Create a webhook endpoint
Source: https://getlago.com/docs/api-reference/webhook-endpoints/create
POST /webhook_endpoints
This endpoint is used to create a webhook endpoint.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/webhook_endpoints" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"webhook_endpoint": {
"webhook_url": "https://foo.bar",
"signature_algo": "hmac"
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import WebhookEndpoint
client = Client(api_key='__YOUR_API_KEY__')
webhook_endpoint = WebhookEndpoint(
webhook_url='https://foo.bar',
signature_algo: 'hmac'
)
try:
client.webhook_endpoints.create(webhook_endpoint)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.webhook_endpoints.create({
webhook_url: 'https://foo.bar',
signature_algo: 'hmac'
})
```
```js Javascript theme={"dark"}
await client.webhookEndpoints.createWebhookEndpoint({
webhook_endpoint: {
webhook_url: "https://foo.bar",
signature_algo: "hmac",
},
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
webhookEndpointInput := &lago.WebhookEndpointInput{
WebhookURL: "https://foo.bar"
}
webhookEndpoint, err := lagoClient.WebhookEndpoint().Create(webhookEndpointInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// webhookEndpoint is *lago.WebhookEndpoint
fmt.Println(webhookEndpoint)
}
```
# Delete a webhook endpoint
Source: https://getlago.com/docs/api-reference/webhook-endpoints/destroy
DELETE /webhook_endpoints/{id}
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/webhook_endpoints/:id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.webhook_endpoints.destroy('id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.webhook_endpoints.destroy('id')
```
```js Javascript theme={"dark"}
await client.webhookEndpoints.deleteWebhookEndpoint('id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
webhookEndpoint, err := lagoClient.WebhookEndpoint().Delete("id")
if err != nil {
// Error is *lago.Error
panic(err)
}
// webhookEndpoint is *lago.WebhookEndpoint
fmt.Println(webhookEndpoint)
}
```
# List all webhook endpoints
Source: https://getlago.com/docs/api-reference/webhook-endpoints/get-all
GET /webhook_endpoints
This endpoint is used to list all webhook endpoints.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/webhook_endpoints?per_page=2&page=1" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.webhook_endpoints.find_all({'per_page': 2, 'page': 1})
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.webhook_endpoints.get_all({ per_page: 2, page: 3 })
```
```js Javascript theme={"dark"}
await client.webhookEndpoints.findAllWebhookEndpoints({
per_page: 2,
page: 3,
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
webhookEndpointListInput := &lago.WebhookEndpointListInput{
PerPage: 10,
Page: 1
}
webhookEndpointResult, err := lagoClient.WebhookEndpoint().GetList(WebhookEndpointListInput)
if err != nil {
// Error is *lago.Error
panic(err)
}
// webhookEndpointResult is *lago.WebhookEndpointResult
fmt.Println(webhookEndpointResult)
}
```
# Retrieve a webhook endpoint
Source: https://getlago.com/docs/api-reference/webhook-endpoints/get-specific
GET /webhook_endpoints/{lago_id}
This endpoint is used to retrieve an existing webhook endpoint.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/webhook_endpoints/:id" \
--header "Authorization: Bearer $API_KEY"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__YOUR_API_KEY__')
try:
client.webhook_endpoints.find('id')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.webhook_endpoints.get('id')
```
```js Javascript theme={"dark"}
await client.webhookEndpoints.findWebhookEndpoint('webhook-endpoint-id')
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
webhookEndpoint, err := lagoClient.WebhookEndpoint().Get("__ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// webhookEndpoint is *lago.WebhookEndpoint
fmt.Println(webhookEndpoint)
}
```
# Update a webhook endpoint
Source: https://getlago.com/docs/api-reference/webhook-endpoints/update
PUT /webhook_endpoints/{lago_id}
This endpoint is used to update an existing webhook endpoint.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/webhook_endpoints/:lago_id" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"webhook_endpoint": {
"webhook_url": "https://foo.bar",
"signature_algo": "hmac"
}
}'
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import WebhookEndpoint
client = Client(api_key='__YOUR_API_KEY__')
webhook_endpoint = WebhookEndpoint(
webhook_url='https://foo.bar',
signature_algo: 'hmac'
)
try:
client.webhook_endpoints.update(webhook_endpoint, '__WEBHOOK_ENDPOINT_ID__')
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.webhook_endpoints.update({
webhook_url: 'https://foo.bar',
signature_algo: 'hmac'
}, '__WEBHOOK_ENDPOINT_ID__')
```
```js Javascript theme={"dark"}
await client.webhook_endpoints.updateWebhookEndpoint("webhook-endpoint-id", {
webhook_endpoint: { webhook_url: "https://foo.bar" },
});
```
```go Go theme={"dark"}
import "fmt"
import "github.com/getlago/lago-go-client"
func main() {
lagoClient := lago.New().
SetApiKey("__YOUR_API_KEY__")
webhookEndpointInput := &lago.WebhookEndpointInput{
WebhookURL: "https://foo.bar"
}
webhookEndpoint, err := lagoClient.WebhookEndpoint().Update(webhookEndpointInput, "__WEBHOOK_ENDPOINT_ID__")
if err != nil {
// Error is *lago.Error
panic(err)
}
// webhookEndpoint is *lago.WebhookEndpoint
fmt.Println(webhookEndpoint)
}
```
# The webhook endpoint object
Source: https://getlago.com/docs/api-reference/webhook-endpoints/webhook-endpoint-object
This object represents the webhook endpoint used for listening to Lago’s events
# Format & Signature
Source: https://getlago.com/docs/api-reference/webhooks/format---signature
Webhooks are HTTP notifications sent from Lago to your application.
The messages are sent as a `POST` to the URL defined in the settings of your
Lago workspace.
If you return an error (other than a 2xx's HTTP response) or if there is a network issue,
the webhook will be sent again. Lago will try to send the webhook 3 times.
## Message format[](#message-format "Direct link to heading")
`POST __WEBHOOK_URL__`
```json theme={"dark"}
{
"webhook_type": "__TYPE__",
"object_type": "OBJECT_TYPE",
"__OBJECT__": {}
}
```
## Unique Key[](#unique-key "Direct link to heading")
Lago sends an idempotency key (unique identifier) in the HTTP headers named `X-Lago-Unique-Key`. This key can be used
to ensure you process a webhook only once.
## Signature[](#signature "Direct link to heading")
Allong with the payload the message contains both `X-Lago-Signature` and `X-Lago-Signature-Algorithm` HTTP header.
It is used to ensure the message is Coming from Lago and that the message has not been altered.
To verify the signature, you must decode the signature and compare the result with the body of the webhook.
You can choose between 2 differents signatures algorithm during your webhook endpoints creation, `hmac` or `jwt`.
Please note that `jwt` is our original signature and is used by default.
### JWT Signature
#### 1. Retrieve the public key[](#1-retrieve-the-public-key "Direct link to heading")
```py Python theme={"dark"}
from lago_python_client import Client
client = Client(api_key='__YOUR_API_KEY__')
webhooks_public_key = client.webhooks().public_key()
```
```js Node.js theme={"dark"}
import Client from "lago-nodejs-client";
let client = new Client("__YOUR_API_KEY__");
let webhooksPublicKey = client.webhookPublicKey();
```
```ruby Ruby theme={"dark"}
require 'net/http'
api_key = "__YOUR_API_KEY__"
uri = URI('https://api.getlago.com/api/v1/webhooks/public_key')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
response = http.send_request(
'GET',
uri.request_uri,
'',
{ 'Authorization' => "Bearer #{api_key}" }
)
webhooks_public_key = response.body
```
You should persist the public key on your side to avoid querying it for each
webhook.
#### 2. Decode and validate the signature[](#2-decode-and-validate-the-signature "Direct link to heading")
```py Python theme={"dark"}
import jwt
decoded_signature = jwt.decode(
request.headers.get('X-Lago-Signature'),
webhooks_public_key,
algorithms=['RS256'],
issuer="https://api.getlago.com"
)
decoded_signature['data'] == request.body
```
```js Node.js theme={"dark"}
import jwt from "jsonwebtoken";
let token = request.header("X-Lago-Signature");
jwt.verify(
token,
webhooksPublicKey,
{
algorithms: ["RS256"],
issuer: "https://api.getlago.com",
},
function (err, payload) {
payload === request.body;
}
);
```
```ruby Ruby theme={"dark"}
require 'openssl'
require 'jwt'
decoded_signature = JWT.decode(
request.headers['X-Lago-Signature'],
OpenSSL::PKey::RSA.new(Base64.decode64(webhooks_public_key)),
true,
{
algorithm: 'RS256',
iss: "https://api.getlago.com",
verify_iss: true,
},
).first
decoded_signature['data'] == request.body
```
### HMAC Signature
#### Decode and validate the signature
```py Python theme={"dark"}
import hmac
import base64
calc_sig = hmac.new(LAGO_HMAC_KEY, request.body.encode(), 'sha256').digest()
base64_sig = base64.b64encode(calc_sig).decode()
request.headers.get('X-Lago-Signature') == base64_sig
```
```js Node.js theme={"dark"}
import crypto from 'crypto';
const signature = request.header('X-Lago-Signature')
const hmac = crypto.createHmac('sha256', 'YOUR_ORGANIZATION_HMAC_KEY')
hmac.update(request.body)
const encodedBody = hmac.digest().toString('base64')
signature == encodedBody
```
```ruby Ruby theme={"dark"}
require 'openssl'
signature = request.headers['X-Lago-Signature']
hmac = OpenSSL::HMAC.digest('sha-256', 'YOUR_ORGANIZATION_HMAC_KEY', request.body)
base64_hmac = Base64.strict_encode64(hmac)
base64_hmac == signature
```
```php PHP theme={"dark"}
$signature = $_SERVER['X-Lago-Signature'];
$requestBody = file_get_contents('php://input');
$hmac = hash_hmac('sha256', $requestBody, 'YOUR_ORGANIZATION_HMAC_KEY', true);
$base64Signature = base64_encode($hmac);
$valid = hash_equals($signature, $base64Signature);
```
# Messages
Source: https://getlago.com/docs/api-reference/webhooks/messages
Below is a list of the event types we currently send. Please note that additional event types may be introduced in the future, so your code should be flexible enough to accommodate new types as they arise. Our objective is to maintain a consistent and predictable event structure, making it easier to integrate and handle messages, along with the objects they affect.
## Alerts
Sent when a new usage alert threshold has been crossed.
[Schema example](https://swagger.getlago.com/#/webhooks/alertTriggered)
## Credit notes and refunds
Sent when a new credit note has been issued for a customer. This will allow your application to proceed with the refund.
[Schema example](https://swagger.getlago.com/#/webhooks/creditNoteCreated)
Sent when the PDF file has been generated for a credit note. This will allow your application to retrieve the PDF credit note.
[Schema example](https://swagger.getlago.com/#/webhooks/creditNoteGenerated)
Sent when there is an error related to the refund process (i.e. the payment provider cannot refund the customer).
[Schema example](https://swagger.getlago.com/#/webhooks/creditNoteRefundFailure)
## Customers
### Basic customer information
Sent when a customer is successfully created in Lago.
[Schema example](https://swagger.getlago.com/#/webhooks/customerCreated)
Sent when a customer is successfully updated in Lago.
[Schema example](https://swagger.getlago.com/#/webhooks/customerUpdated)
Sent when an error was encountered while processing data on an integration
[Schema example](https://swagger.getlago.com/#/webhooks/integrationProviderError)
### External payment providers
Sent when a customer is successfully created in the payment provider's application. This allows you to retrieve the identifier assigned to the customer by the payment service provider.
[Schema example](https://swagger.getlago.com/#/webhooks/customerPaymentProviderCreated)
Sent when there is an error related to the creation of a customer in the payment provider's system.
[Schema example](https://swagger.getlago.com/#/webhooks/customerPaymentProviderError)
Sent when a checkout link is issued for a customer.
[Schema example](https://swagger.getlago.com/#/webhooks/customerCheckoutUrlGenerated)
Sent when a checkout link is issued for a customer.
[Schema example](https://swagger.getlago.com/#/webhooks/customerCheckoutUrlGenerated)
### External accounting providers
Sent when a customer is successfully created in the accounting provider's application (like NetSuite). This allows you to retrieve the identifier assigned to the customer by the accounting service provider.
[Schema example](https://swagger.getlago.com/#/webhooks/customerAccountingProviderCreated)
Sent when there is an error related to the accounting provider sync. Usually occurs when something went wrong in the accounting service provider's application.
[Schema example](https://swagger.getlago.com/#/webhooks/customerAccountingProviderError)
### External CRM providers
Sent when a customer has been created in the CRM provider.
[Schema example](https://swagger.getlago.com/#/webhooks/customerCrmProviderCreated)
Sent when an error was encountered while syncing a customer to a CRM provider.
[Schema example](https://swagger.getlago.com/#/webhooks/customerCrmProviderError)
### External tax providers
Sent when there is an error related to the tax provider sync. This usually occurs due to issues with item mappings, customer definitions, or within the service provider's application.
[Schema example](https://swagger.getlago.com/#/webhooks/customerTaxProviderError)
Sent when a VIES VAT number has been checked for a customer
[Schema example](https://swagger.getlago.com/#/webhooks/customerViesCheck)
## Event ingestion
This webhook is deprecated and will be removed in future versions of Lago.
Sent by the health check process when some events received in the previous hour do not match the validation rules.
[Schema example](https://swagger.getlago.com/#/webhooks/eventsErrors)
This webhook is deprecated and no longer sent in Lago `v0.50.0-beta` and above. It was sent when there was an error related to the creation of an event.
[Schema example](https://swagger.getlago.com/#/webhooks/eventError)
## Features
Sent when a new feature is created.
[Schema example](https://swagger.getlago.com/#/webhooks/featureCreated)
Sent when a new feature is updated.
[Schema example](https://swagger.getlago.com/#/webhooks/featureUpdated)
Sent when a new feature is deleted.
[Schema example](https://swagger.getlago.com/#/webhooks/featureDeleted)
## Invoices
Sent when a new invoice is in draft.
[Schema example](https://swagger.getlago.com/#/webhooks/invoiceDrafted)
Sent when an invoice is finalized. This event serves as a signal to your application that the invoice processing is complete and you can proceed with the necessary billing actions or procedures.
[Schema example](https://swagger.getlago.com/#/webhooks/invoiceCreated)
Sent when a one-off invoice is created. Only add-ons can be applied to one-off invoices.
[Schema example](https://swagger.getlago.com/#/webhooks/invoiceOneOffCreated)
Sent when prepaid credits have been paid and added to the customer's wallet. You can use this information to generate a PDF invoice or collect the payment.
[Schema example](https://swagger.getlago.com/#/webhooks/invoicePaidCreditAdded)
Sent when the PDF file has been generated for a customer invoice. This will allow your application to retrieve the PDF invoice.
[Schema example](https://swagger.getlago.com/#/webhooks/invoiceGenerated)
Sent when the payment status of an invoice is updated based on information provided by the payment provider.
[Schema example](https://swagger.getlago.com/#/webhooks/invoicePaymentStatusUpdated)
Sent when the payment of an invoice is considered as overdue.
[Schema example](https://swagger.getlago.com/#/webhooks/invoicePaymentOverdue)
Sent when an invoice is voided.
[Schema example](https://swagger.getlago.com/#/webhooks/invoiceVoided)
Sent when there is an error related to the payment process. Usually occurs when no valid payment method is defined for the customer in the payment service provider's application.
[Schema example](https://swagger.getlago.com/#/webhooks/invoicePaymentFailure)
Sent whenever a dispute or a chargeback is lost within your payment provider.
[Schema example](https://swagger.getlago.com/#/webhooks/invoicePaymentDisputeLost)
Sent when an invoice has been resynced with salesforce.
[Schema example](https://swagger.getlago.com/#/webhooks/invoiceResynced)
## Payments
This message is triggered when a payment requires additional validation or confirmation, typically via 3D Secure (3DS). This is commonly seen in regions like India or when enhanced customer authentication is necessary.
The `url` field contains the checkout link that initiates 3D Secure (3DS) validation for your customers. The `return_url` is the page displayed once the 3DS process is completed.
[Schema example](https://swagger.getlago.com/#/webhooks/paymentRequiresAction)
This message is triggered when a an error was raised by a payment provider.
[Schema example](https://swagger.getlago.com/#/webhooks/paymentProviderError)
Sent when a manual payment request has been triggered, to request payment for the overdue balance.
[Schema example](https://swagger.getlago.com/#/webhooks/paymentRequestCreated)
Sent when the payment attached to a payment request has failed. The `provider_error` field indicates the error code and message from the payment provider.
[Schema example](https://swagger.getlago.com/#/webhooks/paymentRequestPaymentFailure)
Sent when the payment attached to a payment request is updated to a new payment status, through the \`payment\_status field.
[Schema example](https://swagger.getlago.com/#/webhooks/paymentRequestPaymentStatusUpdated)
## Payment receipts
Payment receipt object. Sent when a payment receipt is created.
This event serves as a signal to your application that the receipt creation is complete and the payment has been recorded.
Payment receipt object. Sent when the PDF file has been generated for a payment receipt. This will allow your application to retrieve the PDF receipt.
## Plans
Sent when a plan is created.
[Schema example](https://swagger.getlago.com/#/webhooks/planCreated)
Sent when a plan is updated.
[Schema example](https://swagger.getlago.com/#/webhooks/planUpdated)
Sent when a plan is deleted.
[Schema example](https://swagger.getlago.com/#/webhooks/planDeleted)
## Subscriptions and fees
Sent when a fee for a charge to be paid in advance is created. You can use this information to collect the payment of the `pay_in_advance` fee. Useful for fintech companies that need to create a statement of transactions without invoicing.
[Schema example](https://swagger.getlago.com/#/webhooks/feeCreated)
Sent when an error was encountered while fetching taxes for a fee on a tax provider.
[Schema example](https://swagger.getlago.com/#/webhooks/feeTaxProviderError)
Sent when a subscription starts. The `previous_plan_code` argument is filled if the subscription has been upgraded or downgraded.
[Schema example](https://swagger.getlago.com/#/webhooks/subscriptionStarted)
Alert for imminent termination of subscriptions with set end dates, sent 45 days and 15 days prior (at fixed intervals).
[Schema example](https://swagger.getlago.com/#/webhooks/subscriptionTerminationAlert)
Sent when a subscription is terminated. The `next_plan_code` argument is filled if the subscription has been upgraded or downgraded.
[Schema example](https://swagger.getlago.com/#/webhooks/subscriptionTerminated)
Sent when the free trial is ended for a subscription.
[Schema example](https://swagger.getlago.com/#/webhooks/subscriptionTrialEnded)
Sent when a progressive billing threshold has been crossed.
[Schema example](https://swagger.getlago.com/#/webhooks/subscriptionUsageThresholdReached)
## Wallets and prepaid credits
[Wallet object](/api-reference/wallets/wallet-object). Sent when a wallet is created.
[Wallet object](/api-reference/wallets/wallet-object). Sent when a wallet is updated. Please note that you won't receive this message if the wallet's ongoing balance is updated.
[Wallet object](/api-reference/wallets/wallet-object). Sent when a wallet is terminated.
Sent when the ongoing balance is negative or equal to 0.
[Schema example](https://swagger.getlago.com/#/webhooks/walletDepletedOngoingBalance)
Sent when a wallet transaction is created. For example, when new credits have been paid or offered.
[Schema example](https://swagger.getlago.com/#/webhooks/walletTransactionCreated)
Sent when a wallet transaction is updated. For example, when wallet transaction is marked as settled.
[Schema example](https://swagger.getlago.com/#/webhooks/walletTransactionUpdated)
Sent when a wallet transaction payment is declined.
[Schema example](https://swagger.getlago.com/#/webhooks/walletTransactionPaymentFailure)
# Product updates
Source: https://getlago.com/docs/changelog/product
New updates and improvements to Lago.
## Granular API access to plan and subscription charges
You can now manage charges, charge filters, and fixed charges directly through the API — without going through the full plan or subscription payload.
Previously, updating a charge required sending the entire plan object. These new dedicated endpoints give you surgical control over individual charges and their pricing rules.
* **Plan charges** — [See API reference](/api-reference/plans/charges/object)
* **Plan charge filters** — [See API reference](/api-reference/plans/charges/filters/object)
* **Plan fixed charges** — [See API reference](/api-reference/plans/fixed-charges/object)
* **Subscription charges** — [See API reference](/api-reference/subscriptions/charges/object)
* **Subscription charge filters** — [See API reference](/api-reference/subscriptions/charges/filters/object)
* **Subscription fixed charges** — [See API reference](/api-reference/subscriptions/fixed-charges/object)
## Multiple payment methods on customer (Beta)
Lago now supports storing and managing multiple payment methods per customer — including manual payments.
Need a subscription paid by card, but a one-off invoice handled manually?
You can now store multiple payment methods per customer and assign them independently to subscriptions, one-off invoices, and wallet top-ups.
[Learn more](/guide/payments/payment-methods)
## Reinvented billing analytics
We've completely rebuilt analytics in Lago from the ground up, powered by [Apache Superset](https://superset.apache.org/).
The old single-purpose dashboards are gone. In their place: a **fully composable analytics layer** where you can build, customize, and explore the reports that matter to your business: Revenue streams, MRR, usage patterns, credit consumption, and more.
What's new:
* **Composable dashboards** — mix and match visualizations to fit your reporting needs
* **Multi-dimensional filtering** — slice data by customer, plan, subscription, currency, country, and time
* **Data export** — download any chart or dataset as JSON, CSV, or Excel
* **Extensible by design** — create custom dashboards for board reporting, product analysis, or customer-level deep dives
[Learn more](/guide/analytics/reports)
## Filter webhook messages by event type
You can now choose exactly **which events are sent to each webhook endpoint**. This gives you full control over the notifications your systems receive and helps reduce unnecessary traffic.
We also added **new filtering options in the webhook list**. You can now filter deliveries by HTTP status, event type, and date range to quickly find and troubleshoot specific messages.
[Learn more](/guide/webhooks)
## Resend emails to customers
Need to send or resend an invoice or credit note to a different recipient? You can now **resend emails** with full control over who receives them.
Choose your recipients using To, CC, and BCC fields, making it easy to forward billing documents to different departments or team members.
This gives you the flexibility to manage your customer communications exactly how you need.
[Learn more](/guide/emails#resend-emails)
## Track billing emails in audit logs
Stay on top of your customer communications with **email logs** now integrated into your audit logs.
Track all emails sent by the system for invoices, credit notes, and payments in one centralized location.
You can easily filter logs to find specific email types and monitor delivery status, ensuring complete visibility into your automated billing communications.
[Learn more](/guide/security/audit-logs)
## Offset unused amounts when terminating a subscription
With the new credit note offset settings, you can now apply this option when terminating a subscription to offset any unused amount due.
The used amount remains payable, while the remaining balance is automatically settled through a closing credit note.
[Learn more](/guide/subscriptions/terminate-subscription#generate-a-closing-credit-note-at-subscription-termination)
## Fixed charges are now available in plans
You can now add fixed charges to your plans to bill recurring fixed fees, independently of usage.
This unlocks common pricing patterns such as platform fees, seat licenses, support plans, or contractual fees.
Fixed charges are managed directly at the plan level and billed automatically with subscriptions.
There’s no need to rely on one-off invoices anymore.
[Learn more](/guide/plans/charges/fixed-charges)
## Offset invoice amount due with credit notes
Overcharged a customer? Issued an invoice by mistake? No problem.
You can now use a credit note to offset the remaining amount due on an invoice.
The credited amount is immediately deducted from the invoice balance, keeping your records accurate and clean
[Learn more](/guide/invoicing/credit-notes/overview#offset)
## Define custom roles and permissions
We have introduced **Custom Roles and Permissions** to give organizations full control over user access within Lago and your billing data.
You can now create an **unlimited number of custom roles and define precise permission sets** that match your team's responsibilities and workflows. This allows you to grant users only the access they need, improving both security and operational clarity.
Key capabilities:
* Create and manage unlimited custom roles;
* Assign granular permissions to each role;
* Automatically propagate permission changes to all users assigned to a role; and
* Ensure continuous platform governance by maintaining at least one `admin` role at all times.
This update simplifies scaling billing operations across teams, strengthens access control enforcement, and allows permissions to evolve seamlessly as your organization grows.
[Learn more](/guide/security/rbac#custom-roles-and-permissions)
## Connect AI Systems with Lago MCP Server
**The Lago MCP Server is now available!** Securely connect your AI ecosystem to enterprise billing data.
It allows you to connect AI systems, such as language models or other intelligent agents, with Lago's billing capabilities.
This enables you to build AI-powered applications that can autonomously manage billing operations, such as creating subscriptions, processing payments, and handling invoices.
[Learn more](/guide/ai-agents/mcp-server)
## Multiple wallets are now available!
You can now create more than one wallet per customer.
Each wallet has its own settings: define its priority, limit its scope to specific billable metrics, and configure dedicated recurring top-up rules to better control how credits are applied.
[Learn more](/guide/wallet-and-prepaid-credits/overview#create-wallets)
## Invoice issuing date preferences
**Take full control of when your subscription invoices are dated.**
Many businesses need invoices dated on the last day of the billing period, not the first day of the next. This is mainly useful for revenue recognition, compliance, or cleaner accounting.
You can now configure this at the Billing Entity level (with per-customer overrides) using two new settings: **Issuing Date Anchor** and **Issuing Date Adjustment**.
For example, an October subscription invoice can now show October 31st instead of November 1st.
[Learn more](/guide/invoicing/invoicing-settings/issuing_date)
## Metadata for credit notes
You can now enrich your credit notes with custom metadata.
This allows teams to store key operational details — such as the reason for issuing the credit note, internal notes, or synchronization references for external tools.
[Learn more](/guide/invoicing/credit-notes/credit-note-metadata)
## Agentic AI for Billing Operations
Introducing our 1st Lago AI Agent, called the **Billing Assistant**, a conversational assistant to help you manage billing operations using natural language.
This conversational assistant helps you **manage billing operations using natural language**, reducing the time spent on manual and repetitive tasks.
Ask questions, retrieve data, and perform actions across your billing entities, all through a simple chat interface.
Conversations are saved for context-aware follow-ups, and built-in safeguards require confirmation before executing any destructive actions.
[Learn more](/guide/ai-agents/billing-assistant)
## E-invoicing and compliant documents
Lago now generates invoices in the correct formats required for **E-invoicing integrations**. The first fully supported jurisdiction is France 🇫🇷, and **adding new jurisdictions is straightforward through template updates or open source contributions**.
For invoices, credit notes, and payments, Lago now produces two documents:
* A hybrid PDF/A 3 with embedded XML using UN/CEFACT Cross Industry Invoice, suitable for human reading; and
* A pure XML file using UBL EN 16931, suitable for machine processing.
While Lago **does not handle automatic transmission to local authorities**, you can download all XML files and upload them to your jurisdiction portal.
Feel free to contact the team or submit an open source contribution, especially for jurisdictions that share similar formats with minor adjustments.
[Learn more](/guide/invoicing/e-invoicing/overview)
## New integration mapping per Lago Billing Entity
We enhanced how accounting and tax integrations are configured with Lago.
You can now **map product items and tax items at the Lago Entity level** across all your integrations.
This gives you precise control over how each Lago entity connects to external accounting or tax systems and ensures accurate data syncs for your team.
## Smarter Revenue Forecasts and Predictions with Lago
Forecasting revenue is notoriously challenging, especially for usage-based companies. Usage fluctuates over time, definitions of revenue vary from a company to another, and reliable prediction models are often missing.
At Lago, we set out to make this process easier!
We have introduced our first **ML model** to **forecast your usage-based revenue up to 12 months ahead**. The model provides **three scenarios**: **Realistic**, **Pessimistic**, and **Optimistic**, and regularly refines its predictions based on your invoiced usage data.
This feature is currently available for companies with at least six months of usage data in Lago to ensure optimal accuracy.
[Learn more](/guide/analytics/forecasted-usage)
## Find customers faster with new filters
Quickly find the right customers by filtering your list (via API or UI) using metadata, active subscriptions, Tax ID, and more — making large datasets easier to navigate and act on.
[Learn more](/api-reference/customers/get-all?playground=open)
## Wallet transaction limits
You can now define minimum and maximum amounts for each paid wallet transaction. Any top-up must stay within these boundaries; transactions below the minimum or above the maximum will be rejected. This ensures better control over wallet usage and prevents unexpected amounts being processed.
For added flexibility, you can bypass wallet transaction limits when needed. Overrides can be applied either by adding the `ignore_paid_top_up_limits` flag in the API payload or by enabling the Skip top-up limits for this transaction option in the UI. This applies to both one-off and recurring (automatic) top-ups.
[Learn more](/guide/wallet-and-prepaid-credits/overview#wallet-transaction-limits)
## Wallet transaction name
Add context to your invoices by naming wallet transactions — whether they come from a manual top-up or a recurring rule.
The transaction name now appears on prepaid credit purchase invoices.
[Learn more](/api-reference/wallets/top-up#body-wallet-transaction-name)
## Semiannual billing interval
In addition to weekly, monthly, quarterly, and yearly billing intervals, subscriptions can now also be billed on a **semiannual** basis.
This new option also applies to recurring wallet top-ups, which can now be scheduled every 6 months.
[Learn more](/guide/plans/plan-model#plan-interval)
## Entitlements are now supported in Lago 🎉
Until now, Lago supported subscriptions, discounts, prepaid credits, and usage-based charges. But one key piece was missing: **Entitlements**.
Entitlements are the features included in a plan or subscription that aren't usage-based, but still define what a customer can access. For example:
* On **Plan A**, a customer gets **Okta SSO** and can invite **up to 3 members**.
* On **Plan B**, another customer can invite **up to 10 members** and gets a **7-day log retention**.
Traditionally, billing and entitlements were managed separately. But they shouldn't be. They are two siblings. Two faces of the same coin. That's why, starting today, you can:
1. **Define features** directly in Lago.
2. Attach (**entitle**) them to plans.
3. **Override** them for individual subscriptions.
4. Create **feature-level privileges** that vary across plans.
With this release, entitlements become first-class citizens in Lago, right alongside subscriptions, metering and usage-based billing.
[Learn more](/guide/entitlements)
## Revenue streams dashboard improvements
We've made some improvements to the Revenue Streams dashboard to make it more intuitive, espeicially for the gross vs net revenue calculation. We now display the contra revenue, including coupons, discounts, and credits.
[Learn more](/guide/analytics/revenue-streams)
## Set service periods on one-off line items
You can now define a service period for one-off line items. Instead of recognizing them on a single date, they can cover a period — in the past, starting today, or in the future.
This gives you full flexibility to set the billing boundaries you need, for each line item individually.
[Learn more](/guide/one-off-invoices/create-one-off-invoices)
## Terminate subscriptions without unwanted credit notes
By default, Lago issues a credit note when you terminate a **pay-in-advance** subscription. Now, you decide what happens: skip the credit note, credit the unused amount, or refund it.
No more cleaning up credit notes that were never meant to be sent — just pick the right option in the termination dialog.
[Learn more](/guide/subscriptions/terminate-subscription#generate-a-closing-credit-note-at-subscription-termination)
## Do not generate invoice at subscription termination
Created a subscription by mistake? You can now terminate it **without generating a closing invoice**, so you don’t have to deal with invoices that were never meant to exist.
Just pick the option in the termination dialog — and we’ll skip creating it.
[Learn more](/guide/subscriptions/terminate-subscription#generate-a-closing-invoice-at-subscription-termination)
## Display the projected usage of your customers
Give your customers visibility into their upcoming bills, before the invoice drops.
With the new Projected Usage endpoint, you can help users estimate their final usage and costs for the current billing period, based on real-time consumption trends.
Perfect for:
1. Displaying projected costs inside your app
2. Give customers visibility into their upcoming bills
3. Helping customers stay in control of their spend
Built on the same engine as the [current usage endpoint](../../api-reference/customer-usage/get-current), it ensures consistent and trustworthy projections.
[Learn more](/guide/events/retrieve-usage#retrieve-projected-usage)
## Regenerate voided invoices
We've just made it easier to **fix and reissue invoices** — no more starting from scratch. With our new **"Regenerate Voided Invoice"** feature, you can now recreate a voided invoice directly from the UI in just a few clicks.
The original line items and fees are pre-filled for convenience, and you can still make changes such as adjusting quantities or updating amounts before sending it out. The regenerated invoice remains linked to the original one, ensuring full traceability for your accounting records.
And the cherry on top 🍒: you now have **multiple refund options when voiding an invoice**, giving you greater flexibility based on the payment method and accounting preferences.
[Learn more](/guide/invoicing/void#regenerate-a-voided-invoice)
## Limit prepaid credits to specific billable metrics
If you're offering prepaid credits, great, you're riding the AI wave! But not all usage should be tied to credits. Some metrics are better off billed the old-fashioned way: with traditional payment methods.
What's new? You can now choose which metrics are deducted from prepaid credits, and which ones are billed separately using other payment methods.
This gives you more control over your pricing strategy and helps align billing with your product's value delivery.
[Learn more](/guide/wallet-and-prepaid-credits/overview#application-scope)
## Get payment links for pending invoices
You're not a technical user, but your customer is asking for a way to pay an invoice generated through Lago. No worries, it's easy! Just click the “Get payment link” button to generate a secure checkout link you can share.
## Custom pricing units for more flexible billing!
You can now express charges in **pricing units** like `credits` or `tokens` — not just fiat currency.
This gives you more flexibility to align your pricing with how your product delivers value. You can now:
* **Create pricing units** (e.g., tks, cdt) from your settings.
* **Define charges** in pricing units within a plan, with a **conversion rate** back to fiat for accurate invoicing.
* **Track usage** in both fiat and pricing units.
* **Generate invoices** that show both values, while ensuring billing in fiat stays consistent.
* **Use pricing units independently or alongside wallets** — they don’t interfere with each other.
[Learn more](/guide/plans/custom-pricing-units)
## Enforce login methods per organization
You can now customize which login methods are allowed for each organization — including requiring SSO (e.g. Okta) while disabling others like email/password or Google.
This ensures better security and compliance for teams with strict authentication requirements.
➡️ Head to Settings → Authentication to configure allowed methods.
[Learn more](/guide/security/sso#login-method-enforcement)
## New navigation bar
July is here, and the sun is knocking on our door!
We’ve redesigned the navigation bar to make it more intuitive and easier to use.
This new navigation will give you access to even more features — but shhh… they’re not ready to launch just yet 🤫
## Track API requests with API Logs
❓'Which endpoints have been used?'
❓❓'Which requests are failing?'
❓❓❓'Which API client triggered this request?'
API logs offer a comprehensive record of all API requests and calls made within your organization. They serve as an essential tool for monitoring activity, troubleshooting issues, and auditing system usage.
[Learn more](/guide/security/audit-logs#api-logs)
## Pricing group keys
**Launch Week IV, Day 5: Pricing Group Keys**
AI and infrastructure platforms often tailor pricing based on variables such as geography, hosting provider, or service tier. Lago's Pricing Group Keys offer a streamlined way to support this kind of dynamic pricing without duplicating product definitions.
With pricing group keys, you can group usage events to a single product based on configurable dimensions—like cloud provider, model type, deployment region, or instance class. This allows you to reflect real-world cost variations while keeping your product catalog clean and manageable.
When setting up a charge, you define the relevant keys. You don't need to predefine every possible value. Instead, Lago intelligently routes each usage event to the correct pricing group based on the attributes provided at runtime.
[Learn more](/guide/plans/charges/grouping#pricing-group-keys)
## Prepaid credits limited to specific charges
**Launch Week IV, Day 4: Restrict Prepaid Credits to Specific Charges**
You can now configure prepaid credits to apply only to designated charges within an invoice. This allows greater control over credit usage—for instance, preventing customers from using their prepaid credits to cover the entire invoice and instead limiting them to specific eligible items or charge types.
[Learn more](/guide/wallet-and-prepaid-credits/overview#application-scope)
## Avalara Tax Integration
**Launch Week IV, Day 3: End Tax Guesswork — Lago x Avalara Integration**
You can now connect Lago to Avalara to make tax management easier. This native integration allows you to automatically update your invoices with tax amounts sourced directly from Avalara.
1️⃣ Lago sends the customer's address, tax identifier (if applicable), and the relevant tax code to calculate the appropriate tax for each line item.
2️⃣ Avalara calculates the tax for the invoice and returns the data to Lago, which is used to update the invoice with accurate tax information.
3️⃣ Lago synchronizes updates for voided and disputed invoices, as well as any credit notes created, ensuring that your records remain up to date.
This integration is accessible with a premium add-on.
[Learn more](/integrations/taxes/avalara)
## Activity Logs
**Launch Week IV, Day 2: Billing Activity Logs**
❓'Who changed that price point?'
❓❓'Who created that plan?'
❓❓❓'What happened to this invoice?'
We got you! That's why we are launching one of the most underrated but essential billing features: Activity Logs.
Lago is used by engineering, finance, sales, and growth teams. Engineers build the billing engine, sales customize deals, finance reviews data—it can get messy. Activity logs bring clarity!
Every change is now logged. You’ll know who did what, when, and how—whether it came from the UI or API. We track the user or API key, the action, timestamps, resource IDs, and more. It is like git, but for your billing stack.
[Learn more](/guide/security/audit-logs)
## Budget & Usage Alerts
**Launch Week IV, Day 1: Budget & Usage Alerts!**
We've all heard the horror stories of unsupervised AWS instances that lead to million-dollar invoices. Even when we're not talking about millions, you probably know the feeling of usage-based bills far more expensive than you thought.
Lago now helps you prevent those scenarios. With budget & usage alerts, you can put hard edges around consumption and billing.
The feature is basically a multi-layered warning system. You can track:
1. **Lifetime spend** for the entire subscription—ideal for free trials that should never exceed, say, a total of \$100.
2. **Current-period spend** so finance knows when a customer hits 80 percent of this month's credits and engineering can act before overages accrue.
3. **Metric-based spend** in amount or usage units, meaning you can send an alert when a user has used up 1 million API calls or \$100 of API calls.
[Learn more](/guide/alerts)
## Multiple billing entities within a Lago account!
You can now manage multiple billing entities within a single Lago account.
Whether you operate with different subsidiaries or invoice on behalf of third parties, this feature lets you issue invoices from multiple senders, different subsidiaries—without duplicating your setup.
Your existing configuration (billable metrics, plans, settings, etc.) stays intact, making it easy to scale across entities while invoice settings (timezone, locale, grace period, etc.) can be configured differently.
[Learn more](/guide/billing-entities)
## Know everything about prepaid credits consumption
Our new prepaid credits dashboard is now live in beta! You can now track the flow of your prepaid credits, including the amount of credits offered, paid, consumed, and voided.
[Learn more](../guide/analytics/prepaid-credits)
## Idempotent payment URL generation
We made the payment URL generation idempotent to safely share with your end customers.
Each URL remains valid and unchanged for 24 hours, no matter how many times the endpoint is called — helping you prevent duplicate payments and simplify the checkout flow.
After 24 hours, a new URL will be generated on the next call, valid for the next 24-hour period.
[Learn more](/guide/payments/payment-retries#generate-a-payment-url)
## Lago Data Pipeline is now in beta
You need to **sync your Lago data to your data warehouse or cloud storage?** We've got you covered with a new native integration called `Lago Data Pipeline`!
Lago Data Pipeline is now in beta and available for a selected group of customers. Reach out to your account manager to get access.
More than 20 data destinations are supported, including Snowflake, BigQuery, Redshift, Databricks, Athena, ClickHouse, MotherDuck, Postgres, Aurora Postgres, MySQL, Aurora MySQL, SQL Server, SingleStore, S3, S3-Compatible, GCS, ABS, and Google Sheets.
[Learn more](../integrations/data/lago-data-pipeline)
## Failed payment nightmares are over: Lago payment pre-authorization
Sick of launching a subscription, watching customers dive in all month, only to have payment fail at billing time—and then radio silence when you reach out? Failed charges not only leave revenue on the table but also create churn, frustrate customers, and bog your team down in manual follow-ups.
With Lago's Payment Pre-Authorization, **you can now verify a card's validity and available funds when starting a subscription.** Catch bad payment methods upfront, automate notifications for declined pre-auths, and keep your service—and your revenue—flowing seamlessly. Enable it in your Lago dashboard today and turn payment nightmares into smooth, uninterrupted growth.
[Learn more](../guide/payments/payment-authorization)
## Pay your Lago invoices with Moneyhash
You can now pay your Lago invoices using [Moneyhash](https://moneyhash.io)!
Moneyhash is the leading payment infrastructure software in Africa and the Middle East.
They help businesses across Emerging Markets to optimize payment performance, scale operations, cut costs, and grow revenue through an all-in-one orchestration platform.
If you issue invoices for customers in Africa or MENA, this integration is for you!
[Learn more](../integrations/payments/moneyhash-integration)
This integration has been built and maintained by our partner Moneyhash.
## Enhanced Revenue Streams and MRR dashboard are now live in Beta
We've just launched Analytics v2 in beta for some premium customers! This upgraded experience brings deeper insights and more powerful tools to understand your revenue performance:
1. Revenue per Stream: Get a detailed breakdown of how each stream contributes to your bottom line.
2. Enhanced MRR Dashboard: Track your Monthly Recurring Revenue breakout with detailed views
This marks a major step forward in Lago's new Analytics view, designed to help you make smarter, data-driven decisions. If you're part of the beta, we'd love to hear your feedback!
[Learn more](../guide/analytics/revenue-streams)
## Rescue failed wallet transactions!
Payment intent failed? No worries — we've added a new endpoint that generates a payment URL for pending and failed wallet transactions. This feature allows your customers to complete their wallet top-ups through a secure checkout page, similar to how invoice payments work.
A smoother recovery, a better experience. Dive into the docs for all the details!
[Learn more](../api-reference/wallets/wallet-transaction-payment-url)
## Track every cent: Payment Receipts are now available!
✨ This feature is only available as an add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Payment Receipts.
To give your customers better visibility into their payments, we've introduced **Payment Receipts** — a new PDF document and API payload generated by Lago.
Unlike invoices, these receipts provide a clearer breakdown of payments received, including the payment method used and any remaining balance.
This helps your customers track their transactions more easily and improves transparency around outstanding amounts.
[Learn more](../guide/payments/receipts)
## Disable pdf generation
If you don’t rely on our PDFs, you can now configure Lago—via an environment variable—to skip PDF generation for invoices, credit notes, and receipts.
Lago won’t process any jobs related to these documents, keeping your queues less crowded.
[Learn more](../guide/lago-self-hosted/docker#environment-variables)
## Invoice previews for upgrades and downgrades
You can now preview invoices not just for new customers or dry runs on existing subscriptions, but also for upgrades, downgrades, and even plan terminations.
This means you have all the tools you need to estimate and preview invoices for every billing scenario. Get ready to take control of your billing like a pro!
[Learn more](../guide/invoicing/previews#preview-an-invoice-for-upgrades-and-downgrades)
## Enhanced wallet transaction details
You can now view detailed information about a wallet transaction by simply clicking on it.
We’ve added comprehensive data to improve your understanding, including all relevant transaction details, linked payments, and associated invoices.
This update makes it easier to track and analyze your wallet transactions at a glance.
## Failed wallet transaction
We’ve introduced the `failed` wallet transaction! Now, when a wallet transaction is linked to a failed payment, its status will automatically update from `pending` to `failed`.
This enhancement provides a clearer view of the transaction lifecycle and simplifies debugging when needed.
## Expiration date for wallet recurring transaction rule
As part of our initiative to enhance the wallet experience, we’ve introduced two new settings for wallet recurring transaction rules.
* You can now set an expiration date for a rule, and Lago will automatically terminate it once reached, preventing any further top-ups.
* Additionally, you can define metadata for recurring top-ups directly through the Dashboard.
[Learn more](../guide/wallet-and-prepaid-credits/wallet-top-up-and-void#expiration-date)
## New webhook message on wallets
We’ve introduced new webhook messages to help you better understand activity on your wallets. You can now listen to `wallet.created`, `wallet.updated`, and `wallet.terminated` events.
[Learn more](../api-reference/webhooks/messages#wallets-and-prepaid-credits)
## Pay Lago invoices via Bank Transfers
Lago now supports Stripe’s bank transfers (customer\_balance) for invoice payments. Supported methods:
* JPY: Japan
* GBP: United Kingdom
* EUR: Specific SEPA countries (see Stripe documentation)
* MXN: Mexico
* USD: United States, United Kingdom, and select SEPA countries
[Learn more](../guide/payments/stripe-integration#bank-transfers-customer-balance)
## Custom SMTP Management
By default, Lago automatically handles your SMTP configuration—no extra setup required.
However, if you prefer to use your own SMTP server, Enterprise customers can now send emails through a custom SMTP configuration.
## Effortless Docker deployment in a single command
We heard you—the old Docker commands were a bit of a hassle, so we've made things easier. Now, you can get the app up and running with just one simple command in your shell. Enjoy!
[Learn more](../guide/lago-self-hosted/docker#run-the-app-with-a-one-click-docker-command)
## To the moon: Crypto payments are now available
Lago now supports crypto payments! Don't worry though, your customers won't be paying you in a dog meme coin anytime soon. For now, we support USDC/USDP payments if you're using Lago with Stripe payments.
If you don't know, USDC is a stablecoin that's pegged to the US Dollar and always worth exactly \$1, so it's not some speculative memecoin you're getting into.
Of course, you can turn this on and off as you like.
[Learn more](../guide/payments/stripe-integration#crypto-stablecoins)
## Record payments and partial payments
✨ This feature is only available via a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
Some invoices aren't paid in full right away, or some of them are paid through bank transfers. This is true especially in bigger enterprise deals with unique payment terms. But this means that the invoice is neither unpaid nor paid — it's partially paid.
You can now record these payments in Lago and easily find partially paid invoices at a glance by filtering. That way, you don't have to remember payments in your head, but always have an accurate overview directly in Lago.
[Learn more](../guide/payments/record-manual-payments)
## Partner billing & self-invoicing
✨ This feature is only available via a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
Many of our customers share some revenue with partners. If a partner gets them a new customer, the partner gets a cut of that revenue.
This is easy enough for subscriptions and tons of vendors enable this. But if you charged based on usage, you had to do it all manually because most billing systems couldn’t handle this.
We’re solving this now. Previously, you could only use Lago to invoice your customers. Now you can create partners. A partner invoice is addressed to you and comes from your partner, a concept we call self-billing.
This means you can now manage partnerships directly within Lago instead of needing multiple tools. Lago will also calculate both the revenue this partner brings you and their overall cost.
[Learn more](../guide/revenue-share)
## Back to the future with invoice previews
✨ This feature is only available via a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
By using the `/invoices/preview` endpoint, you can generate a preview of an invoice for a potential purchase or to estimate the dry-run invoice of an active subscription.
This preview calculates the total invoice amount, itemizes each charge, and applies any relevant taxes or discounts.
By creating a preview, you can share the projected payment details without generating or finalizing an invoice.
1. Prospective customers can now see exactly what they’ll have to pay if they buy the product. This gives them more clarity and makes them more likely to buy.
2. As a company, you can now see what a customer’s invoice would look like if it was issued right now. This lets you a) support your customers better when they have.
3. Your customers can preview what they’ll have to pay if they downgrade, upgrade, etc. in fine detail—including all taxes, credits, etc.
[Learn more](../guide/invoicing/previews)
## Add up to 10 webhook endpoints
We’ve increased the limit on the number of webhook endpoints available in your Lago app!
You can now add up to 10 webhook endpoints in the developer section.
[Learn more](../guide/webhooks#adding-a-webhook-url)
## Add fees to your draft invoices
As communicated, we no longer generate fees at 0 units, but you can still add them to Draft invoices if no event has been received.
Don’t hestiate to navigate into a Draft invoice and add fees linked to charges with no Event.
[Learn more](../guide/invoicing/draft-invoices#add-fees-to-draft-invoice)
## Retrieve a wallet transaction endpoint
We’ve added a new endpoint to the wallet experience!
No need to query the full wallet transaction list to view the details of a specific transaction—you can now retrieve a single wallet transaction directly with the new `GET /wallet_transactions/{lago_id}` endpoint.
[View endpoint](../api-reference/wallets/get-specific-transaction)
## Let Lago sync your customers directly with Salesforce!
We’ve streamlined the Salesforce integration experience.
Like all our other integrations, you can now set up the creation of a customer in Lago to sync with Salesforce.
If you need to test the Salesforce package, feel free to [reach out](mailto:hello@getlago.com)!
[Learn more](../integrations/crm/salesforce-crm#sync-customers-to-salesforce-v2-7)
## No need to leave Salesforce to apply coupons to accounts!
We understand that sales teams prefer to stay within Salesforce as much as possible, so we’ve enhanced the Salesforce integration.
You can now select specific coupons and apply or remove them directly to or from your accounts in Salesforce—no need to switch to Lago.
[Learn more](../integrations/crm/salesforce-crm#applying-coupons-to-accounts)
## Display custom invoice sections
Tailor invoices to each customer by adding personalized bank details!
With the custom invoice section, you can easily personalize templates and include essential details like legal information, all conveniently displayed in the footer.
Head to **Settings > Invoices > Invoice Custom Section** to try out this new feature.
[Learn more](../guide/invoicing/download-invoices#add-custom-invoice-section)
## Filter and export credit notes
Users can now filter the list of credit notes (e.g. by currency, customer, issuing date, amount, reason, etc.) and the filtered list can then be exported from the user interface.
Two export options are available:
* Standard, including the list of credit notes and credit note amounts (i.e. one row per credit note); and
* Advanced, including the list of credit note line items (i.e. one row per line item, so multiple rows per credit note if it includes multiple items).
The list is automatically emailed to the requester in a CSV file.
[Learn more](../guide/invoicing/export#filter-and-export-credit-notes)
## Granular API key permissions
You can now customize permissions for API keys in Lago! 🔒
When creating or editing an API key, you can define **read**, **write**, or **read and write** access for every object in the Lago API. This gives you full control over which endpoints can be accessed and how.
If an API key doesn’t have the required permissions, the API will block the request, ensuring enhanced security and precise access control.
[Learn more](../guide/security/api-keys#set-api-key-permissions)
## Edit and delete dunning campaign
You can now instantly update dunning campaign thresholds, delays, and attempts to fit your needs—changes may trigger new attempts for linked customers. No longer need a campaign? Delete it! Customers will either switch to the default campaign or be excluded if none exists.
[Learn more](../guide/dunning/automatic-dunning#edit-a-dunning-campaign)
## Create new API keys
✨ This feature is only available via a premium licence. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
Need more API keys? You can now manage your API keys more efficiently—create, name, and delete them to seamlessly connect Lago to other tools.
Visit the **Developers > API Keys** section to explore this new experience.
[Learn more](../guide/security/api-keys#create-an-api-key)
## Schedule an API key rotation
✨ This feature is only available via a premium licence. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
You can schedule an API key rotation to proactively manage security migrations. Choose a timeframe—now, in 1 hour, 24 hours, 48 hours, or 7 days—and Lago will automatically deactivate the old API key.
[Learn more](../guide/security/api-keys#schedule-an-api-key-rotation)
## Rotate your API key
Oops! Think your API key might be exposed, or just want to rotate it to stay safe? No worries—you don’t need to reach out to us. You can now quickly roll your key anytime in the Developer section.
[Learn more](../guide/security/api-keys)
## Automatic dunning: Payment reminders on autopilot
For businesses billing on usage, keeping payments timely is essential. That's why we're introducing **Automatic Dunning**—a hands-off way to manage overdue invoices and keep cash flow steady.
With Automatic Dunning, you can **set up tailored reminder campaigns** for different customer groups. Once activated, **these campaigns run on autopilot**, sending scheduled email reminders for any unpaid invoices. Reminders will keep going until the payment is made or you adjust the settings.
Automatic Dunning keeps your payment reminders on autopilot, so you can focus on what matters while your billing engine handles collections in the background.
[Learn more](../guide/dunning/automatic-dunning)
## Customizable rounding for usage metrics
Previously, usage rounding in Lago was limited to a default precision. Now, with **Customizable Rounding Rules**, you have full control over how usage-based metrics are rounded.
Choose from these rounding options:
* **Ceil**: Always round up to the nearest integer.
* **Floor**: Always round down to the nearest integer.
* **Round**: Round to the nearest integer using standard rounding rules.
Additionally, you can specify a **precision level**—positive or negative—allowing you to round usage to a set number of decimals.
[Learn more](../guide/billable-metrics/rounding)
## Build any usage-based metric with SQL expressions
Previously, usage-based metrics in Lago were powered by a single field—ideal for simplicity but limited in flexibility. Now, we are giving you complete control with SQL Expressions.
**With SQL Expressions, you can build metrics tailored to your needs**. Use advanced math operations, concatenations, rounding, and more to create precise, custom metrics that reflect your unique usage patterns.
**Custom expressions allow you to define more advanced computation logic** by dynamically using any event field within your expression. Here are a few examples:
* **Concatenation:** `CONCAT(value1, '_', value2)`
* **Math operations:** `((value1 * value2) / value3)`
* **Rounding:** `ROUND(value1 / value2)`
```SQL SQL Expression example theme={"dark"}
CEIL((event.properties.ended_at - event.timestamp) / 3600)
```
[Learn more](../guide/billable-metrics/sql-expressions)
## Cascade plan editions to overridden subscriptions
You have now the flexibility to decide whether changes made to the parent plan should automatically cascade to all overridden subscriptions.
For instance, if you add a new charge to the parent plan, it will immediately reflect in the overridden subscriptions, ensuring that all pricing updates are seamlessly applied across your entire customer base while maintaining the flexibility of custom pricing.
[Learn more](../guide/plans/overview#editing-plans)
## Sync billing data to HubSpot
With Lago’s new integration, you can now seamlessly sync billing data in real time to HubSpot. By connecting your Lago account to HubSpot, you’ll enable the following:
1. **Customer Creation**: Automatically create Contacts or Companies in HubSpot based on your Lago customer data.
2. **Invoice Syncing**: Real-time invoice sync to a HubSpot custom object named `LagoInvoices`.
3. **Subscription Syncing**: Real-time subscription sync to a HubSpot custom object named `LagoSubscriptions`.
[Learn more](../integrations/crm/hubspot)
## Quote in Salesforce CPQ, bill in Lago!
Our enhanced Salesforce package now enables you to use Salesforce CPQ for quoting leads and customers.
**Once a quote is approved and signed, it automatically triggers a real-time subscription in Lago**.
No need for separate processes—your sales team can directly create subscriptions from validated quotes within Salesforce.
[Learn more](../integrations/crm/salesforce-cpq)
## Dynamic pricing
Do your prices change dynamically based on a provider or complex in-house calculations?
Here are some real-life use cases:
* 🤖 AI companies: prices fluctuating based on real-time models cost
* 🏦 Fintech: matching prices to live market data
* 📱 Telco/CPaaS: adjusting costs to fluctuating carrier rates
We've heard you, and we're excited to introduce Dynamic Pricing for this!
You can now set a charge model as Dynamic and send the event amount directly through each event. No more headaches trying to manage interchange fees or fluctuating custom prices.
[Learn more](../guide/plans/charges/charge-models/dynamic)
## Credit note on prepaid credit invoices
Refund your customers who purchased prepaid credit in no time!
You can now process refunds for prepaid credit bought within Lago directly, without needing to engage your payment provider.
Lago takes care of the refund through its credit note module, enabling you to initiate the refund to the payment provider and automatically void the prepaid credit in the active wallet according to the wallet’s refund status.
[Learn more](/guide/invoicing/credit-notes/overview)
## Customer Portal complete rework
We’ve **completely reworked the Customer Portal**. You can now embed the portal URL to display in real-time **plans and usage information**, **wallet data**, **customer info**, and **invoice lists**.
Additionally, your end customers can take actions directly within the portal, such as **adding prepaid credits** and **updating their customer info**—all automatically synced with your Lago back office.
**Cherry on top?** We’re offering the new Customer Portal **for free** to all users, including those on our open-source plan.
## Usage ingestion sources
Premium ingestion sources for metering and usage consumption are now **generally available**.
Instead of using the basic API, you can leverage dedicated connectors to ingest data directly from sources like **AWS S3**, **AWS Kinesis**, **Kafka**, **MongoDB**, and **Azure**.
Most connectors support ingestion rates of **over 15,000 events per second** (compared to 1,000 via the basic REST API).
For custom ingestion connectors, please contact the Lago team.
[Learn more](/guide/events/metering-source)
## Customer type

Users can specify whether the customer is a company or an individual by setting the customer type.
By default, if no customer type is specified, customers are created without a defined type and you will need to assign one manually.
[Learn more](/guide/customers/customer-management#companies-vs-individuals)
## Send tax invoices

Lago invoices are now fully compliant with local legislation in Australia, Indonesia, New Zealand and the United Arab Emirates.
In those countries, it is mandatory to emit "Tax Invoices" accord to specific rules. This can now be handled with Lago.
## Retrieve all events using the API
Users can now retrieve and filters all events using the API. The endpoint also allows for filtering by:
* `code`
* `external_subscription_id`
* `timestamp_from`
* `timestamp_to`
[Learn more](/api-reference/events/list-events)
## Anrok integration ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
We have developed an integration with Anrok to make tax management easier. This native integration allows you to automatically update your invoices with tax amounts sourced directly from Anrok.
* Lago sends the customer's address, tax identifier (if applicable), and the relevant product ID to calculate the appropriate tax for each line item
* Anrok calculates the tax for the invoice and returns the data to Lago, which is used to update the invoice with accurate tax information
* Lago synchronizes updates for voided and disputed invoices, as well as any credit notes created, ensuring that your records remain up to date
This integration ensures compliance with international tax regulations by calculating taxes for US & non-US obligations, like VAT.
[Learn more](/integrations/taxes/anrok#mapping-items-between-lago-and-anrok-mandatory)

## Precise amount for fees
Lago now allows you to retrieve the precise (ie. non rounded) amount on the fee object. Before only the rounded `amount_cents` was available.
To use the precise fee amount, you can use the `precise_amount` field.
[Learn more](/api-reference/fees/fee-object)

## Progressive billing ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
Progressive billing, also known as threshold billing, automatically triggers an invoice when a customer's cumulative usage reaches predefined thresholds.
This method ensures that customers cannot exceed certain usage limits without ensuring payment is received, reducing the risk of unpaid services or fraud.
You can setup 2 types of threshold:
* Step-based threshold: invoices are generated when the lifetime usage of a subscription reaches a defined threshold. You can set an unlimited number of thresholds, each with a specific amount and a unique name
* Recurring threshold: this threshold determines what happens after the final step-based threshold is reached. (For example, after the last threshold, Lago will automatically bill \$100 each time the lifetime usage increments by that amount)
[Learn more](/guide/plans/progressive-billing#progressive-billing)
## Skip empty invoices generation
Users can now decide whether or not to issue \$0 invoices (ie. empty invoices). By default, empty invoices are generated. You can change this setting at the organisation level.
When creating a customer, it takes by default the configuration of the organization for this specific field.
However, you can decide to override this information for a specific customer. Why? You might have customers who need to receive an invoice each month, even if the total amount is 0.
[Learn more](/guide/invoicing/overview#finalize-empty-invoices)

## Filter and export invoices
Users can now filter the list of invoices (e.g. by currency, customer, issuing date, etc.) and the filtered list can then be exported from the user interface.
Two export options are available:
* Standard, including the list of invoices and invoice amounts (i.e. one row per invoice)
* Advanced, including the list of fees (i.e. one row per fee, so multiple rows per invoice if the invoice includes multiple fees)
The list is automatically emailed to the requester in a CSV file.
[Learn more](/guide/invoicing/export)

## Wallet transaction metadata
When creating a wallet transaction via API, you can add metadata to store additional information (e.g. source of the transaction).
This information is not displayed in the user interface.
[Learn more](/api-reference/wallets/wallet-transaction-object)
## Invoicing options for wallet top-ups
When creating a new wallet for a customer, users can choose to generate invoices for credit purchases either:
* As soon as the wallet transaction is created
* Only when payment is successful, which avoids generating invoices for transactions that have not been finalized
These options are also available for automatic and manual top-ups (see `wallet_transaction.invoice_requires_successful_payment`).
[Learn more](/guide/wallet-and-prepaid-credits/overview#invoicing-after-successful-payment-option)

## API changes (v1.7.0)
As announced a few months ago, we have updated the event ingestion process and removed deprecated API fields. Changes include:
**1. Replacing groups with filters**
The new dimension system based on filters allows users to create billable metrics with more than two dimensions, and makes it easier to create charges based on custom event properties. The old dimension system based on groups has been permanently removed from the Lago API ([see all changes](/guide/migration/migration-to-v1.2.0#1-transition-from-group-to-filters)).
**`2. Marking external_subscription_id as mandatory for events`**
Events that only include `external_customer_id` are no longer taken into account when aggregating usage ([learn more](/guide/migration/migration-to-v1.2.0#2-mandatory-external-subscription-id-field-in-event-payloads)). This change will streamline the event validation process and enable real-time billing capabilities.
**3. Removing deprecated API fields**
For the sake of clarity and to preserve the quality of the API, we've deprecated several legacy fields ([see full list](/guide/migration/migration-to-v1.2.0#3-deprecated-fields)).
[Learn more](/guide/migration/migration-to-v1.2.0)
## Invoicing options for instant charges ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
For charges paid in advances, Lago offers three invoicing options:
* An invoice can be issued for each event
* An invoice that only includes paid fees can be issued at the end of the billing period
* No invoices (users only rely on the `fee.created` webhook)
[Learn more](/guide/plans/charges/invoiceable-vs-noninvoiceable)

## Xero integration ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
We have developed a Xero integration to make accounting easier. Available features include:
* Connecting a Lago account to a Xero account via OAuth
* Mapping Lago objects such as billable metrics, plans, coupons, wallet credits and taxes to Xero items
* Real-time synchronization of customer accounts
* Real-time synchronization of invoices
* Real-time synchronization of credit notes
* Real-time synchronization of payments
[Learn more](/integrations/accounting/xero)

## Link checkout
For card payments processed through integration with Stripe, users can enable the Link option. Link automatically fills the customer's payment information for faster checkout.
[Learn more](/integrations/payments/stripe-integration#link)

## Overview of customer billing
The customer view features a new billing section, including:
* Gross revenue (i.e. total amount billed to the customer)
* Total overdue (i.e. total amount of invoices that are past their due date)
This improvement is the first step toward dunning management (coming soon).
[Learn more](/guide/customers/customer-management#monitor-the-customers-billing-status)

## NetSuite integration ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
We have developed a NetSuite integration to make accounting easier. Available features include:
* Connecting a Lago account to a NetSuite account via OAuth
* Mapping Lago objects such as billable metrics, plans, coupons, wallet credits and taxes to NetSuite items and tax items
* Real-time synchronization of customer accounts
* Real-time synchronization of invoices (and sales orders)
* Real-time synchronization of credit notes
* Real-time synchronization of payments
[Learn more](/integrations/accounting/netsuite)

## Shipping address
In addition to the customer's billing address, users can add a shipping address. This information can be useful when the applicable tax rates are determined through integration with a tax management provider (e.g. Anrok).

## Overdue invoices
If an invoice is not marked as paid once its due date has passed, it is considered to be overdue. The billing system will then send a webhook message to notify the organization that issued the invoice (see `invoice.payment_overdue`).
[Learn more](/api-reference/webhooks/messages#payment-overdue)

## Custom pricing ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
For companies whose aggregation and pricing models cannot be reproduced using standard functions, our team can inject a custom code snippet into the billing application.
This feature allows users to implement advanced billing rules based on custom logic, which can be very useful when migrating from an in-house billing system.
[Learn more](/guide/plans/charges/charge-models/custom-price)
## Okta SSO ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
Users can sign up and log in to their Lago account through Okta single sign-on (SSO), which enables a better experience and ensures that the identity provider remains the system of record for authenticating users.
[Learn more](/guide/security/sso#okta-sso)

## Hiding subscription fees at zero
We have modified the invoice template and introduced new rules for subscription fees:
* If `amount_cents` is zero for the subscription fee and there are no other fees (e.g. usage-based charges or commitment) in the invoice, the subscription fee will appear on the PDF invoice
* If `amount_cents` is zero for the subscription fee and there are other fees in the invoice, the subscription fee will not be displayed on the PDF invoice
## Role-based access control (RBAC) ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
With the RBAC feature, organizations can ensure that each member only has access to the information and actions required to perform their job duties.
There are three roles available on the Lago platform:
* Admin: full access to all views and actions (usually assigned to billing engineers and managers)
* Account Manager: can manage customer accounts and subscriptions (suitable for sales and success teams)
* Finance & Analyst: mostly view-only, with the ability to manage invoices and credit notes
[Learn more](/guide/security/rbac)

## Recurring wallet top-ups ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
Users can define rules to automatically trigger wallet top-ups, based on two methods:
* Fixed: a predefined number of credits is added to the customer's wallet
* Target: credits are added to the customer's wallet to reach a predefined balance
There are also two trigger options:
* Interval: weekly, monthly, quarterly, semiannual or yearly top-ups, with a custom start date
* Threshold: the top-up is triggered when the ongoing balance of the wallet reaches a predefined minimum threshold
[Learn more](/guide/wallet-and-prepaid-credits/wallet-top-up-and-void#setup-recurring-top-ups)

## Webhook messages for wallets
Lago now sends webhook messages when:
* A wallet transaction is created (see `wallet_transaction.created`)
* The status of a wallet transaction is updated (e.g. when a pending transaction is settled - see `wallet_transaction.updated`)
* When the ongoing balance of the wallet is zero or less than zero (see `wallet.depleted_ongoing_balance`)
[Learn more](/api-reference/webhooks/messages#wallets)
## Void wallet credits
The endpoint `POST /wallet_transactions` includes a new function to void credits, which are immediately deducted from the balance of the customer's wallet.
This action can also be triggered via the user interface.
[Learn more](/api-reference/wallets/top-up)

## Filters for billable metrics
We have made changes to our dimension system and replaced metric groups with filters. This new feature offers greater flexibility as:
* Users can create as many filters as needed (they are no longer limited to two dimensions)
* Users can define specific rates based on very granular filter combinations (e.g. online card payments with Visa cards, offline card payments with Amex cards, etc.)
[Learn more](/guide/plans/charges/charges-with-filters)

## Google SSO
Users can sign up and log in to their Lago account through Google single sign-on (SSO), which enables a better experience and ensures that the identity provider remains the system of record for authenticating users.
[Learn more](/guide/security/sso#google-sso)

## Improved trial period
When the subscription fee of a plan is paid in advance and the plan includes a trial period, the first invoice was initially generated when the subscription started. Following feedback from the Lago Community, we have modified this logic to generate the first invoice at the end of the free trial.
[Learn more](/guide/plans/plan-model#the-trial-period-optional)
## Payment disputes
If a payment dispute is reported as lost by the payment provider, Lago will provide `invoice.payment_dispute_lost_at` and send the webhook message `invoice.payment_dispute_lost`.
This feature is available via integrations with Stripe and Adyen.

## Upcoming API changes (v1.2.0)
We have released a new version of Lago with exciting new features, but also API changes likely to affect our users' workflows.
**1. Replacing groups with filters**
We have developed a new dimension system that offers greater flexibility. Filters allow users to create billable metrics with more than two dimensions, and make it easier to create charges based on custom event properties.
However, this feature introduces changes to a number of objects, including `billable_metric`, `plan`, `fee` and `customer_usage`. In addition, the endpoint to retrieve billable metric groups will be deprecated ([see all changes](/guide/migration/migration-to-v1.2.0#1-transition-from-group-to-filters)).
**2. The external subscription ID becomes mandatory for events**
In order to develop real-time billing capabilities, we need to streamline our validation process. We have therefore decided to make `external_subscription_id` mandatory when sending events via the Lago API.
Events that only include `external_customer_id` will no longer be taken into account when aggregating usage ([learn more](/guide/migration/migration-to-v1.2.0#2-mandatory-external-subscription-id-field-in-event-payloads)).
**3. Deprecation of API fields**
For the sake of clarity and to preserve the quality of the API, we are going to deprecate several legacy fields ([see full list](/guide/migration/migration-to-v1.2.0#3-deprecated-fields)).
**Timeline**
We will maintain the current API logic until July 9, 2024. After this date, previous versions will no longer be supported. We kindly ask our users to update their integration before that day to avoid any potential breaking change.
[Learn more](/guide/migration/migration-to-v1.2.0)
## Minimum plan commitment ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
When creating a plan, defining a commitment ensures a minimum invoice amount for the billing period.
This minimum is calculated at the end of the period, taking into account the subscription fee and all usage-based charges. If the total amount invoiced is less than the minimum commitment, Lago will automatically apply a true-up fee.
The default commitment can be overridden when assigning the plan to a customer.
[Learn more](/guide/plans/commitment)

## ACH and BACS payments
Lago's native integration with Stripe supports two new payment methods:
* ACH Direct Debit for customers with a US bank account
* BACS Direct Debit for customers with a UK bank account
[Learn more](/integrations/payments/stripe-integration#supported-payment-methods)

## Grouping of charges
It is possible to group charges on the invoice according to a custom attribute. When creating a charge based on the standard pricing model, users can define one or several `grouped_by` attributes that will then be used to provide information on the distribution of usage.
For a customer who has sent thousands of API requests, for instance, we could display the breakdown of usage based on the `workspace_id` to which each request is linked.
[Learn more](/guide/invoicing/overview#custom-invoice-grouping)

## Updated Salesforce package ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to the Salesforce CRM integration.
This new package allows users to initiate actions in Lago without leaving the Salesforce interface. It includes two customizable flows:
1. Ability to automatically create Lago customers from Salesforce accounts
2. Ability to automatically create Lago subscriptions from Salesforce opportunities, including the option to override existing plans
[Learn more](/integrations/crm/salesforce-crm#iii-actions-from-salesforce-to-lago)
## Payment link for a specific invoice
We have added a new endpoint to generate checkout URLs for specific invoices.
This feature is available via integrations with Stripe and Adyen. It allows users to collect payments in countries where payment methods cannot be saved for future use.
[Learn more](/api-reference/invoices/payment-url)
## Wallet balance in (near) real-time ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
In addition to the invoiced balance, which represents the credit available in the wallet after the last invoice has been finalized, wallets include an ongoing balance, which takes into account the customer's current usage and taxes.
The ongoing balance gives an overview of the credit available in the wallet in near real-time, as it is updated every 5 minutes.
[Learn more](/guide/wallet-and-prepaid-credits/overview#real-time-wallet-balance)

## Edit draft invoices ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
When an invoice is in draft (i.e. during the grace period), fees can be modified via the user interface. Users can either:
* Overwrite the total number of units, in which case Lago will automatically recalculate the fee based on the pricing model associated with the charge
* Overwrite the number of units and unit price, in which case Lago will automatically recalculate the fee based on this information
[Learn more](/guide/invoicing/draft-invoices#edit-a-specific-fee)

## Multiple PSP accounts
If an organization has multiple accounts with the same PSP (e.g. US Stripe account and EU Stripe account) they can all be connected to Lago. Users can then select the most appropriate account to process payments for each customer.
[Learn more](/integrations/introduction)

## Batch endpoint
Events can now be sent in batches using the new `/events/batch` endpoint. Each API call may include up to 100 events.
[Learn more](/api-reference/events/batch)
## Disabling emails for invoices without fees
To avoid sending too many notifications to customers, we have deactivated emails for invoices without fees.
Although invoices with `"fees_amount_cents": 0` are no longer sent to customers by email, they are still available in the database and user interface.
[Learn more](/guide/emails#email-scenarios)
## Custom invoice numbering
We have made invoice numbering more flexible, with three elements:
* Prefix that can be customized
* Dynamic sequence, either based on sequential customer IDs, or based on year and month (i.e. YYYYMM)
* Sequential number of the invoice (i.e. 001, 002, 003, etc.)
[Learn more](/guide/invoicing/overview#invoice-numbering)

## EU tax management
Lago's EU tax detection feature allows users to check customers' tax identification numbers through integration with the European VAT Information Exchange System (VIES), and to automatically assign them a tax rate based on their country.
[Learn more](/integrations/taxes/lago-eu-taxes)

## Unit prices
PDF invoices now include details of charges for each pricing model (e.g. for graduated pricing, we display the number of units and unit price for each tier).
This information is also available in the invoice object (see `invoice.fees.amount_details`).
[Learn more](/api-reference/invoices/invoice-object)

## Automatic wallet top-ups ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
Customer wallets can be topped up automatically according to predefined rules:
* Based on a time interval (e.g. weekly, monthly, etc.)
* Based on a threshold (e.g. when the wallet balance is less than or equal to \$10)
[Learn more](/guide/wallet-and-prepaid-credits/wallet-top-up-and-void#setup-recurring-top-ups)

## Event validations
We have added an `events.errors` webhook message to notify users when some of the events ingested in the last hour are invalid.
Possible errors include:
* Invalid billable metric code
* Missing aggregation property
* Missing group key
[Learn more](/api-reference/webhooks/messages#event-ingestion)
## Regenerate checkout links
When a customer wants to update their payment method, or when a checkout link has expired, users can generate a new checkout URL on demand through the Lago API.
This action is available for all our native payment integrations.
[Learn more](/api-reference/customers/psp-checkout-url)
## Custom success URL
When setting up one of our native payment integrations, users can define the URL to which customers should be redirected after completing the checkout process. Custom URLs can only be added via the user interface.
[Learn more](/integrations/introduction)

## Default currency
The organization's currency can be defined in the settings of the account or via API. It is used as the default currency when creating new objects, such as plans and add-ons, and to display information on dashboards.
[Learn more](/api-reference/organizations/update)

## Helm chart updates
We have released a new version of the Lago Helm Charts to facilitate on-premise deployment.
[Learn more](https://github.com/getlago/lago-helm-charts)
## Integration with Salesforce CRM ✨
✨ This feature is only available via a paying add-on. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to the Salesforce CRM integration.
With the new Salesforce CRM integration, Lago data is automatically synced with Salesforce.
Users can access their customers' subscriptions, invoices and credit notes directly in their CRM application.
[Learn more](/integrations/crm/salesforce-crm)
## Removal of event validations
We are currently upgrading our infrastructure and setting up a new event ingestion system. As part of this project, we have decided to remove the validations that were automatically performed when ingesting events through the Lago API.
This means that the API no longer returns error messages when events include incorrect parameters (e.g. wrong billable metric code, subscription not found, `transaction_id` already exists, etc.).
## Retrieve a subscription
We have added a new endpoint to allow users to retrieve a specific subscription via the Lago API, using the `external_id` of the subscription.
[Learn more](/api-reference/subscriptions/get-specific)
## Webhooks for subscription upgrades/downgrades
When the plan associated with a subscription changes, Lago automatically notifies the user with two webhook messages:
* `subscription.terminated` to confirm the termination of the initial plan (includes `next_plan_code`)
* `subscription.started` to confirm the start of the new plan (includes `previous_plan_code`)
[Learn more](/api-reference/webhooks/messages)
## Plan details
In the Plans section of the app, users can now click one of their plans to see its details (i.e. name, code, interval, currency, subscription fee, usage-based charges, etc.) and also retrieve the list of subscriptions linked to the plan.
In addition, in the customer view of the app, users can click one of the subscriptions assigned to their customer to see its details (i.e. status, start date, interval, currency, fees, charges, etc.).

## Override plans ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
When assigning a plan to a customer, you can modify some attributes to create a custom plan. Editable fields include (but are not limited to):
* Currency
* Subscription fee
* Charge prices
* Minimum spending requirements
* Tax rates
* Invoice display names
Details of the new plan will be available in the customer view.
[Learn more](/guide/subscriptions/assign-plan#overriding-a-plan)

## Spanish locale
¡Hola a todos! The Spanish locale is now available on Lago.
Users can select it as their organization's default language or as a customer's preferred language.
[Learn more](/api-reference/resources/locales)
## Swedish locale
Hej alla! The Swedish locale is now available on Lago.
Users can select it as their organization's default language or as a customer's preferred language.
[Learn more](/api-reference/resources/locales)
## Display names on invoices
When creating or updating a plan, users can define custom display names for subscription and usage-based charges, which will be printed on the PDF files generated by Lago.
Display names can be defined via the user interface or the API (see `plan.invoice_display_name` and `charges.invoice_display_name`).
[Learn more](/guide/plans/charges/usage-based-charges#update-invoice-display-names)

## Retrieve past usage
We have added a new endpoint to retrieve past usage. When a billing period has ended, users can still retrieve usage data through `GET /customers/{external_customer_id}/past_usage`.
Users must specify `external_subscription_id` and can filter results by `billable_metric_code`. They can also select the number of past periods for which they wish to retrieve usage data.
[Learn more](/api-reference/customer-usage/get-past)
## LATEST aggregation
`latest_agg` allows users to compute usage based on the last value received during the period for a billable metric.
Consider the following example for the `storage` metric, where usage is aggregated based on the property `gb`:
* The first event includes 5 GB
* The second event includes 7 GB
* The third event includes 6 GB
With `latest_agg`, at the end of the billing period, the total number of units used to calculate the fee will be 6, as it's the last value received.
[Learn more](/guide/billable-metrics/aggregation-types/latest)

## WEIGHTED SUM aggregation
`weighted_sum_agg` allows users to compute usage based on a custom property and the time elapsed between two events (e.g. memory consumption measured in GB-seconds).
Billable metrics based on this aggregation type can be metered or recurring, and are always billed at the end of the billing period.
[Learn more](/guide/billable-metrics/aggregation-types/weighted-sum)
## Subscription end date
When a subscription end date is set, the subscription is automatically terminated by Lago.
A notification is sent to the user 45 days and 15 days before the subscription is terminated (see `subscription.termination_alert` webhook).
If no end date is set for a subscription, it will renew automatically.
[Learn more](/guide/subscriptions/assign-plan#subscription-end-date)
## Duplicate plans
Users can duplicate an existing plan from the user interface to create a new plan with the same structure. They can then choose a name and a code for their new plan, and modify the parameters that differ from the original plan (e.g. interval, currency, charges, etc.).

## Edit dimensions
When dimensions are defined for a billable metric, users can add/remove groups by modifying the corresponding code snippet via the user interface, or by updating the billable metric object via API.
Changes to dimensions may affect all plans where the billable metric is listed as a charge.
[Learn more](/guide/billable-metrics/filters)
## Default price for groups
For billable metrics that include several [groups](/guide/billable-metrics/filters), when configuring their plans, users can set a default price that applies to all groups.
The default price can be overwritten by setting a different price for a specific group.
If the default price is not defined, it is automatically set to zero.
[Learn more](/guide/invoicing/overview#custom-invoice-grouping)

## Italian locale
Ciao a tutti! The Italian locale is now available on Lago.
Users can select it as their organization's default language or as a customer's preferred language.
[Learn more](/api-reference/resources/locales)
## Minimum / Maximum per transaction ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
The percentage pricing model includes a new option for defining minimum and maximum prices per transaction.
When applied, Lago adjusts the fees based on the `per_transaction_min_amount` and `per_transaction_max_amount` parameters.
[Learn more](/guide/plans/charges#available-charge-models)

## Webhook for subscriptions started
We have added a new webhook message for subscriptions.
When the status of a subscription switches to `active`, Lago automatically sends a `subscription.started` message.
[Learn more](/api-reference/webhooks/messages)
## Graduated percentage pricing
We have added a new graduated pricing model, which allows users to define prices based on a percentage of the number of units, and to add a flat fee for each tier (optional).
[Learn more](/guide/plans/charges#available-charge-models)

## Quarterly billing interval
In addition to the weekly, monthly and yearly intervals, Lago `v0.44.1-beta` includes the new quarterly interval.
When selected, all fees (i.e. subscription fee and charges) are billed every three months.
[Learn more](/guide/plans/plan-model#plan-interval)

## Webhook signatures
When creating a webhook endpoint through the user interface or the API, you can choose between:
* The original `JWT` signature
* The new `HMAC` signature, which includes a shorter header
Please refer to the guide to find out how to verify the webhook signatures.
[Learn more](/api-reference/webhooks/format---signature)

## Taxes applied to add-ons
Tax objects can now be used to define the default tax rate(s) associated with an add-on.
When creating a one-off invoice, if there is no tax rate associated with the add-on, Lago will automatically select the tax rate defined at customer or organization level.
The tax rate applied to the add-on can be modified at any time through the user interface or the API.
[Learn more](/guide/invoicing/invoicing-settings/taxes#taxes-at-the-add-on-level)

## Net payment term
The net payment term determines the number of days given to the customer to pay their invoice. It is calculated based on the date the invoice is finalized and displayed on the PDF file.
When the net payment term is defined at the organization level, it applies to all customers by default. However, it can be overridden by the net payment term defined at the customer level.
[Learn more](/guide/invoicing/invoicing-settings/net-payment-term)

## Taxes defined at plan and charge level
In addition to the taxes defined at organization and customer level, users can select tax objects at plan and charge level.
For subscription invoices, the tax hierarchy is as follows:
1. Taxes defined at **organization level** will apply to all fees (i.e. subscription and charges)
2. Taxes defined at **customer level** will take precedence over taxes defined at organization level and will apply to all fees (i.e. subscription and charges)
3. Taxes defined at **plan level** will take precedence over taxes defined at customer level and will apply to all fees (i.e. subscription and charges)
4. Taxes defined at **charge level** will take precedence over taxes defined at plan level but will only apply to the fee associated with the corresponding charge
[Learn more](/guide/invoicing/invoicing-settings/taxes)
## Filter subscriptions by status
We have added a new query parameter to the endpoint that allows users to retrieve subscriptions.
By default, `GET /api/v1/subscriptions/` returns all active subscriptions. However, you can also retrieve pending, canceled and terminated subscriptions by using the `status` parameter.
[Learn more](/api-reference/subscriptions/get-all)
## SEPA Direct Debit with Stripe
Our native integration with Stripe now supports SEPA Direct Debit payments.
When Stripe is defined as the default payment provider for a customer, you can select the authorised payment method(s): card, direct debit or both.
Before initiating a payment intent, Lago will automatically check the customer's default payment method registered in Stripe.
Kindly note, SEPA Direct Debit is only available for invoices denominated in euros (EUR).
[Learn more](/integrations/payments/stripe-integration#payment-methods)
## Recurring and prorated charges
When a billable metric is defined as [recurring](/guide/plans/charges#metered-vs-recurring-charges), the number of billing units at the end of the billing period is carried over to the next period. It is not reset to zero, as with metered metrics.
Users can create recurring metrics based on `sum_agg` and `count_unique_agg`. They can also define whether the corresponding charges should be [prorated](/guide/plans/charges#prorated-vs-fully-billed-charges) (this option is only available for the standard and volume pricing models).
ℹ️ Metrics based on `recurring_count_agg` have been automatically converted into `count_unique_agg` metrics with the attribute `"recurring": true`.

## Cancel pending subscriptions
When a subscription is created with a subscription date in the future, its status is automatically set to `pending`.
You can now cancel a pending subscription through the Lago API, using the following endpoint:
`DELETE /api/v1/subscriptions/{external_id}?status=pending`
[Learn more](/api-reference/subscriptions/terminate)
## Multiple webhook endpoints
Webhook messages can be used to collect billing information and set up custom workflows. They are related to subscriptions, events, fees, invoices, payment providers and credit notes.
You can now create up to five webhook endpoints to listen to Lago events.
[Learn more](/guide/webhooks)
## Custom tax objects
In the settings of their account, users can define the default tax rate that applies by default to all customers of their organization. This tax rate can then be overwritten at the customer level.
Whether set at the organization level or the customer level, so far the tax rate used to calculate fees was simply indicated as "Tax" on invoices.
To give users more flexibility, we've added the option to create several tax objects, which can then be assigned to the organization or specific customers (e.g. state sales tax, VAT, reverse charge, GST, etc.).
[Learn more](/guide/invoicing/invoicing-settings/taxes)
## Stripe checkout URL
When a new customer is successfully created through Lago's native integration with Stripe, the billing system sends a `customer.checkout_url_generated` webhook message.
You can redirect your customer to the corresponding page to register their payment method, which will then be used to collect payment when a new invoice is issued.
[Learn more](/integrations/payments/stripe-integration#stripe-checkout-storing-customers-payment-method-information)
## Tax identification number
The [customer object](/api-reference/customers/object) and [organization object](/api-reference/organizations/organization-object) include a new `tax_identification_number` attribute. When a value is available for this attribute, it is automatically displayed on the PDF version of the next invoices.
## Integration with GoCardless
Lago now offers native integration with [GoCardless](https://gocardless.com/), including (but not limited to):
* Ability to define GoCardless as the default payment provider for a customer
* Ability to automatically create Lago customers in GoCardless and retrieve their customer ID
* Ability to automatically collect payments via direct debit
* Ability to automatically update the status of an invoice depending on the payment status
* Ability to automatically resubmit failed payments with [GoCardless Success+](https://gocardless.com/solutions/success-plus/)
To learn more about this integration, please [consult our guide](/integrations/payments/gocardless-integration)
## Minimum spend on charges ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
You can now define minimum spending requirements for usage-based charges.
The minimum spend is defined as an amount excluding tax. If at the end of the billing period, your customer has spent less than the minimum, then Lago will automatically generate a true-up fee to compensate for the difference.
Minimum spending requirements are defined when creating or editing plans, either through the user interface or the API.
[Learn more](/guide/plans/charges#charge-spending-minimum)
## Coupons limited to specific metrics
We have added a new option to the coupon settings: it is now possible to limit the application scope of a coupon to specific billable metrics.
By default, coupons apply to all charges but when creating a new coupon, you can define the list of billable metrics to which the coupon applies.
This feature is related to the `billable_metric_codes` attribute of the `coupon` object ([see API documentation](/api-reference/coupons/create)).
Please refer to [the guide](/guide/coupons) for more information on coupons.

## Reset password
You can now reset your password via the user interface.
On the login page, click "Forgotten password" to access the dedicated page where you can request a link to reset your password.

## Automatic emails ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
We are introducing a new built-in invoicing feature, which allows you to automatically send invoices and credit notes from Lago to your customers.
The email template can be customized with the name, email address and logo of your organization, and will be sent in the customer's preferred language (or the default language defined in the settings of your account).
For cloud users, Lago takes care of the SMTP setup. For users on the self-hosted version, the setup is described in the public documentation.
[Learn more](/guide/emails)
## Customer billing portal ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
We have released the first version of our billing portal, which allows your customers to access their invoices.
You can generate access links through the user interface or embed the customer portal into your application using our API and an iframe.
[Learn more](/guide/customers/customer-portal)
## Invoice metadata
After an invoice has been generated, you can add metadata to store additional information (e.g. custom ID, payment reference, etc.). This information will be included in the `invoice` object but will not be displayed on the PDF invoice.
Invoice metadata can be managed via the user interface or the API.
[Learn more](/guide/invoicing/invoice-metadata)

## Customer metadata
When creating or editing a customer, you can add metadata to store additional information (e.g. customer type, name of the account manager, etc.).
Customer metadata can be displayed on invoices, and can be managed via the user interface or the API.
[Learn more](/guide/customers/customer-metadata)

## Webhook logs
The new webhook management system allows you to access the list of webhook messages sent by Lago and check their status. You can re-trigger a message that has failed through the user interface.
To access the webhook logs:
1. Go to the **Developers** section via the sidebar
2. Open the **Webhooks** tab
3. Click on the webhook endpoint to see the list of messages
[Learn more](/guide/webhooks)

## Document translation
PDF files including invoices and credit notes can be generated in different languages.
The [default language](/guide/invoicing/download-invoices#translate-invoices) that is set at the organization level can be overwritten by the [customer's preferred language](/guide/customers/invoice-customer#preferred-language).
In the API, the `document_locale` attribute determines the language of the documents.
You can contribute to Lago's open-source project by helping us translate documents. The new language will then be added to the [list of supported locales](/api-reference/resources/locales) and available to the entire Lago Community.
## Update payment status
You can now update the payment status of an invoice through the user interface.
To do so:
1. Access the **Invoices** section
2. Find the relevant invoice
3. Click the ellipsis icon on the right
4. Click **Update payment status**
5. Select the new payment status
6. Click **Update status** to confirm
This action can be performed [via the API](/api-reference/invoices/update) as well.

## Coupons limited to specific plans
We have added a new option to the coupon settings: it is now possible to limit the application scope of a coupon to specific plans.
By default, coupons apply to all plans but when creating a new coupon, you can define the list of plans to which the coupon applies.
This feature is related to the `plan_codes` attribute of the `coupon` object ([see API documentation](/api-reference/coupons/create)).
Please refer to [the guide](/guide/coupons) for more information on coupons.

## Coupons that apply forever
When creating a coupon, through the [user interface](/guide/coupons) or the [API](/api-reference/coupons/create), it is now possible to select the `forever` frequency.
Coupons with the `forever` frequency apply to all subscription invoices, regardless of the number of subscription invoices generated in a given period.
ℹ️ The value of the coupon is deducted from the amount of the invoice after tax. Coupons do not apply to add-ons or any other one-off charges.

## Search bar
Tired of scrolling through an endless list to find the customer your are looking for? We understand that.
We have added a search functionality to the user interface to make it easier to find metrics, plans, customers, invoices, etc.

## Payment retries
We have added the ability to resend payments for collection.
This new feature is available to all users:
* Through the user interface ([learn more](/guide/payments/payment-retries))
* Through the API ([learn more](/guide/payments/payment-retries))

## Grace period ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
If at the end of the billing period, you want to review the invoices before sending them to customers for payment, you can define a [grace period](/guide/invoicing/invoicing-settings/grace-period).
During the grace period, invoices are in `draft` status and can be modified. Available actions include:
* **Adding usage records** by sending events with a `timestamp` within the relevant billing period
* **Applying coupons** to the customer's account
* **Adding credits** to the customer's wallet and credit note wallet
When the grace period expires, invoices are automatically `finalized` (they can no longer be edited), which triggers the `invoice.created` [webhook](/api-reference/webhooks/messages). You can also finalize invoices manually.
The organization's grace period applies to all customers by default, but it can be overwritten by the customer's grace period.
## Invoice list
We have added a new **Invoices** section, which allows you to access the list of invoices.
Invoices are filtered according to their status (i.e. draft or finalized) and according to their payment status (i.e. succeeded, pending or failed).
The same filters can be applied when [retrieving invoices via the API](/api-reference/invoices/get-all).

## Credit notes ✨
✨ Lago may automatically generate a credit note when a subscription is upgraded or downgraded. However, only users with a premium license can manually generate credit notes via the user interface or the API. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
You can now use your Lago account to issue credit notes for subscription invoices and add-ons.
Depending on the payment status of the invoice, you will be able to:
* **Refund the customer** (only for paid invoices)
* **Credit back the customer's account**
Please refer to the [documentation](/guide/invoicing/credit-notes/overview) for more information on credit notes and credit methods.
## Timezones ✨
✨ This feature is only available to users with a premium license. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
You can now set the timezone of your organization in the settings of the app. To do so:
1. Access the **Settings** section via the side menu
2. In the **Organization** tab, you will see the current timezone (UTC by default)
3. Click **Edit**
4. Select a new timezone from the list
5. Click **Save timezone** to confirm
It can also be set through the API using this [endpoint](/api-reference/organizations/update).
The organization's timezone applies to all customers by default and determines when billing periods start and end (i.e. when invoices should be generated). It is also the reference timezone for most views and lists in the app.
The organization's timezone can be overwritten by the customer's timezone ([learn more](/guide/customers/invoice-customer#bill-following-your-customers-timezone)).
ℹ️ In the app, you can hover over any date with a dotted underline to see the reference timezones.
## Lago Open API
We have developed an Open API to help you get started with Lago and make it easier to test our solution.
Please refer to the [documentation](/guide/lago-open-api) to learn how to import the Lago Open API into Postman and create a new collection.
Our [public repository](https://github.com/getlago/lago-openapi) is also available on GitHub.
## Apply several coupons
You can now apply several coupons to a customer account.
When several coupons are applied to a customer, they will be deducted according to the date on which they were applied: the coupon that was applied first will be deducted first.
The remaining value / number of remaining periods for each coupon will be visible in the **Overview** tab of the customer view.
You can also use `GET /api/v1/applied_coupons` to retrieve all coupons applied to a customer.
## Invoice details
To review the invoice details through the user interface:
1. Go to the **Customers** section
2. Select a customer to open the customer view
3. Open the **Invoices** tab
4. Click the invoice to see its details
On the details page, you can download the invoice in PDF format and copy the invoice ID through the **Actions** dropdown in the upper right corner.

## Integration with GoCardless
Lago now offers native integration with [GoCardless](https://gocardless.com/), including (but not limited to):
* Ability to define GoCardless as the default payment provider for a customer
* Ability to automatically create Lago customers in GoCardless and retrieve their customer ID
* Ability to automatically collect payments via direct debit
* Ability to automatically update the status of an invoice depending on the payment status
* Ability to automatically resubmit failed payments with [GoCardless Success+](https://gocardless.com/solutions/success-plus/)
To learn more about this integration, please [consult our guide](/integrations/payments/gocardless-integration).
## Subscription date
It is now possible to set a start date in the past or in the future for a new subscription.
Setting a start date in the past can be useful when migrating existing customers to Lago, while setting a start date in the future can be useful for scheduling upcoming subscriptions.
For more information about the impact of the start date on the invoicing process, please refer to [the documentation](/guide/subscriptions/assign-plan#subscription-date).
## Dimensions for grouping events
When creating a new billable metric, you can define dimensions that will be used to group events according to their properties.
For example, if you want to charge your customers for compute capacity according to the cloud provider and server region, you can create a `compute` billable metric with two dimensions ([learn more](/guide/billable-metrics/filters)).
Changes to the API include:
* Ability to add a `group` parameter with one or two dimensions when [creating](/api-reference/billable-metrics/create) or [updating](/api-reference/billable-metrics/update) billable metrics
* Ability to add a `group_properties` parameter when [creating](/api-reference/plans/create) or [updating](/api-reference/plans/update) a plan
* Ability to retrieve [customer usage](/api-reference/customer-usage/customer-usage-object) by group
* New `lago_group_id` for fees (see [invoice object](/api-reference/invoices/invoice-object))
## Enhanced coupon model
We have improved the coupon model to offer more flexibility.
Changes include (but are not limited to):
1. Ability to define the value of a coupon as a fixed amount or percentage
2. Ability to create recurring coupons that apply over several billing periods
3. Ability to set an expiration date (i.e. date after which the coupon can no longer be redeemed)
[Learn more](/guide/coupons)
## Customer currency
It is now possible to define the currency at [customer](/api-reference/customers/object) level.
The currency associated with each customer was previously defined by the currency of the plan assigned to the customer. This logic prevented users from assigning a coupon or an add-on to a customer before creating a subscription.
When creating a new customer via the user interface or the API, you can now select the currency associated with the customer. If the currency is not defined at customer level, it will be determined by the first object assigned to the customer (i.e. currency of the plan, add-on, coupon, or wallet).
⚠️ Once an object has been assigned to the customer (i.e. plan, add-on, coupon, or wallet), the currency associated with the customer cannot be changed.
## Error management
We have refactored the error management system to give more visibility to API users.
The `message` attribute for errors has been replaced with `code` and `error_details`, which provide more information about the errors. There are several codes associated with each error.
For example, when creating a new billable metric, the API may return `"error": "Unprocessable entity"` with the code `value_is_mandatory` for the `name` field (i.e. the name of the billable metric is missing).
Please refer to the [documentation](/api-reference/intro) available for each endpoint for more information on error codes.
## Invite members
You can now invite your teammates to join your Lago account.
To add a new member via the user interface:
1. Go to the **Settings** section of the app
2. Open the **Members** tab
3. Click **Invite a member** on the right
4. Enter the email address of your teammate
5. Click **Generate invitation link** to confirm
6. Copy the invitation link to share it with your teammate
Invitation links have no expiration date. When your teammate clicks the link, they can choose their password and then access the account.
You can remove a member by clicking the **bin icon** on the right of the list of members.
ℹ️ All members have the same role and permissions.
## Overwrite plans
If after a negotiation phase, you need to create a custom plan for an important customer, you can use the 'overwrite' feature, available through the user interface.
This feature allows you to create a new plan from an existing one, in order to adjust the plan model and charges according to your business needs.
Overwriting a plan has no impact on the original plan or existing subscriptions.
[Learn more](/guide/subscriptions/assign-plan#overwriting-a-plan)
## Recurring count
Companies with fair and transparent pricing models are often praised by customers. If you are considering implementing seat-based pricing for instance, the `reccuring_count` aggregation is exactly what you need.
This new aggregation type allows you to push events for persistent units.
Consider the following example:
> Your customer is on a monthly plan and adds a new user to their account on September 15th, so you generate an event that corresponds to one billing unit.
>
> At the end of September, Lago will automatically create a prorated charge for this user, based on the number of days of activity (i.e. from September 15th to September 30th).
>
> This billing unit will remain valid until you generate another event to remove it. For instance, if your customer deletes the user on October 22nd, Lago will create another prorated charge for the period October 1st to October 22nd.
Consult [our guide](/guide/billable-metrics/recurring-vs-metered) to learn more about persistent units.
## External IDs
We are introducing changes to the API that will make it easier to manage subscriptions:
* For the [creation of new subscriptions](/api-reference/subscriptions/assign-plan), `subscription_id` and `unique_id` will be removed and replaced with `external_id` (required)
* For all other endpoints, `subscription_id` will be replaced with `external_subscription_id`
This will allow you to operate via the API using your own identifiers and save you the trouble for storing our IDs.
In addition to this, for consistency purposes:
* For the [creation of new customers](/api-reference/customers/create), `customer_id` will be replaced with `external_id`
* For all other endpoints, `customer_id will be replaced with `external\_customer\_id\`
These changes will come into effect on **September 8, 2022**.
Please [get in touch](https://www.getlago.com/slack) with our team if you have any questions.
## Volume charge model
The new volume charge model allows you to create a tiered pricing structure and then calculate a unit price that applies to all units depending on total volume.
It is similar to the graduated charge model, except that only one price tier applies at the end of the billing period.
Please refer to [the guide](/guide/plans/charges#charge-models) and [API documentation](/api-reference/plans/create) for more information.
## Anniversary dates for subscriptions
When assigning a plan to a customer, you can now choose whether the subscription should be renewed at the beginning of the period or on its anniversary date.
For instance, if a monthly plan is assigned to a customer on August 10th and you choose to align the billing cycle with the anniversary date of the subscription, the customer will be billed every 10th of the month.
With [the API](/api-reference/subscriptions/assign-plan), you can use the `billing_time` attribute to choose your preferred option. If not provided, Lago will base the subscription on calendar periods.
[Learn more](/guide/subscriptions/assign-plan#billing-cycles)
## Free units for the percentage charge model
We have released an enhanced version of the percentage charge model, including:
* Ability to define free units based on the number of events (e.g. first 3 events are free)
* Ability to define free units based on the total amount (e.g. first \$500 are free)
Please refer to the [documentation](/guide/plans/charges#charge-models) for more information.
## Multiple plans
It is now possible to assign multiple plans to a customer (e.g. if your customer needs to create several workspaces on your platform, you can link a plan to each workspace).
To help differentiate each plan, you can add display names that will appear in the user interface and on invoices.
Kindly note that:
1. All plans must be denominated in the same currency
2. You must now specify the `subscription_id` for each event or create batch events
[Click here to see the documentation](/guide/subscriptions/assign-plan#multiple-plans)
## Tracking & Analytics
To help us better understand your needs, we have added a tracking module to the self-hosted version of Lago.
Data analytics will help us improve the quality of our product and performance of the API.
As the privacy of our users is of paramount importance, we will not collect any personal information about your customers or the amount of your invoices, and you can opt out at any time.
[Learn more](/guide/lago-self-hosted/tracking-analytics)
## Go client
We have added a new API client to make it easier for Go users to set up their billing system with Lago.
[Click here to see the documentation](/api-reference/intro)
## App version
It is now possible to check the version of the Lago application you are using.
Click on of your `organization's name` in the top-left corner of the user interface to see the app version currently in use.

## Current usage
Good news for those who follow closely the consumption of their customers. You can now track the current billing usage of your customers either from the UI or from the API.
**To access this Usage tab:**
1. Access your list of **customers**
2. Select a specific customer that is **already linked to a subscription**
3. Access the **usage** tab
4. Get a complete view of **usage-based consumption** that is going to be billed on the next invoice
On top of that, you can fetch the current usage of a customer directly from the API. To do so, you can access the following endpoint `GET /api/v1/customers/:customer_id/current_usage`

## PDF invoices
Lago will generate a PDF file for each new invoice.
You can download invoices via the user interface or the API and can also modify some of the elements included in the invoice template.
Full documentation [available here](/guide/invoicing/download-invoices).
## New API endpoints
We like our users when they use our nice and clean UI, but we also love when they use our API. One of the usecase could be to use Lago as a white-labeled solution.
Here is the full list of endpoints we have just released:
**Billable metrics**
* Create a billable metric `POST /api/v1/billable_metrics`
* Update a billable metric `PUT /api/v1/billable_metrics/:code`
* Destroy a billable metric `DELETE /api/v1/billable_metrics/:code`
* Fetch a specific billable metric `GET /api/v1/billable_metrics/:code`
* Fetch all billable metrics `GET /api/v1/billable_metrics?per_page=2&page=1`
**Plans**
* Create a plan `POST /api/v1/plans`
* Update a plan `PUT /api/v1/plans/:code`
* Destroy a plan `DELETE /api/v1/plans/:code`
* Fetch a specific plan `GET /api/v1/plans/:code`
* Fetch all plans `GET /api/v1/plans?per_page=2&page=1`
**Coupons**
* Create a coupon `POST /api/v1/coupons`
* Update a coupon `PUT /api/v1/coupons/:code`
* Destroy a coupon `DELETE /api/v1/coupons/:code`
* Fetch a specific coupon `GET /api/v1/coupons/:code`
* Fetch all coupons `GET /api/v1/coupons?per_page=2&page=1`
**Add-ons**
* Create a add\_on `POST /api/v1/add_ons`
* Update a add\_on `PUT /api/v1/add_ons/:code`
* Destroy a add\_on `DELETE /api/v1/add_ons/:code`
* Fetch a specific add\_on `GET /api/v1/add_ons/:code`
* Fetch all add\_ons `GET /api/v1/add_ons?per_page=2&page=1`
**Current usage**
* Get the current usage of a specific customer `GET /api/v1/customers/:customer_id/current_usage`
**Organization**
* Update the information of your organization `PUT /api/v1/organizations`
## Integration with Stripe Payments
Lago now offers native integration with Stripe, including (but not limited to):
* Ability to create Lago customers in Stripe automatically and retrieve their customer ID
* Ability to define Stripe as the default payment provider for a customer
* Ability to generate payment intents automatically
* Ability to update the status of an invoice depending on the payment status
* Ability to receive a webhook when a payment fails
To learn more about this integration, please [consult our guide](/integrations/payments/stripe-integration).
## Weekly plan interval
When setting up a plan, you can select the weekly interval to define a weekly billing period.
The plan interval applies to the subscription and charges, which means that:
* For plans that must be paid in advance, the subscription fee is invoiced at the beginning of the week
* For plans that are paid in arrears, the subscription fee is invoiced at the end of the week
* Usage is calculated at the end of each week
The week starts on Monday and ends on Sunday. If the customer's subscription starts in the middle of the week, the fees will be applied on a pro-rata basis.
## Invoice monthly charges for a plan paid yearly
Before the release of this feature, usaged-based features (charges) were following the plan period. If the plan period was invoiced yearly, the charges were invoiced yearly.
It's now possible to **invoice billable metrics on a montly basis** for a plan billed yearly. The base amount of the plan will be invoice yearly (in-arrears or in-advance), but your usage based features will be invoiced on a monthly basis.
**To do so:**
1. Access a **Plan**
2. Define a plan **yearly**
3. Price **additional charges** from your billable metrics
4. Turn `on` the toggle for **applying charges monthly**
By switching on, **all the charges** will be invoiced monthly even if the plan is yearly.
ℹ️ The last invoice is gathering both the subscription and the usage-based charges
## Events list
You are now able to view all the ingested events sent from your application to Lago. We called this feature `Events list` because it makes the event ingestion easier and more understandable.
1. Access the `Developer` sidebar item
2. Click the `Events` tab
3. Take a look at the latest events ingested
ℹ️ If an event you sent is not shown in the UI, it means that it has not been ingested by Lago
This events list is also helpul to warn you for 2 specific cases:
1. **Warning 1** - The event code is not related to an existing billable metric
2. **Warning 2** - The property sent does not match the aggregation property defined in your billable metric

## Add-ons
Add-ons are now available on Lago. Create add-ons to apply one-time fees (e.g. setup fee, one-time purchase, etc.) and generate the corresponding invoices instantly.
Full documentation [available here](/guide/one-off-invoices/create-add-ons).
## Pay-as-you-go template
We've added a new template to our collection: [click here](https://www.getlago.com/resources/templates/algolia) to learn how to replicate Algolia's pay-as-you-go pricing.
It's a great starting point for companies whose pricing fully depends on usage, such as cloud service providers and API companies.
With Lago, you can adapt this template to your products and services, using some of our most popular features, including the ['sum' aggregation type](/guide/billable-metrics/aggregation-types) and the [package charge model](/guide/plans/charges#charge-models).
## Coupons
Introducing coupons, a new feature that allows you to offer discounts to your customers.
Full documentation [available here](/guide/coupons).
## Subscription changes
You can now modify the subscription assigned to a customer through the user interface.
To learn how to upgrade or downgrade a subscription and how it affects billing, please refer to the documentation.
## Package pricing for charges
It is now possible to apply a [package pricing model](/guide/plans/charges#charge-models) to a charge. To do so:
1. Select an existing plan (or create a new one)
2. Add a charge
3. Select the package pricing model
This new pricing model allows you to apply a flat fee to a range of units. The price will be fixed for the entire range, regardless of the number of units consumed by the customer during the billing period.
## Percentage charge model
Inside the **plan**, when creating a charge, you can now select the **percentage charge model**.
This feature is useful for industries willing to take a `% + fixed fee` out of a usage-based features (for banking or charity industry, for instance). These fees are applied on the *units to be charged* (e.g. the aggregation result of your billable metric).
# About Lago
Source: https://getlago.com/docs/faq/about-lago
## 1. What is Lago?
[Lago](https://www.getlago.com/) is the leading open-source pricing solution focused on complex billing: multi-product/geographies, transactional, usage-based, subscription hybrids, etc, chosen by unicorns like Mistral (AI, \$13.7 billion valuation), Accel-backed Swan (Embedded banking), or Groq (AI, \$6.9 billion valuation).
Lago is API-first, the most loved billing solution on Github, and was voted Product of the Day, Week, and Month on Product Hunt.
Lago raised a total of [\$22M of funding](https://techcrunch.com/2024/03/14/lago-a-paris-based-open-source-billing-platform-banks-22m/) from investors including Y Combinator, FirstMark Capital, SignalFire, [Meghan Gill](https://www.linkedin.com/in/meghanpgill/), who has led the monetization efforts of MongoDB for 14 years, [Romain Huet](https://www.linkedin.com/in/romainhuet/), former head of Developer Relations at Stripe - now leading OpenAI developer experience, and [Clément Delangue](https://www.linkedin.com/in/clementdelangue/), CEO of AI open platform Hugging Face.
## 2. What does Lago do?
Lago helps businesses calculate how much their end-users need to pay, and make sure they’re paid.
This includes, but is not limited to:
* Managing subscriptions
* Metering consumption, or usage (e.g., for a telco provider: the number of minutes of a call ; for an electricity provider: the number of kWh used)
* Generating and sending invoices
* Triggering and tracking payments
* Managing customers’ accounts
**Features overview:**
Real-time metering for flexible pricing.
Billing & invoicing without the headaches.
Entitlements managed directly in billing.
Flexible cash collection for hybrid billing models.
Revenue analytics you can trust, across every stream.
White-label billing for platforms and ecosystems.
AI-powered billing intelligence.
Enterprise billing integrations that scale with you.
Check our documentation [here](/guide), for more information.
Reproduce Notion, Slack, or Stripe’s pricing in a few clicks with our templates [here](/templates/introduction).
## 3. What is Lago origin story?
Lago was founded in 2021 by Anh-Tho and Raffi, who were among the earliest employees at Qonto.com – a \$5B B2B neobank. They led Qonto's revenue growth from pre-product to Series D, and built and scaled the monetization system that took the company from 0 to \$100M+ of revenue.
A fun fact was that when Raffi pitched the idea of Lago to Romain (a senior billing engineer at Qonto), he told him “no way”, and said he did want to quit his position at Qonto but he would “NEVER touch a billing system again”.
Step by step, Raffi managed to convince him he could channel this energy and experience to make sure fewer engineers would need to relive the billing nightmares he had to endure. And it worked!
At Qonto, they would always underestimate the engineering nightmare billing would create, and learned the hard way about the side effects: delayed launches at best, billing errors, resulting in churning users, and a growing “billing engineering” team that not only was expensive, but very hard to retain. The worst was that at some point, the “pricing strategy” nearly switched to “what’s the easiest option to implement”, rather than “what’s the best for the company”.
Raffi and Anh-Tho, and the founding Lago team then spent a lot of time carefully analyzing why no one had solved this huge problem yet, as they thought solid companies like Stripe or Chargebee had partially addressed it.
That’s how they built our conviction on the open-source and “platform” approach of Lago, to not be another “buy billing” option, but rather a “Lego '' that engineers build with to create their tailored monetization stack.
## 4. Does it work with my stack?
Yes. Lago is agnostic and can be used via:
* Our no-code interface, see it in action [here](https://youtu.be/dXnoMRetsr4)
* Our [API](/api-reference)
* Our native integrations: Segment, Hightouch, Stripe Payments, Adyen, Salesforce, and many others, [here](https://www.getlago.com/integrations)
* One of our [backend libraries](/api-reference) covering the main programming languages and tools
You can use Lago with your stack, whatever it is.
## 5. Is this supported properly?
Lago is a well funded project with thousands of stars on [Github](https://github.com/getlago/lago), in [very active development](https://github.com/getlago/lago-api/graphs/commit-activity), by our [core team](https://www.getlago.com/about-us) and our active community.
Additionally, we have strong uptime performance ([99,99%+ uptime](https://status.getlago.com/)) and \<10 min median response time across support channels.
# About the software
Source: https://getlago.com/docs/faq/about-software
## 1. How popular is the software?
Lago has thousands of users, thousands of stars on Github and great investors.
Lago is the most popular open-source repository solving for billing on Github, to give you a point of reference, the second most popular one was started ten years ago, Lago caught up fast!
It has been chosen by companies like:
* [Mistral.ai](http://Mistral.ai) – the open source genAI model provider, which raised more than \$600M with top VC ([see here](https://techcrunch.com/2024/06/11/paris-based-ai-startup-mistral-ai-raises-640-million/?guccounter=1)).
* [Groq](https://groq.com/) – the startup building AI-chip for fast inference, which raised more than \$640M from top VC ([see here](https://techcrunch.com/2024/08/05/ai-chip-startup-groq-lands-640m-to-challenge-nvidia/))
* [Juni](https://www.juni.co/) – the fintech company that develops a banking app for e-commerce.
* [Swan](https://swan.io) – the leading European Banking-as-a-Service (BaaS), backed by Accel and Creandum.
and many more.
To hear firsthand experiences from our users, explore Lago's [customer stories](https://www.getlago.com/customers/stories) and our [love wall](https://shoutout.io/lago).
## 2. Is the software updated regularly?
We release new versions every 2-3 weeks, our team is working relentlessly to improve the product.
Sign up to our newsletter, or follow us on [Linkedin](https://fr.linkedin.com/company/getlago) or [X](https://twitter.com/getlago?lang=en) (fka Twitter).
Our past product updates are [here](https://www.getlago.com/resources/updates).
## 3. How secure is Lago?
Keeping your data secure is critical to how Lago operates. Lago is SOC 2 Type 2 compliant. SOC 2 compliance ensures the secure storage and transmission of data. Type 2 compliance tests the design and effectiveness of the systems over a long period of time.
To protect access to and transmission of your data, Lago supports Single Sign-On (SSO) and Role-based access control (RBAC). SSO allows you to centrally manage your access and RBAC policies define how users interact with Lago, giving you the chance to minimize security vulnerability.
Learn more about security at Lago [here](/guide/security/rbac).
## 4. How is this different from the other billing tools?
A lot of companies continue building billing in-house, even if it means building systems that engineers hate to build, let alone maintain.
Lago has been conceived to address complex billing use cases, with a unique open-source approach, solving for:
* Transparency: you can inspect our code, have an overview on our pull requests, github issues, what our users say and how they use Lago.
* Control: you can opt for the convenience of Lago Cloud (our hosted solution) or choose the total control that our on-premise deployment offers: keep your data within your own system, and keep a direct access to all your usage, billing and payment data in your own infrastructure, with the highest level of granularity.
* Extensibility and connectivity: because engineers understand our code and infrastructure better.
Lago is the only open source metering and usage-based billing solution. A lot of closed source (aka ‘SaaS’) solutions exist (e.g., Stripe Billing, Zuora) but they require you to send your data to third-parties, to blindly trust a Chargebee‘black box’ with your most critical internal system (billing / revenue).
There are multiple open source billing offerings. However, Lago is the only open source software that gives you:
1. Real-time event-based usage metering
2. Subscription billing
3. Hybrid plans, mixing subscription and consumption (e.g., a usage-based billing plan that requires a recurring minimum spend per month)
4. A full fledge API to automate ‘self-serve/product-led’ plans, and an intuitive no-code user interface to configure ‘custom/enterprise’ plans
5. Additional features including: instant charges, modular couponing, spending minimums, grace periods, etc
## 5. I have a home-made billing infrastructure. How is Lago useful?
Billing is indeed much harder and costly for engineers than it might initially seem.
When getting started, it seems pretty straightforward – you decide on a price, and customers pay you. But as your business grows, things get trickier. It's like managing a puzzle where the pieces keep changing. You have to deal with dates, handle plan upgrades, track usage, avoid charging twice, remind customers to pay, and navigate the tax maze (we have written some posts on this topic [here](https://www.getlago.com/blog/why-billing-systems-are-a-nightmare-for-engineers) and [here](https://www.getlago.com/blog/the-4-biggest-problems-with-homemade-billing-systems)).
Lago is an open source metering and billing API tailored for usage-based pricing. Our API and architecture are open, so you can embed, fork and customize them as much as your pricing and internal processes require.
If you are interested, you can [get started here](https://www.getlago.com/get-started) or [book a demo](https://getlago.com/book-a-demo).
## 6. Can Lago handle high volume processing?
Lago is designed for usage-based billing and high-volume data processing. Its engine is able to handle hundreds of thousands events per second, whether they come in the form of logs or back-end events. Our infrastructure is made to scale to billions of events per month if needed. For more details, we have written about our infrastructure [here](https://github.com/getlago/lago/wiki/Using-Clickhouse-to-scale-an-events-engine).
## 7. I’m an AI company. How is Lago helpful?
Engineering teams in AI companies should be 100% focused on monetizing, not getting bogged down by [billing nightmares](https://news.ycombinator.com/item?id=31424450).
That's where Lago, with its open-source metering and billing engine, comes in. Lago has already been chosen by leading AI companies such as [Mistral](https://mistral.ai/fr/), [Groq.com](http://Groq.com), or [Cerebrium](https://www.cerebrium.ai/), for instance.
Lago’s infrastructure handles hundreds of thousands events per second and makes it easy to offer market-practices pricing features like per-token pricing, prepaid credits, real-time consumption monitoring and progressive billing.
Use one of our templates to replicate the pricing of [OpenAI](/templates/per-token/openai) or [Mistral](/templates/per-token/mistral).
# Community
Source: https://getlago.com/docs/faq/community
## 1. What’s the community like?
Lago Community thrives through the active engagement of 6.6K+ users and developers, making it the largest and fastest-growing billing community on GitHub (see [here](https://github.com/getlago/lago)). It serves as the central hub where users and developers can seek support, request features and contribute to the ongoing enhancement of Lago's product.
You can also join hundreds of billing and pricing professionals in our [Slack Community](https://www.getlago.com/slack).
## 2. How can I contribute?
There are many ways to contribute to the Lago community. You can:
* Share your expertise by answering questions on the Lago Community ([Join our Slack](https://www.getlago.com/slack))
* Write blog posts or tutorials about Lago
* Participate in Lago surveys and user interviews
* Contribute to the Lago codebase (learn more [here](https://github.com/getlago/lago/blob/main/CONTRIBUTING.md))
* Report bugs or suggesting improvements ([here](https://github.com/getlago/lago/blob/main/CONTRIBUTING.md))
For instance, our community played a pivotal role in introducing the "[Latest](/guide/billable-metrics/aggregation-types/latest)" aggregation type to Lago's product. Additionally, we regularly receive translation contributions from users in languages such as Italian, Spanish, and Norwegian.
Thanks to valuable contributions from our users, our community continues to grow stronger!
## 3. Can I suggest new features?
Yes. Lago warmly welcomes feature suggestions. Your ideas are valuable to us. You can suggest new features [here](https://getlago.canny.io/feature-requests). We will carefully review and prioritize highly requested ones, providing regular updates on their progress.
# Deployment
Source: https://getlago.com/docs/faq/deployment
## 1. Is this hard to set up?
Lago is easy to set up, you can run our app in a few clicks by downloading our [Docker image](/guide/lago-self-hosted/docker).
If you have any questions, or want access to our [premium features and/or our cloud version (paying)](https://www.getlago.com/pricing), reach out via [Slack](https://www.getlago.com/slack) or send an email to [hello@getlago.com](mailto:hello@getlago.com); we'll get back to you shortly.
## 2. Can I self-host?
Yes. Lago’s self-hosted version can be deployed on any infrastructure. We provide detailed instructions on [how to self-host Lago](/guide/lago-self-hosted/docker).
## 3. How do I deploy?
There are three options:
1. Lago Self-hosted:
* Self-hosting the open-source product - Free, and self-serve [here](/guide/lago-self-hosted/docker)
* Self-hosting the premium product - Reach out [here](https://www.getlago.com/book-a-demo)
2. Lago Cloud, with either US or EU hosting - There are only a few spots available to use this product at the moment, so we’ll ask you a couple of questions first, reach out [here](https://docs.google.com/forms/d/e/1FAIpQLSfKwXdwe3jIpPJuPs2Nmkw_3GqoUOEP1YxQ3B6frYfGgYJ11g/viewform?usp=send_form)
3. Hybrid hosting: for Enterprise customers, Lago also offers cloud-prem or Virtual Private Cloud (VPC) deployments options
## 4. Can I get it live with my favorite hosting option?
See our instructions to deploy Lago’s open source product [here](/guide/lago-self-hosted/docker).
Want to set it up differently? (Raise an issue)([https://github.com/getlago/lago/issues](https://github.com/getlago/lago/issues)) in the repo.
# General
Source: https://getlago.com/docs/faq/general
## 1. Is billing that hard for engineers?
Yes. Billing is indeed much harder for engineers than it might initially seem. Imagine you're starting a business, and you want to charge your customers for your products or services. At first, it seems pretty straightforward – you decide on a price, and customers pay you. But as your business grows, things get trickier. It's like managing a puzzle where the pieces keep changing. You have to deal with dates, handle plan upgrades, track usage, avoid charging twice, remind customers to pay, and navigate the tax maze (see more [here](https://www.getlago.com/blog/why-billing-systems-are-a-nightmare-for-engineers)).
For example, deciding how often to charge your customers for subscriptions and charges might sound simple, like choosing between weekly, monthly, or yearly billing. But it's more complex than it appears. You also need to factor in things like leap years, offering free trial periods, and deciding how to handle pro-rata pricing. And if you ever decide to switch from billing based on 'anniversary' dates to calendar dates, that adds even more complexity to the mix.
At Lago, we've adopted a radical approach – we're building an open source billing API for product-led SaaS. Our API and architecture are open, so that you can embed, fork and customize them as much as your pricing and internal processes require.
If you're interested, you can [get started here](https://www.getlago.com/get-started) or [book a demo](https://getlago.com/book-a-demo).
## 2. How is Lago different from Stripe? Can Lago replace it?
Lago is an open source metering and billing solution, whereas Stripe primarily focuses on payment processing.
Stripe offers 21 products with separate fees, including Stripe Billing and Stripe Invoicing.
Lago can replace Stripe for some services such as billing, invoicing and potentially [more](https://www.getlago.com/blog/calculating-stripe-mrr-is-difficult), but it does not process payments directly. Businesses using Lago will need a separate payment processor. Lago calculates how much you should charge a user and when, and sends this information to your chosen payment gateway(s) (Lago is agnostic) for the actual payment processing.
## 3. Is Lago cheaper than Stripe?
Stripe Billing will cost you 0.5% (and up to 0.8%) of your transaction volume, on top of Stripe Payments (starts at 2.9% + \$0.30 per successful card charge). With the full vendor lock-in of Stripe, you might stack dozens of fees that are directly impacting your own revenue. Once again, Stripe has 21 products and each of them has their own pricing.
## 4. How is Lago different from Chargebee?
Chargebee is not designed for usage-based billing. Lago is.
Lago is designed for usage-based pricing models, providing a high level of flexibility and support complex usage-based scenarios. Chargebee supports standard usage-based models (e.g. \$20 per user) but may not be flexible enough for businesses that need support for complex usage-based pricing models (e.g., PayPal's per-transaction pricing). Chargebee limits the maximum number of usages that can be recorded for a subscription is 5,000, over its lifetime.
Lago has no rate limit for usage-based billing events, allowing for high volume processing. Chargebee has a rate limit of 100 simultaneous requests per minute, which could prevent you from sending granular usage when you start scaling your number of customers.
Additionally, Lago, being an open source solution, offers complete transparency, allowing engineers to audit its code and even build on top of it, which Chargebee does not allow.
## 5. Is Lago cheaper than Chargebee?
Chargebee offers two services including billing and retention with separate fees. For billing:
* Starter plan: No flat fee, with the first \$250K of cumulative billing included; 0.75% on billing thereafter. This plan includes basic billing features.
* Performance plan: \$599 monthly flat fee for up to \$100K of monthly billing; 0.75% on billing thereafter. This plan offers access to some advanced features.
* Enterprise plan: Custom pricing.
Lago offers a forever-free open source solution for small businesses, allowing access to fundamental billing features. Besides, Lago provides Enterprise Plans with access to premium features, as listed [here](https://www.getlago.com/pricing).
## 6. Can Lago be used by non-tech users?
Yes. Lago is a developer-first product with an intuitive interface. All actions in Lago can be performed via the API or the user interface, making Lago accessible to both tech-savvy and non-technical users alike.
For **Engineers**: Lago is Developer-first and API-first, offering high flexibility and ability to build on top of it. Lago can handle a high volume of events and works seamlessly with your existing tools.
For **Product managers**: Lago can adapt to any pricing model, and our easy-to-use interface lets non-technical teams manage billing without developer assistance. You can retrieve billing data for integration to your BI tools. You can also use it to trigger automations and implement alerting as needed.
For **Finance leaders**: Lago streamlines invoicing by automating charge calculations, supports various pricing plans, and helps track payments. Lago ensures the invoicing and cash collection process under your control. For instance, check who paid their invoices in a glance to improve cash collection. It also integrates billing data into your tools for better revenue insights.
# Pricing
Source: https://getlago.com/docs/faq/pricing
## 1. Is Lago free?
Lago offers a forever-free open source solution offering access to fundamental billing features. Besides, Lago also offers paying plans with access to premium features listed [here](https://www.getlago.com/pricing).
## 2. How is your pricing structured?
Our pricing is structured in packages that are tailored to specific company stages: early, scaling, or more on the enterprise side.
We’re willing to grow with our customers sustainably (if they are successful, we are successful too) so we have included a usage-based dimension (e.g., number of events ingested, invoices generated, or active customers) in our packages
Contact us at [hello@getlago.com](mailto:hello@getlago.com) to discuss what features and usage volumes work best for your company.
## 3. Can I self-host the Premium features?
Yes. Lago offers Enterprise plans with access to premium features listed [here](https://www.getlago.com/pricing). You have the flexibility to choose between cloud hosting or self-hosting options.
Please reach out via [Slack](https://www.getlago.com/slack) or [hello@getlago.com](mailto:hello@getlago.com) for further details.
## 4. Can I have a free trial for Lago Premium?
You can use and/or try Lago forever-free product by downloading our self-hosted and open source product [here](/guide/introduction/welcome-to-lago). We unfortunately do not offer free trials for our premium plans (cloud or self-hosted).
In specific cases, our Solution Engineering team can organize ‘proofs of concepts’. Reach out via [Slack](https://www.getlago.com/slack) or [hello@getlago.com](mailto:hello@getlago.com) if you need help testing Lago.
# Product features
Source: https://getlago.com/docs/faq/product-features
## 1. Does Lago support prepaid credits?
Yes. Prepaid credits are a great way to give customers better spend visibility and facilitate payment collection in advance.
To prepay for usage with lago follow this simple steps:
1. Create a new wallet for prepaid credits;
2. Assign a value for each credit (eg. 1 credit equals 1\$);
3. Specify the number of credits to purchase; and
4. Configure recurring top-up rules based on real-time consumption (threshold or interval top-ups)
See a real-life example of prepaid credits with Mistral [here](/templates/per-token/mistral).
## 2. Which payment methods does Lago support?
Lago is agnostic and enables you to connect with any payment providers. Lago is already natively integrated with several payment providers ([see here](/guide/payments/payment-providers)).
## 3. Does Lago support invoicing?
Yes. Without charging a percentage of billings, every plan includes built-in invoicing automation with native invoice generation.
Lago enables you to issue invoices and send them to your customers via email. Lago offers advanced invoicing features, allowing you to customize invoice templates, and to include [customer metadata](/guide/customers/customer-metadata) & [credit notes](https://github.com/getlago/lago/wiki/Refunds,-Coupons-&-Credit-Notes:-why-they-are-different) in invoices and set [invoice grace periods](https://www.getlago.com/blog/grace-period-to-adjust-invoice-usage). These features can enhance invoicing operations and compliance.
Additionally, Lago offers support for multiple languages for invoices and emails, making it a versatile solution for businesses operating in various countries or aiming for global expansion ([see more here](/api-reference/resources/locales)).
Companies also have the option to integrate our billing engine with an existing invoicing provider like Quickbooks, Netsuite, Bill.com, or Stripe. Learn more [here](/integrations/introduction).
## 4. Does Lago provide a customer self-service portal?
Yes. Lago allows you to effortlessly integrate the customer portal into your application, providing your customers with seamless access to detailed usage information and invoice data.
## 5. Does Lago provide Analytics and Reporting?
Lago is your go-to solution for in-depth analytics of your billing data. This gives you access to accurate revenue computation with ease and other critical financial information.
Analytics dashboard are accessible through both user interface and dedicated API endpoints to obtain the insights that matter most to you, like your monthly recurring revenues (if you use Stripe, you probably know how [difficult it is to gather this info](https://www.getlago.com/blog/calculating-stripe-mrr-is-difficult))
Learn more about analytics [here](/guide/analytics/overview).
## 6. Does Lago support different time zones?
Yes. Lago allows you to set time zones at a customer level, ensuring that usage ingestion, expiry dates and billing will be triggered based on the time zone of your customer.
Read more about why time zones matter [here](https://www.getlago.com/blog/bill-your-customers-in-their-timezone-not-yours).
## 7. What integrations does Lago support?
All Lago’s plans offer native integrations with third party tools for payments (Stripe Payments, GoCardless, Adyen), accounting (NetSuite, QuickBooks), taxes (Anrok), CRM (Salesforce) and others.
You can learn more about integrations [here](/integrations/introduction).
## 8. Does Lago support taxation?
Lago features automatic European tax detection integration for your customers. Learn more about Lago EU Taxes integration [here](/integrations/taxes/lago-eu-taxes).
You can also integrate with Anrok, the global sales tax platform for software companies. Learn more about this integration [here](/integrations/introduction).
## 9. Does Lago process payments?
Lago does not process payments directly but enables you to integrate with any payment processors (Stripe Payments, GoCardless, Adyen, etc). Learn more about payment integrations [here](/integrations/introduction).
Lago will process and calculate how much you should charge a user and when, and send this information to your chosen payment gateway, so that your user can proceed to the actual payment. We also allow you to monitor payment status and track refunds.
# The Billing Assistant (Beta)
Source: https://getlago.com/docs/guide/ai-agents/billing-assistant
Your AI-powered billing assistant for automating manual and repetitive billing operations.
## Overview
The Billing Assistant AI Agent is a conversational assistant designed to help you manage billing operations more efficiently. Instead of navigating through multiple screens or performing repetitive tasks manually, simply describe what you need in plain language and let the assistant handle it for you.
## Billing assistant capabilities
1. **Automate repetitive tasks:** Bulk updates, batch operations, and routine billing actions;
2. **Query billing data instantly:** Get quick answers without clicking through multiple screens;
3. **Streamline manual operations:** Create invoices, apply coupons, manage subscriptions and more, all through conversation;
4. **Receive actionable responses:** Formatted results with clickable links to relevant records; and
5. **Work faster with context:** The assistant remembers your past conversations for seamless follow-ups.
## Getting started
### Requirements
To use the AI Agent, you need access to your Lago organization and have the AI chat permission enabled for your account.
**PREMIUM ADD-ON** ✨
This Billing Assistant Agent is in beta, and available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium feature.
### How to use
Open the AI Agent chat interface in your Lago dashboard.
Type your question or request in natural language.
Review the AI's response, which may include formatted tables, links, and actionable data.
You might need to confirm certain actions before they are executed.
Continue the conversation with follow-up questions as needed
## Available operations
The Billing Assistant can help you with a wide range of billing operations:
* **Invoices:** Retrieve invoice details, track payment status, handle failed invoices, refresh draft invoices and generate previews before finalizing charges.
* **Customers:** Access customer information, create new customer records, and monitor current usage across your customer base.
* **Subscriptions:** Manage the full subscription lifecycle, from creation through updates and termination.
* **Events:** Review ingested usage events and send new events when needed.
* **Payments:** Track payment activity and record new payments against outstanding invoices.
* **Plans:** Browse your pricing plans and make updates to your plan catalog.
* **Coupons:** View available discounts and apply them to customer accounts.
* **Logs:** Investigate activity logs and API logs to troubleshoot issues or audit recent changes.
The assistant can handle batch and concurrent operations, allowing you to perform actions on multiple records at once.
## Example requests
Here are some examples of how this AI Agent can help with your billing operations:
* *"Show me overdue invoices for the last 30 days"*
* *"List the latest activity logs"*
* *"What is the current usage for customer Acme Corp?"*
* *"Show me all subscriptions created this month"*
* *"What are the number of invoices generated last week?"*
* *"Create a new customer with email `gavin@hooli.com`"*
* *"Apply coupon `SUMMER20` to customer Acme Corp"*
* *"Retry all failed invoices from last week"*
* *"Update the billing email for customer xyz"*
* *"Apply coupon SUMMER20 to all US customers"*
* *"Generate invoice previews for all customers with active subscriptions"*
* *"List all overdue invoices and retry payments"*
* *"Download invoice `INV-001`"*
* *"What plans are available?"*
* *"Show me payment history for customer ID xyz"*
## Destructive or important actions
For operations that modify data, delete data or create any important billing operations, the Billing Assistant requires explicit confirmation to protect against accidental changes. Here is an example:
* **You:** *"Terminate subscription for Acme Corp"*
* **Billing Assistant:** *"This subscription is currently active (\$2,500/month). Type `CONFIRM` to proceed."*
You must type `CONFIRM` to execute destructive actions such as terminating subscriptions, issuing invoices or refunds or removing customers.
## Security
The Billing Assistant AI Agent is designed with security as a priority:
1. **Organization-scoped access:** You can only query and modify data within your own organization;
2. **Permission-based:** Actions are limited to your account permissions;
3. **No cross-tenant access:** Your data is isolated from other organizations;
4. **Prompt injection protection:** The AI Agent is designed to ignore attempts to bypass security controls; and
5. **Batch operation limits:** To prevent abuse, batch operations are capped and throttled to prevent excessive load.
## Conversation history
Your conversations with the Billing Assistant are saved, allowing you to:
* Return to previous conversations;
* Maintain context across sessions; and
* Reference past queries and responses.
Each conversation is named after your first message for easy identification.
## Tips for best results
* **Be specific:** "Show invoices over \$1,000 from last month" works better than "Show me some invoices";
* **Use follow-ups:** After getting a list, ask follow-up questions like "Tell me more about the first one" or "Retry all of these";
* **Specify timeframes:** Include date ranges when relevant ("in the last 30 days", "from Q3");
* **Name entities clearly:** Use customer `external_id`, invoice `id`, or useful identifiers when you have them; and
* **Chain tasks together:** Complete related operations in one conversation to save time.
## Technical details
### System Overview
```mermaid theme={"dark"}
flowchart LR
Frontend["Frontend (React)"]
LagoAPI["Lago API (Rails)"]
MCP["MCP Server (Rust)"]
Mistral["Mistral AI"]
LagoREST["Lago API (REST)"]
Frontend <-->|"GraphQL WebSocket"| LagoAPI
LagoAPI -->|"HTTP/SSE"| MCP
MCP <-->|"Agents API"| Mistral
MCP -->|"lago-rust-client"| LagoREST
```
### Technologies
| Component | Technology | Purpose |
| ---------- | --------------------- | --------------------------------- |
| Frontend | React + Apollo Client | Chat UI & GraphQL subscriptions |
| Backend | Rails + Action Cable | GraphQL API & WebSocket streaming |
| MCP Server | Rust + rmcp | Model Context Protocol server |
| AI Model | Mistral Agents API | LLM with function calling |
| API Client | lago-rust-client | Type-safe Lago API interactions |
# Lago MCP Server
Source: https://getlago.com/docs/guide/ai-agents/mcp-server
Connect Lago live data, models, and billing logic to any AI system, bringing billing context and interactions everywhere.
The [Lago MCP Server](https://github.com/getlago/lago-agent-toolkit) (Model Context Protocol) is written in Rust and provides AI assistants (like Claude) with direct access to Lago's billing data.
The server acts as a bridge between AI models and the Lago API, enabling natural language queries about invoices, customers, and billing information.
## Quick start using Claude Desktop
### Configure Claude Desktop
The easiest way to get started is using the pre-built Docker image with Claude Desktop:
```json theme={"dark"}
{
"mcpServers": {
"lago": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"--name", "lago-mcp-server",
"-e", "LAGO_API_KEY=your_lago_api_key",
"-e", "LAGO_API_URL=https://api.getlago.com/api/v1",
"getlago/lago-mcp-server:latest"
]
}
}
}
```
### Set your credentials
Simply replace your `LAGO_API_KEY` with your actual Lago API key. You can find this in your Lago dashboard under API settings.
Also, make sure that you are using the right `LAGO_API_URL` for your Lago instance.
### Start chatting
Once configured, you can ask Claude natural language questions about your billing data:
* "Show me all pending invoices from last month"
* "Find all failed payment invoices"
* "Give me the total amount of overdue invoices for the month of March 2025"
The list of available commands and their descriptions can be found in the [Lago MCP Server GitHub repository](https://github.com/getlago/lago-agent-toolkit?tab=readme-ov-file#available-tools).
You can contribute to the project by adding more commands or improving existing ones.
# Alerts
Source: https://getlago.com/docs/guide/alerts
Alerts allow you to monitor your subscriptions' usage and billing by firing notifications when certain conditions are met.
## Overview
Usage alerts are essential for effectively monitoring customer activity and managing billing. They help ensure that customers stay within their usage limits and prevent unexpected charges. Below are some key use cases where alerts can be beneficial:
1. Allow customers to set and manage their own usage limits and budgets, empowering them to control their consumption;
2. Alert customers with skyrocketing usage to prevent unexpected costs or overages on their bills; or
3. Implement entitlement logic to halt usage tracking when a customer reaches their predefined limit, ensuring accurate billing and compliance.
## Create an alert
An alert must be tied to a specific subscription. To create an alert for a particular subscription, follow these steps:
1. Access the specific subscription view;
2. Click on the **Alerts** tab;
3. Click on the **Add an alert** button;
4. Select the type of alert (e.g., Lifetime Usage Amount);
5. Set the progressive thresholds and code for the alert;
6. Define the optional recurring threshold for the alert; and
7. Click on the **"Create alert"** button to confirm.
The alert threshold `code` helps distinguish between different types of alert notifications. For example, some notifications may indicate a `soft` limit, while others may trigger a `hard` limit, each with different levels of urgency or action required.
```bash Lifetime usage amount alert creation theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/subscriptions/:external_id/alerts" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"alert": {
"alert_type": "lifetime_usage_amount",
"code": "lifetime_usage_alerts",
"name": "Lifetime Usage Alerts",
"thresholds": [
{
"code": "soft",
"value": "1000.0",
"recurring": false
},
{
"code": "soft",
"value": "2000.0",
"recurring": false
},
{
"code": "hard",
"value": "15000.0",
"recurring": false
}
],
"billable_metric": null
}
}'
```
## Alert types
Lago supports the following alert types:
* **Lifetime Usage Amount**: Triggered when a subscription's lifetime usage exceeds predefined thresholds.
* **Current Usage Amount**: Triggered when a subscription's usage exceeds predefined thresholds for the current billing period.
* **Billable Metric Current Usage Amount**: Triggered when the usage of a specific billable metric exceeds predefined thresholds for the current billing period.
* **Billable Metric Current Usage Units**: Triggered when the usage of a specific billable metric units exceeds predefined thresholds for the current billing period.
## Alert notifications
After configuring an alert and starting to ingest usage, you can listen for the `alert.triggered` webhook message. These webhooks serve as notifications sent to your system, indicating when an alert threshold has been crossed, along with all the relevant alert details.
```json theme={"dark"}
{
"webhook_type": "alert.triggered",
"object_type": "triggered_alert",
"triggered_alert": {
"lago_id": "ff604dc4-2223-412a-a8f4-8fde7dfd3346",
"lago_alert_id": "98d00d14-dc17-40c8-81c2-701b7cdbb038",
"lago_subscription_id": "0705ad6b-c063-421a-87b6-a6c25f98c842",
"billable_metric_code": null,
"alert_name": "Total Usage Alerts",
"alert_code": "total_usage",
"alert_type": "usage_amount",
"current_value": "100.0",
"previous_value": "0.0",
"crossed_thresholds": [
{
"code": "hard_limit",
"value": "100.0",
"recurring": false
}
],
"triggered_at": "2025-05-27T19:25:02Z"
}
}
```
## Limitations
Please consider the following limitations for usage alerts:
* Alerts only evaluate usage data reported after their creation;
* Alerts run on a default 5-minute interval clock. Contact the team if you need a different frequency; and
* Identical alerts cannot be created more than once.
# Forecasted usage
Source: https://getlago.com/docs/guide/analytics/forecasted-usage
## Overview
The Forecasted Usage feature leverages machine learning to predict future usage. This helps you anticipate customer usage patterns and do revenue forecasting with confidence.
The forecasting system uses a machine learning pipeline that trains multiple models on historical usage data and generates probabilistic predictions for future periods.
## How forecasting works
### Data-driven predictions
The ML pipeline uses historical usage data, grouped by billable metric, subscription, charge, and charge filter to identify patterns and trends and train ML models.
The target variable to forecast is future paid usage, as opposed to just invoiced usage which may or may not be eventually paid.
The model generates forecasts for 12 months ahead at monthly granularity.
As a rule of thumb, the forecasts are updated in the first 2 weeks of the month.
### Forecasting methods
The system supports two main forecasting approaches:
#### 1. Trained ML Models
Advanced machine learning models that learn from historical patterns, including:
* **LightGBM**: Gradient boosting model with quantile loss for probabilistic forecasting
* **N-BEATS**: Deep learning neural network specialized for time series
* **Ensemble**: Combines multiple models for improved accuracy
These models generate three forecast scenarios (conservative, realistic, and optimistic) based on different probability quantiles.
#### 2. Historical Mean
A simpler baseline method that uses historical average usage as the forecast. It is used whenever there is insufficient data to train ML models.
### Probabilistic forecasting
All trained model forecasts include three scenarios:
* **Conservative**: Lower-bound estimate for cautious planning
* **Realistic**: Median forecast representing the most likely outcome
* **Optimistic**: Upper-bound estimate for best-case scenarios
This probabilistic approach helps you understand the range of possible outcomes and plan accordingly.
### Subscription growth
We explicitly model the growth in the number of subscriptions using the historical data of your organization.
### Limitations
The models forecast the future usage amounts for a subset of all potential future revenue sources. For example, it doesn't explicitly account for new business products and features.
Recently created and unused/deleted billable metrics and charges can be excluded from the forecasts.
## Filtering options
Filter forecasted usage data by:
* Currency
* Customer country
* Customer external ID
* Customer type
* Customer has TaxID
* Plan code
* Subscription external ID
* Billable metric
**PREMIUM FEATURE** ✨
Forecasted Usage and advanced filtering options are only available to users with a premium license. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
# Reports
Source: https://getlago.com/docs/guide/analytics/reports
Lago provides a unified analytics layer for billing, revenue, and product usage data. It enables finance and operations teams to compute, monitor, and reconcile revenue metrics with accuracy and confidence.
## Overview
Revenue dashboards are available directly in the Lago application and are the default landing experience after login, ensuring immediate visibility into key financial indicators. The same datasets are accessible through the Lago API, allowing teams to integrate revenue analytics into external BI tools, internal dashboards, or financial workflows.
The analytics layer is designed to be production-ready and extensible, supporting standard reporting needs while allowing customization for advanced use cases.
## Architecture and composability
Lago's analytics interface is built on [Apache Superset](https://superset.apache.org/), an open-source data visualization and dashboarding platform. This foundation enables:
* Fully composable dashboards
* A wide range of visualization types
* Reusable charts and reporting components
* Flexible metric definitions and breakdowns
Lago ships with prebuilt dashboards covering core finance and usage reporting. Teams can extend these dashboards or create new ones to address custom reporting requirements, such as board reporting, product performance analysis, or customer level revenue analysis.
## Finance reports
Lago includes standard financial reporting views required by modern subscription and usage-based businesses. These reports include, but are not limited to:
* Revenue streams
* Monthly Recurring Revenue (MRR)
* Revenue breakdown by customer, subscription, or product
* Time based revenue evolution
These reports are designed to align with billing data and reflect finalized invoice and subscription states according to Lago's revenue logic.
## Usage and credits reports
In addition to financial metrics, Lago provides detailed usage analytics, including:
* Credit consumption over time
* Usage distribution across customers or subscriptions
* Breakdown of metered events by product or feature
This enables product and finance teams to analyze monetization efficiency, credit burn patterns, and usage to revenue alignment.
## Filters and dimensions
All dashboards support flexible filtering, time aggregation, and multidimensional analysis.
Users can apply filters across relevant business attributes and time ranges to focus on specific subsets of data. Metrics can be aggregated at different time intervals to support both high level trend analysis and granular operational review.
Reports can also be broken down across multiple dimensions, enabling comparative analysis and deeper insight into performance drivers. This exploration model allows teams to investigate data directly within Lago without requiring external processing.
## Data export
All charts and datasets can be exported in standard formats:
* JSON
* CSV
* Excel
Exports respect the active filters and breakdowns applied in the dashboard, ensuring consistency between the UI view and the extracted data. This supports reconciliation workflows, offline analysis, and data sharing with stakeholders.
## Data refresh strategy
To ensure fast and consistent performance across both the UI and API, Lago uses a strategic caching layer for revenue analytics.
Revenue and analytics datasets are refreshed daily around 12:00 AM UTC.
As a result:
* Dashboards and API endpoints may not reflect same day billing changes immediately.
* There may be a short delay between transactional events and their appearance in analytics views.
This refresh model balances performance and data consistency, making Lago suitable for operational monitoring, financial reporting, and executive dashboards.
# Aggregation examples
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/aggregation-examples
Imagine you are a Tracking API company (such as
[Segment.com](https://www.segment.com/)). For the same events received, the
result provided by the aggregation types proposed by Lago is completely
different. This result is used to charge your customers.
## Example of events received[](#example-of-events-received "Direct link to heading")
You decided to charge the `Tracked Pages`. **This is your Billable metric.**
Here are the 2 events sent by your backend to Lago, based on the consumption of
a customer:
```json Event received n°1 theme={"dark"}
{
"transaction_id": "1111-1111-1111-1111",
"external_customer_id": "1",
"timestamp": "2022-03-16T00:00:00Z",
"code": "tracked_pages",
"properties": {
"tracked_user_id": "1234-5678-9098-7654",
"pageviews": 10
}
}
```
```json Event received n°2 theme={"dark"}
{
"transaction_id": "2222-2222-2222-2222",
"external_customer_id": "1",
"timestamp": "2022-03-17T00:00:00Z",
"code": "tracked_pages",
"properties": {
"tracked_user_id": "1234-5678-9098-7654",
"pageviews": 20
}
}
```
Let's see below the differences between the aggregation types.
## Differences between the aggregation types[](#differences-between-the-aggregation-types "Direct link to heading")
| Aggregation | Code | Units to be charged |
| ---------------- | -------------------------------------------------------- | ------------------- |
| **COUNT** | `COUNT(tracked_pages)` | 2 |
| **SUM** | `SUM(tracked_pages.properties.pageviews)` | 30 |
| **MAX** | `MAX(tracked_pages.properties.pageviews)` | 20 |
| **COUNT UNIQUE** | `UNIQUE_COUNT(tracked_pages.properties.tracked_user_id)` | 1 |
Based on the aggregation type you defined for your Billable metric
`Tracked Pages`, the result that is going to be charged to your customer is
completely different. Make sure to choose the right aggregation type for all
your Billable metrics. If you need help, don't hesitate to reach out to the Lago
Team!
# COUNT
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/count
The count aggregation type is straightforward. It tallies the exact number of events received during a period.
## COUNT billable metric
Here is how you can create a count aggregation from the UI:
1. Access the **"Billable metrics"** section via the side menu;
2. Create a new billable metric;
3. Define a name, a code and an optional description;
4. Select **"count"** as the aggregation type;
5. Apply dimension groups if any; and
6. Click **"Add billable metric"**.
This billable metric is `metered` only, meaning it cannot be recurring, and the number
of billing units resets to 0 at the end of each period.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "API Request",
"code": "api_requests",
"description": "Number of API requests.",
"aggregation_type": "count_agg",
"group": {}
}
}'
```
## Calculation example
Lago calculates the `COUNT(events.code)` for the two following events received.
```json theme={"dark"}
//Event received #1
{
"transaction_id": "transaction_1",
"external_customer_id": "1",
"timestamp": "2022-03-16T00:00:00Z",
"code": "api_requests",
"properties": {}
}
//Event received #2
{
"transaction_id": "transaction_2",
"external_customer_id": "1",
"timestamp": "2022-03-17T00:00:00Z",
"code": "api_requests",
"properties": {}
}
```
In that case, with this aggregation type, Lago simply counts the number of events received, **resulting in a billable value of 2 units.**
# UNIQUE COUNT
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/count-unique
The unique count aggregation type counts only the unique values of a specified event property.
## UNIQUE COUNT billable metric
Here is how you can create a unique count aggregation from the UI:
1. Access the **"Billable metrics"** section via the side menu;
2. Create a new billable metric;
3. Define a name, a code and an optional description;
4. Select **"count unique"** as the aggregation type;
5. Define if this metric is `metered` or `recurring`;
6. Define the property to aggregate;
7. Apply dimension groups if any; and
8. Click **"Add billable metric"**.
This billable metric can be both `metered` or `recurring`.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "API Request",
"code": "api_requests",
"description": "Number of API requests.",
"aggregation_type": "unique_count_agg",
"field_name": "request_id",
"group": {}
}
}'
```
## Calculation example
Lago calculates the `COUNT_DISTINCT(events.properties.property_name)` for the two following events received.
```json theme={"dark"}
//Event received #1
{
"transaction_id": "transaction_1",
"external_customer_id": "1",
"timestamp": "2022-03-16T00:00:00Z",
"code": "api_requests",
"properties": {
"request_id": "id_1"
}
}
//Event received #2
{
"transaction_id": "transaction_2",
"external_customer_id": "1",
"timestamp": "2022-03-17T00:00:00Z",
"code": "api_requests",
"properties": {
"request_id": "id_1"
}
}
```
In that case, with this aggregation type, Lago only counts the unique values of the `request_id` property in the event payloads, **resulting in a billable value of 1 unit.**
# CUSTOM
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/custom-agg
**Premium feature ✨**:
This feature is only available to users with a premium license. Please **[contact us](mailto:hello@getlago.com)** to get access to this feature.
Lago's basic interface and API allow you to configure metrics using conditional statements and predefined functions for usage aggregation.
However, for more sophisticated metrics, you may require more complex aggregation capabilities than those provided by Lago's default settings.
To address this need, Lago can parse your custom code, enabling you to implement advanced billing rules and custom aggregation logic.
By using custom code for aggregation, you gain complete flexibility over your usage metrics, allowing you to define and tailor them to your specific requirements.
This feature empowers you to create bespoke solutions that precisely match your billing needs.
If you're interested in leveraging custom code aggregation, please contact our team to enable this feature.
# LATEST
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/latest
The latest aggregation type selects the most recent value of a specified event property from all received events.
## LATEST billable metric
Here is how you can create a latest aggregation from the UI:
1. Access the **"Billable metrics"** section via the side menu;
2. Create a new billable metric;
3. Define a name, a code and an optional description;
4. Select **"latest"** as the aggregation type;
5. Define the property to aggregate;
6. Apply dimension groups if any; and
7. Click **"Add billable metric"**.
This billable metric is `metered` only, meaning it cannot be recurring, and the number of billing units resets to 0 at the end of each period.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "API Request",
"code": "api_requests",
"description": "Number of API requests.",
"aggregation_type": "latest_agg",
"field_name": "total_requests",
"group": {}
}
}'
```
## Calculation example
Lago calculates the `LAST_VALUE(events.properties.property_name) OVER ([PARTITION BY events.timestamp])` for the two following events received.
```json theme={"dark"}
//Event received #1
{
"transaction_id": "transaction_1",
"external_customer_id": "1",
"timestamp": "2022-03-16T00:00:00Z",
"code": "api_requests",
"properties": {
"total_requests": 20
}
}
//Event received #2
{
"transaction_id": "transaction_2",
"external_customer_id": "1",
"timestamp": "2022-03-17T00:00:00Z",
"code": "api_requests",
"properties": {
"total_requests": 10
}
}
```
In that case, with this aggregation type, Lago takes the latest value of the `total_requests` property from all events, **resulting in a billable value of 10 units.**
# MAX
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/max
The max aggregation type selects the highest value of a specified event property from all received events.
## MAX billable metric
Here is how you can create a max aggregation from the UI:
1. Access the **"Billable metrics"** section via the side menu;
2. Create a new billable metric;
3. Define a name, a code and an optional description;
4. Select **"max"** as the aggregation type;
5. Define the property to aggregate;
6. Apply dimension groups if any; and
7. Click **"Add billable metric"**.
This billable metric is `metered` only, meaning it cannot be recurring, and the number of billing units resets to 0 at the end of each period.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "API Request",
"code": "api_requests",
"description": "Number of API requests.",
"aggregation_type": "max_agg",
"field_name": "total_requests",
"group": {}
}
}'
```
## Calculation example
Lago calculates the `MAX(events.properties.property_name)` for the two following events received.
```json theme={"dark"}
//Event received #1
{
"transaction_id": "transaction_1",
"external_customer_id": "1",
"timestamp": "2022-03-16T00:00:00Z",
"code": "api_requests",
"properties": {
"total_requests": 20
}
}
//Event received #2
{
"transaction_id": "transaction_2",
"external_customer_id": "1",
"timestamp": "2022-03-17T00:00:00Z",
"code": "api_requests",
"properties": {
"total_requests": 10
}
}
```
In that case, with this aggregation type, Lago takes the highest value of `total_requests` property from all events, **resulting in a billable value of 20 units.**
# Overview
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/overview
Aggregation types will define how consumption will be measured.
Here is the full list of **aggregation types** officially
supported by Lago.
| Aggregation | Description | Transcription |
| ---------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **COUNT** | Count the number of times an incoming event occurs | `COUNT(events.code)` |
| **COUNT UNIQUE** | Count the number of unique values of a defined property for incoming events | `COUNT_DISTINCT(events.properties.property_name)` |
| **LATEST** | Get the latest value of a defined property for incoming events | `LAST_VALUE(events.properties.property_name) OVER ([PARTITION BY events.timestamp])` |
| **MAX** | Get the maximum value of a defined property for incoming events | `MAX(events.properties.property_name)` |
| **SUM** | Sum a defined property for incoming events | `SUM(events.properties.property_name)` |
| **WEIGHTED SUM** | Sum a defined property for incoming events, prorated based on time used per period | `SUM(events.properties.property_name) / (DATEDIFF(SECOND, timestamp.event_1, timestamp.event_2) + 1) * (DATEDIFF(SECOND, 'period_start', 'period_end') + 1)` |
| **CUSTOM** | Define a custom code for your aggregation | Custom code |
Except the `COUNT` (that is counting the number of times an event occurs), the
other types aggregate over a single property of the event. **The result of this
aggregation will be used to charge your customers.**
# SUM
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/sum
The sum aggregation type adds up the value of a defined event property.
## SUM billable metric
Here is how you can create a sum aggregation from the UI:
1. Access the **"Billable metrics"** section via the side menu;
2. Create a new billable metric;
3. Define a name, a code and an optional description;
4. Select **"sum"** as the aggregation type;
5. Define if this metric is `metered` or `recurring`;
6. Define the property to aggregate;
7. Apply dimension groups if any; and
8. Click **"Add billable metric"**.
This billable metric can be both `metered` or `recurring`.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "API Request",
"code": "api_requests",
"description": "Number of API requests.",
"aggregation_type": "sum_agg",
"field_name": "total_requests",
"group": {}
}
}'
```
## Calculation example
Lago calculates the `SUM(events.properties.property_name)` for the two following events received.
```json theme={"dark"}
//Event received #1
{
"transaction_id": "transaction_1",
"external_customer_id": "1",
"timestamp": "2022-03-16T00:00:00Z",
"code": "api_requests",
"properties": {
"total_requests": 20
}
}
//Event received #2
{
"transaction_id": "transaction_2",
"external_customer_id": "1",
"timestamp": "2022-03-17T00:00:00Z",
"code": "api_requests",
"properties": {
"total_requests": 10
}
}
```
In that case, with this aggregation type, Lago adds up the values of the `total_requests` property in the event payloads, **resulting in a billable value of 30 units.**
# WEIGHTED SUM
Source: https://getlago.com/docs/guide/billable-metrics/aggregation-types/weighted-sum
The Weighted Sum aggregation type adds up the value of a defined event property and prorates it based on time used per period.
This is especially handy for automated GB/second calculations, for instance.
Currently, prorating is available **per second per period**.
Feel free to reach out if you need additional proration options, such as hourly rates.
## WEIGHTED SUM billable metric
Here is how you can create a weighted sum aggregation from the UI:
1. Access the **"Billable metrics"** section via the side menu;
2. Create a new billable metric;
3. Define a name, a code and an optional description;
4. Select **"weighted sum"** as the aggregation type;
5. Define if this metric is `metered` or `recurring`;
6. Define the property to aggregate;
7. Define the `weighted_interval` used for time proration. Currently, Lago only supports `seconds`.
8. Apply dimension groups if any; and
9. Click **"Add billable metric"**.
This billable metric can be both `metered` or `recurring`.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "GB Seconds",
"code": "gb/s",
"description": "Gigabytes prorated per seconds used per period",
"aggregation_type": "weighted_sum_agg",
"weighted_interval": "seconds",
"field_name": "gb",
"group": {}
}
}'
```
## Calculation example
Lago calculates the `SUM(events.properties.property_name) / (DATEDIFF(SECOND, timestamp.event_1, timestamp.event_2) + 1) * (DATEDIFF(SECOND, 'period_start', 'period_end') + 1)` for the two following events received.
```json theme={"dark"}
//Event received #1
{
"transaction_id": "transaction_1",
"external_customer_id": "1",
"timestamp": "2022-03-16T00:00:00Z",
"code": "gb/s",
"properties": {
"gb": 20
}
}
//Event received #2
{
"transaction_id": "transaction_2",
"external_customer_id": "1",
"timestamp": "2022-03-17T00:00:00Z",
"code": "gb/s",
"properties": {
"gb": 10
}
}
```
In that case, with this aggregation type, Lago adds up the values of the `gb` property in the event payloads, but prorates it based on time used during the current period.
Keep in mind that the entire month comprises 2,678,400 seconds. The first 20 GB has been used for a day (86,400 seconds), and the 30 GB (20 + 10) has been used for 15 days (1,296,000 seconds till the end of the month):
* (20 / 2678400) x 86400 = 0.64516129032 GB/s
* (30 / 2678400) x 1296000 = 14.5161290323 GB/s
* 0.64516129032 + 14.5161290323 = **15.1612903226 GB/s**
# Create billable metrics
Source: https://getlago.com/docs/guide/billable-metrics/create-billable-metrics
Billable metrics define how incoming events are aggregated in order to measure consumption.
If you want to charge your customers for the use of a particular feature, then
you should create the corresponding billable metric.
To add a new billable metric through the user interface:
* Enter its `name`;
* Assign it a `code` which will be used as the name of the event sent from your
backend;
* Add a `description` *(optional)*;
* Select the `aggregation type` which will define how consumption will be
measured;
* Define the aggregation property `field_name` to aggregate on;
* Define `groups` if you price several dimensions for a same billing component; and
* Define if this billable metric is `recurring` and kept in memory period over period, or resume to 0 at the end of each period.
Here are a few examples of billable metrics you can create:
```bash Storage theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Storage",
"code": "storage",
"description": "Number of GB used",
"aggregation_type": "sum_agg",
"field_name": "gb",
"recurring": false,
"group": {
"key": "provider",
"value": ["aws", "google", "azure"]
}
}
}'
```
```bash Seats theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Seats",
"code": "seats",
"description": "Active seats added",
"aggregation_type": "unique_count_agg",
"field_name": "seat_id",
"recurring": true
}
}'
```
```bash CPUs theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "CPU",
"code": "cpu",
"description": "Maximum number of CPUs used",
"aggregation_type": "max_agg",
"field_name": "total_cpu",
"recurring": false
}
}'
```
```bash Payments theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Payments",
"code": "payments",
"description": "Card payments issued",
"aggregation_type": "sum_agg",
"field_name": "amount",
"recurring": false
}
}'
```
The next section describes the different
[aggregation types](/guide/billable-metrics/aggregation-types). In addition to this, we have added some
[examples](/guide/billable-metrics/aggregation-types/aggregation-examples) to help you understand the relationship
between incoming events and billable metrics.
# Delete billable metrics
Source: https://getlago.com/docs/guide/billable-metrics/delete-billable-metrics
You may delete a billable metric linked to [charges](/guide/plans/charges) associated
with existing [subscriptions](/guide/subscriptions/assign-plan).
If you do so:
* The events associated with this billable metric, which are assigned to the
current billing period or linked to `draft` invoices, will be immediately
deleted;
* The charges associated with this billable metric will be immediately removed
from all plans and existing subscriptions;
* The charges associated with this billable metric will no longer be included in
the [current usage](/api-reference/customer-usage/customer-usage-object) of the customers
concerned; and
* The charges associated with this billable metric will be immediately removed
from all `draft` invoices linked to these subscriptions.
However, the charges associated with this billable metric will still be included
in all `finalized` invoices linked to these subscriptions.
After deleting a billable metric, you can create a new one using the same
code. However, past events will not be linked to this new billable metric.
```bash Delete "Storage" metric theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/billable_metrics/storage" \
--header "Authorization: Bearer $API_KEY"
```
# Filters
Source: https://getlago.com/docs/guide/billable-metrics/filters
When setting up your pricing, you may want to filters events according to their property. To do so, you can create filters for your billable metric.
## Create filters[](#create-filters "Direct link to heading")
Your company provides DevOps services and you want to charge your customers for compute capacity by the hour.
In your Lago account, you create a `compute` billable metric that calculates the total number of hours (i.e. `SUM(properties.hours)`).
As your customers can choose from different cloud providers and define a region, you need to filter usage records (i.e. events) according to the provider and region.
On the configuration page of your billable metric, you can define two filters: `provider` and `region`, with all the necessary values (see snippet below).
1. Create a new billable metric;
2. Add a new filter; and
3. Define your different filters.
Here are a few examples of billable metrics you can create:
```bash Billable metrics with filters {14-23} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Compute",
"code": "compute",
"aggregation_type": "sum_agg",
"field_name": "hours",
"recurring": false,
"filters": [
{
"key": "provider",
"values": ["aws", "google", "azure"]
},
{
"key": "region",
"values": ["europe", "africa", "asia", "north_america"]
}
]
}
}'
```
Below is an example of an event including two group values for the billable metric described above:
```json Event including a group value theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "event_001",
"external_customer_id": "customer_1234",
"code": "compute",
"timestamp": 1668461043,
"properties": {
"hours": 0.07,
"provider": "aws",
"region": "europe"
}
}
}'
```
Values are case-sensitive. If you don't use the exact value when pushing
events, they will not be taken into account. Following our example: the
expected value is `"aws"` and `"AWS"` is an invalid value.
You can also create billable metrics with dimensions
[via the API](/api-reference/billable-metrics/create).
## Edit filters
You can edit billable metric filters associated with existing subscriptions. It’s important to note that making changes to these metric filters can have an impact on all plans where this billable metric is defined as a charge. Here’s an example to illustrate the impact of editing a billable metric:
```json theme={"dark"}
From Payload A:
{
"billable_metric": {
"name": "gigabyte",
"code": "gigabyte",
"aggregation_type": "sum_agg",
"field_name": "total",
"filters": [
{
"key": "region",
"values": [
"usa",
"europe",
]
}
]
}
}
To Payload B:
{
"billable_metric": {
"name": "gigabyte",
"code": "gigabyte",
"aggregation_type": "sum_agg",
"field_name": "total",
"filters": [
{
"key": "region",
"values": [
"USA",
"europe",
"africa"
]
}
]
}
}
```
Note that each filter's keys and values are case-sensitive. Here's how Lago handles these changes:
1. Since `"region": "europe"` remains the same between both payloads, this filter remains in the billable metric.
2. As `"region": "usa"` is present in Payload A but not in Payload B, this filter is removed from the billable metric.
3. As `"region": "USA"` is not present in Payload A but is present in Payload B, this filter will be created in the billable metric.
4. Similarly, as `"region": "africa"` is not present in Payload A but is present in Payload B, this filter will be created in the billable metric.
When this billable metric is associated with charges, editing it will impact all plans where it is defined.
* If an existing filter combination remains the same (case 1), Lago will retain this specific filter from the filters combination in all associated charges.
* If an existing filter combination is removed from the billable metric (case 2), Lago will remove this specific filter from the filters combination in all associated charges.
* If a new filter combination is created in the billable metric (case 3 and 4), Lago will not automatically add this filter in the filters combination in all associated charges; you will need to add them manually.
# Recurring vs metered
Source: https://getlago.com/docs/guide/billable-metrics/recurring-vs-metered
## Recurring billable metrics[](#recurring "Direct link to heading")
When you set `recurring: true` or choose the "recurring" option in the user interface, the billing aggregation for your billable metric
will persist across billing periods. This means that the accumulated result will carry over and be used to charge the customer in
subsequent periods.
```bash Seats example {14} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Seats",
"code": "seats",
"description": "Active seats added",
"aggregation_type": "unique_count_agg",
"field_name": "seat_id",
"recurring": true
}
}'
```
## Metered billable metrics[](#metered "Direct link to heading")
Conversely, if you set `recurring: false` or select the "metered" option in the user interface, the billing aggregation for your billable
metric will reset to zero at the end of each billing period. This ensures that the customer's charges reflect only the usage within
that specific period.
```bash Storage example {14} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Storage",
"code": "storage",
"description": "Number of GB used",
"aggregation_type": "sum_agg",
"field_name": "gb",
"recurring": false
}
}'
```
# Rounding
Source: https://getlago.com/docs/guide/billable-metrics/rounding
Lago aggregates your events in real time. You can add rounding rules to the final result.
## Rounding options
When creating or editing a billable metric, you have the option to apply rounding to the final aggregated value. By default, no rounding is applied. If you choose to enable rounding, you can select from the following options:
* **Ceil**: Rounds up to the nearest integer;
* **Floor**: Rounds down to the nearest integer; or
* **Round**: Rounds to the nearest integer based on standard rounding rules.
## Precision types
### No precision
Omitting precision rounds to the nearest whole number (integer). By default, no specific precision is set for your rounding option.
👉 *Example: 123.4567 rounded with no precision → `123`.*
### Positive precision
Adding a positive precision rounds to a specific number of decimal places.
👉 *Example: 123.4567 rounded with precision 2 → `123.46` (two decimal places retained).*
### Negative precision
Adding a negative precision rounds to a specific position to the left of the decimal.
👉 *Example: 123.4567 rounded with precision -1 → `120` (rounds to the nearest ten).*
# SQL Expressions
Source: https://getlago.com/docs/guide/billable-metrics/sql-expressions
For more advanced calculations, you can use SQL custom expressions. These expressions are helpful when the aggregation results for a billable metric require complex calculations.
## Creating a SQL Custom Expression
When creating a billable metric, you can choose between using a simple aggregation field or a custom expression.
**Custom expressions allow you to define more advanced computation logic**, which is useful when the required aggregation involves complex calculations that Lago should handle.
To add a custom expression through the user interface:
* Define the `name` and `code` for the billable metric;
* Choose an aggregation type;
* Select `Custom expressions` as the aggregation option instead of `Unique field`;
* Enter your custom expression in the expanded side panel;
* Test the custom expression; and
* Save the billable metric.
Here are a few examples of custom expressions you can create for a billable metric:
```bash Storage {13, 14} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Storage",
"code": "storage",
"description": "Number of GB consumed",
"aggregation_type": "sum_agg",
"expression": "event.properties.gb * event.properties.replicas * (event.properties.ended_at - event.properties.started_at) / 3600",
"field_name": "consumed_gb_hours",
"recurring": false
}
}'
```
```bash Seats {13} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Seats",
"code": "seats",
"description": "Number of seats used",
"aggregation_type": "unique_count_agg",
"expression": "CONCAT(event.properties.user_id, '-' , event.properties.app_id)",
"field_name": "seat_id",
"recurring": true
}
}'
```
Custom expressions can be used with any aggregation type except `COUNT`.
## Supported Expressions
A variety of SQL custom expressions are available for use. Here are a few examples:
* **Concatenation:** `CONCAT(event.properties.user_id, '-', event.properties.app_id)`
* **Math operations:** `(event.properties.cpu_number * 25 * event.properties.duration_msec) + (event.properties.memory_mb * 0.000001 * event.properties.duration_msec)`
* **Rounding:** `ROUND(event.properties.duration_msec * 1000)`
* **Least/Greatest:** `LEAST(event.properties.memory_mb, 10.0)`
You can find the full list of supported expressions below:
* [Event attributes](#event-attributes)
* [Atoms](#atoms)
* [Operators](#operators)
* [Functions](#functions)
* [`CONCAT`](#CONCAT)
* [`ROUND`](#ROUND)
* [`FLOOR`](#FLOOR)
* [`CEIL`](#CEIL)
* [`LEAST`](#LEAST)
* [`GREATEST`](#GREATEST)
If you need a custom expression that isn't supported by default in Lago, **feel free to contact our team** or **consider contributing to the open-source version**.
### Event attributes
Lago expressions may include the following event attributes:
* `event.code` (event code)
* `event.timestamp` (event timestamp)
* `event.properties.[property_name]` (event property)
For example, `event.properties.my_property` is a valid event attribute.
### Atoms
Lago expressions may include atoms:
* `123` (integer)
* `123.45` (decimal)
* `'Hello, world!'` (string)
### Operators
Lago expressions may include basic operators:
* `+` (addition)
* `-` (subtraction)
* `*` (multiplication)
* `/` (division)
* unary minus (`-12`)
### Functions
#### `CONCAT`
The `CONCAT` function is used to concatenate two or more strings.
```SQL theme={"dark"}
CONCAT(str1, str2[,strs,...])
```
**Parameters:**
* `str1`: The first string to concatenate
* `str2`: The second string to concatenate
* `strs`: (Optional) Additional strings to concatenate.
**Returns:** A string with the concatenated strings.
**Examples:**
* `CONCAT(event.properties.user_id, '-', event.properties.app_id)`
#### `ROUND`
The `ROUND` function is used to round a number to a specified number of decimal places.
```SQL theme={"dark"}
ROUND(value, precision)
```
**Parameters:**
* `value`: The number to round
* `precision`: (Optional) Number of decimal places. Defaults to `0`.
**Returns:** A number rounded to the specified precision.
**Examples:**
* `ROUND(14.2355)` returns `14`
* `ROUND(14.2355, 0)` returns `14`
* `ROUND(14.2355, 2)` returns `14.24`
* `ROUND(14.2355, -1)` returns `10`
#### `FLOOR`
The `FLOOR` function is used to round a number down to the nearest integer.
```SQL theme={"dark"}
FLOOR(value, precision)
```
**Parameters:**
* `value`: The number to round
* `precision`: (Optional) Number of decimal places. Defaults to `0`.
**Returns:** A number rounded down to the specified precision.
**Examples:**
* `FLOOR(16.2365)` returns `16`
* `FLOOR(16.2365, 0)` returns `16`
* `FLOOR(16.2365, 2)` returns `16.23`
* `FLOOR(16.2365, -1)` returns `10`
#### `CEIL`
The `CEIL` function is used to round a number up to the nearest integer.
```SQL theme={"dark"}
CEIL(value, precision)
```
**Parameters:**
* `value`: The number to round
* `precision`: (Optional) Number of decimal places. Defaults to `0`.
**Returns:** A number rounded up to the specified precision.
**Examples:**
* `CEIL(14.2345)` returns `15`
* `CEIL(14.2345, 0)` returns `15`
* `CEIL(14.2345, 2)` returns `14.24`
* `CEIL(14.2345, -1)` returns `20`
#### `LEAST`
The `LEAST` function is used to find the minimum of two or more numbers.
```SQL theme={"dark"}
LEAST(num1, num2[,nums,...])
```
**Parameters:**
* `num1`: The first number to check minimum value
* `num2`: The second number to check minimum value
* `nums`: (Optional) Additional numbers to check minimum value.
**Returns:** The minimum of the given numbers.
**Examples:**
* `LEAST(event.properties.disk1_usage_mb, event.properties.disk2_usage_mb, 10.0)`
#### `GREATEST`
The `GREATEST` function is used to find the maximum of two or more numbers.
```SQL theme={"dark"}
GREATEST(num1, num2[,nums,...])
```
**Parameters:**
* `num1`: The first number to check maximum value
* `num2`: The second number to check maximum value
* `nums`: (Optional) Additional numbers to check maximum value.
**Returns:** The maximum of the given numbers.
**Examples:**
* `GREATEST(event.properties.memory_mb, 10.0)`
## Testing your SQL Custom Expression
Lago provides a testing tool to help you validate the custom expressions you've created. A sample event is used to test your expression. You can override any field in the test event.
If your custom expression is incorrect, Lago will return an error, and you won't be able to save it until it's valid.
Keep the following in mind:
* You can dynamically reference any event field within your expression; and
* Use precise paths to reference fields accurately. For instance, to use the event timestamp, the path is `event.timestamp`. To reference a custom property sent with the event, the path is `event.properties.your_field`.
# Billing entities
Source: https://getlago.com/docs/guide/billing-entities
Billing entities allow an organization to manage different billing configurations.
Managing multiple billing entities is a premium feature. Contact your account manager to enable it for your organization.
## Create a billing entity
Billing entities let you manage your end customers under distinct billing configurations.
To create a billing entity, follow these steps:
Using the user interface:
1. Click **Settings** in the side navigation bar.
2. In the **Settings** menu, click **"Add a billing entity"**.
3. Enter a **name** and a **unique code** for your billing entity.
4. Configure the entity’s settings as needed.
5. Click **"Add billing entity"** to confirm.
```bash theme={"dark"}
# Create a billing entity
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billing_entities" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_entity": {
"code": "acme_corp",
"name": "Acme Corporation",
"invoice_prefix": "ACM",
"invoice_footer": "Thank you for your business"
}
}'
```
> ℹ️ The first billing entity created in your organization is considered the **default**.
>
> Billing entity settings only apply to the customers assigned to that specific entity. More information is available in the following sections.
***
## Edit a billing entity
You can update all billing entity information **except the code** after creation.
To edit a billing entity:
Using the user interface:
1. Click **Settings** in the side navigation bar.
2. In the **Settings** menu, select the relevant billing entity.
3. Click any section to edit its settings.
```bash theme={"dark"}
# Update a billing entity
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/billing_entities/{code}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_entity": {
"name": "Acme Corporation",
"invoice_prefix": "ACM",
"invoice_footer": "Thank you for your business"
}
}'
```
***
## Delete a billing entity
Deleting a billing entity is **not available** via the Dashboard or API.
> To delete a billing entity, please contact the Lago team directly.
***
## Assign a billing entity to a customer
When creating a customer, you can assign it to a billing entity in two ways:
* Through the Dashboard by selecting the billing entity.
* Via API by passing the `billing_entity_code` in the customer creation payload.
If no billing entity is specified via API, the customer will automatically be assigned to the **default** billing entity to avoid breaking changes.
> ⚠️ A customer can only be linked to one billing entity.
>
> If you need the same customer under a different billing entity, we recommend creating a new customer.
Once a customer is linked to a subscription, invoice, coupon, or wallet, **you cannot change their billing entity**.
# Coupons
Source: https://getlago.com/docs/guide/coupons
Coupons allow you to offer discounts to your customers. When you apply a coupon to a customer, its value will be deducted from their next subscription invoice(s).
The value of the coupon is deducted from the amount of the invoice before tax.
## Create a coupon[](#create-coupon "Direct link to heading")
To create a coupon through the user interface:
1. Access the **"Coupons"** section via the side menu;
2. Click **"Add a coupon"**;
3. Choose a name and a code for your coupon;
4. Select the type of coupon (i.e. fixed amount or percentage);
5. Define its value and frequency (i.e. will be applied once, over several
periods or forever);
6. Choose if the coupon can be applied several times to the same customer
account or not;
7. Choose whether or not to set an expiration date (i.e. date after which the
coupon can no longer be redeemed);
8. Select the **plan(s)** or **billable metric(s)** to which the coupon applies (applies to all plans and metrics by default); and
9. Click **"Add coupon"** to confirm.
The expiration date displayed in the app is based on the organization's timezone.
```bash Create a coupon theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/coupons" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"coupon": {
"name": "Startup Deal",
"code": "startup_deal",
"amount_cents": 5000,
"amount_currency": "USD",
"coupon_type": "fixed_amount",
"reusable": true,
"frequency": "recurring",
"frequency_duration": 6,
"expiration": "time_limit",
"expiration_at": "2022-08-08T23:59:59Z",
"applies_to": {
"plan_codes": ["premium"],
"billable_metric_codes": []
}
}
}'
```
## Apply coupons[](#apply-coupons "Direct link to heading")
If the currency of the customer is already defined, the currency of the coupon
must be the same, otherwise you will not be able to apply the coupon to the
customer.
To apply a coupon to a customer:
1. Select a customer from the list;
2. Click **"Actions"** in the upper-right corner and select **"Apply coupon"**;
3. Select a coupon;
4. Override values and currency; and
5. Click **"Apply coupon"** to confirm.
You can also apply coupons via the API ([learn more](/api-reference/coupons/apply)).
```bash Apply a coupon to a customer theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/applied_coupons" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"applied_coupon": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"coupon_code": "startup_deal",
"amount_cents": 6000,
"amount_currency": "EUR",
"frequency": "recurring",
"frequency_duration": 3
}
}'
```
## Application scope[](#application-scope "Direct link to heading")
You can apply several coupons to a customer. However, if a coupon has been
marked as non-reusable, you will only be able to apply it once to the customer
account, even if it has not been fully consumed. A coupon applied to a customer continues to apply beyond the expiration date.
Coupons are deducted from future subscription invoices. As mentioned previously, the value of
the coupon is deducted from the amount of the invoice before tax.
For coupons whose value is a fixed amount:
* **When the coupon only applies once** and its value is higher than the invoice
amount, the remaining unused amount will be applied to the following invoices,
until the coupon is totally consumed or removed; and
* **When the coupon is recurring** and its value is higher than the invoice amount,
any remaining unused amount will be lost, even if it is the last application
period.
When several coupons are applied to the customer account, they will be deducted according to the following rules:
* **Coupons limited to specific billable metrics will be deducted first** (if any, and if there is at least one subscription
associated with the relevant metric);
* **Coupons limited to specific plans will be deducted next** (if any, and if there is at least one subscription associated with the relevant plan); and
* **Coupons that apply to all plans** will be deducted according to the date on which they were applied (i.e. the coupon that was applied first will be deducted first).
You can see the remaining value / number of remaining periods for each coupon in
the **"Overview"** tab of the customer view.
Coupons do not apply to add-ons or any other one-off charges.
## Edit, terminate and delete coupons[](#edit-terminate-and-delete-coupons "Direct link to heading")
In the coupon view, you can click the **ellipsis icon** to see all available
actions:
1. **Edit**: allows you to modify the name, code and settings of the coupon;
2. **Terminate**: allows you to deactivate the coupon so that it cannot be
applied to any new customer (customers to whom the coupon has already been
applied continue to benefit from it); and
3. **Delete**: allows you to delete the coupon and remove it from the list (this
action cannot be undone).
You cannot modify the code, value and frequency of a coupon, or delete it, if
it has already been applied to a customer.
## Remove coupons[](#remove-coupons "Direct link to heading")
To remove a coupon that has been applied to a customer and is still active:
1. Select the customer;
2. Locate the coupon under **"Overview"**;
3. Click the **bin icon** on the right; and
4. Click **"Remove coupon"** to confirm.
The coupon will instantly disappear from the customer view and will not be
applied to the next invoice.
# Customer management
Source: https://getlago.com/docs/guide/customers/customer-management
## Create and update a customer[](#create-and-update-a-customer "Direct link to heading")
To create a customer through the user interface:
1. Access the **"Customers"** section via the side menu;
2. In the upper right corner, click **"Add a customer"**;
3. Enter the customer's name and external ID (i.e. unique ID as defined in your
backend system);
4. Select the customer's timezone (optional -
[learn more](/guide/customers/invoice-customer#bill-following-your-customers-timezone));
5. Enter the customer's billing information, including company information and
address (optional);
6. Select the default payment provider for this customer (optional -
[learn more](/guide/payments/payment-providers); and
7. Click **"Create customer"** to confirm.
```bash Create or update a customer theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"address_line2": "",
"city": "Woodland Hills",
"country": "US",
"currency": "EUR",
"email": "dinesh@piedpiper.test",
"legal_name": "Coleman-Blair",
"legal_number": "49-008-2965",
"tax_identification_number": "EU123456789",
"logo_url": "http://hooli.com/logo.png",
"name": "Gavin Belson",
"phone": "1-171-883-3711 x245",
"state": "CA",
"timezone": "Europe/Paris",
"url": "http://hooli.com",
"zipcode": "91364",
"tax_codes": [],
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"document_locale": "fr",
}
"metadata": [
{
"key": "Name",
"value": "John",
"display_in_invoice": true
}
]
}
}'
```
Once a customer is created, you can access the customer view, where you can edit their information.
You cannot change the `external_id` and the `currency` of customers after an object has been
assigned to them (i.e. plans, coupons, one-off invoices, wallet and credits).
## Companies vs Individuals
When creating or updating a customer, you can specify whether the customer is a `company` or an `individual` by setting the customer type.
By default, if no customer type is specified, the customer will be created without a defined type, and you will need to assign one manually.
## Assign objects to a customer[](#assign-objects-to-a-customer "Direct link to heading")
The usage monitoring and billing processes start when you assign a plan to a
customer, which triggers a [subscription](/guide/subscriptions/assign-plan).
You can also apply [coupons](/guide/coupons), [one-off invoices](/guide/one-off-invoices/create-one-off-invoices) and
[prepaid credits](/guide/wallet-and-prepaid-credits) to a customer account.
To assign objects to a customer through the user interface:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. In the upper right corner of the customer view, click **"Actions"**; and
4. Select an action from the dropdown list.
## Monitor the customer's current usage[](#monitor-the-customers-current-usage "Direct link to heading")
When a plan that includes usage-based charges is assigned to a customer, you can
start pushing [events](/guide/events/ingesting-usage) associated with the customer account.
During the billing period, the customer's current usage is visible in the
**"Analytics"** tab of the customer view, under **"Current usage report** including (but not limited to):
* Total amount for the period under consideration; and
* Breakdown by charge, including total number of billing units and amount.
You can retrieve the customer's current usage via the API using [this endpoint](/api-reference/customer-usage/get-current).
```bash Get customer current usage theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_CUSTOMER_ID="5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba"
EXTERNAL_SUBSCRIPTION_ID="sub_1234567890"
curl --location --request GET "$LAGO_URL/api/v1/customers/$EXTERNAL_CUSTOMER_ID/current_usage?external_subscription_id=$EXTERNAL_SUBSCRIPTION_ID" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
## Monitor the customer's billing status[](#monitor-the-customers-overdue-balance "Direct link to heading")
The "**Billing overview**" lets you see at a glance where a customer stands in terms of revenue and collection. It takes into account invoices since the customer's creation date.
* Gross revenue indicates how much has been billed to this customer
* Total overdue highlights the aggregated amount from invoices that are past due
You can retrieve the customer's gross revenue via the API using [this endpoint](/api-reference/analytics/gross-revenue).
```bash Get customer gross revenue theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/analytics/gross_revenue?external_customer_id=hooli_1234¤cy=USD" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
```
You can retrieve the customer's overdue balance via the API using [this endpoint](/api-reference/analytics/overdue-balance).
```bash Get customer overdue balance theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/analytics/overdue_balance?external_customer_id=hooli_1234¤cy=USD" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
```
## Deleting a customer
You may delete a customer linked to existing objects (i.e. applied coupons, wallets, subscriptions, add-ons).
If you do so:
* All [subscriptions](/guide/subscriptions/assign-plan) associated with this customer account will be immediately terminated (this action may trigger the generation of invoices and/or credit notes);
* All [coupons](/guide/coupons) applied to this customer account will be immediately terminated;
* The customer's active [wallet](/guide/wallet-and-prepaid-credits) will be immediately terminated and all remaining credits will be voided; and
* All `draft` invoices associated with this customer account will be immediately finalized.
`finalized` invoices and [credit notes](/guide/invoicing/credit-notes/overview) associated with the deleted customer remain available in the **"Invoices"** section of the user interface and can also be retrieved via the API.
It is possible to generate new credit notes and process refunds after the deletion of the customer.
After deleting a customer account, you can create a new one using the same `external_id`.
# Customer metadata
Source: https://getlago.com/docs/guide/customers/customer-metadata
## Add metadata on customer
Metadata on customer is useful for storing additional structured information on an object to provide more context.
For example, you could store a customer's full name and unique identifier from your system on a Customer object by defining a key-value pair. A key cannot exist without its corresponding value, and vice versa.
## Edit and delete metadata on customer
After adding metadata to a customer, you can edit or delete it. To edit metadata, you have two options:
1. Use the user interface to update the information displayed in the "Edit customer" drawer, and then save the customer changes.
2. Use the API to target the key-value pair information with the metadata ID in your code snippet and edit the key and value.
When editing customer metadata through the API, make sure to include the existing metadata in your payload to avoid removing them.
Similarly, you can delete a key-value metadata pair by:
1. Clicking on the trash icon in the user interface, and then saving the customer changes.
2. Removing the key-value metadata object from your code snippet when using the API.
## Display metadata in invoice object
To display customer metadata on invoices, you can switch on the option in the customer creation/edition drawer or set `display_in_invoice` to true. Once this option is activated, metadata will be displayed on all new finalized and downloaded invoices.
When the customer's metadata is added/edited/removed, the change only applies to new PDF files. Existing documents are not affected.
## Customer metadata limitation
1. We are limiting the number of metadata on customers to 5.
2. Keys must be strings under 20 characters.
3. Values must be strings under 100 characters.
# The customer portal
Source: https://getlago.com/docs/guide/customers/customer-portal
The Lago Customer Portal is a user-friendly platform that allows you to effortlessly share billing information, such as past invoices, with your end customers. As we continue to develop this tool, you will be able to display even more useful information to your customers.
## Generate a customer portal link
To generate a customer portal URL that can be embedded into your product, you have two options:
1. Use the [API endpoint](/api-reference/customers/customer-portal); or
2. Click the Customer Portal link on a specific customer details view.
## Embedding the dashboard
You can also use the API to generate an embeddable Customer Portal that can be displayed in your application by using an iframe. To do so, use the endpoint `/customers/:external_customer_id/portal_url` to generate an embeddable URL that can be displayed in your user interface.
For security reasons, the token returned by the API **expires after 12 hours**. Therefore, it is important to use the endpoint and generate a new token every time a customer refreshes or accesses the billing page.
## Customer portal preferred language
By default, the embedded portal is displayed in English. However, you can easily change the language for a specific customer by adjusting the `document language` in their settings. To access this feature, follow these simple steps:
To access document language settings:
1. Go to the specific customer's profile;
2. Click the **Settings** tab;
3. **Edit** the document language section; and
4. Select the preferred language.
You can also update the language of a customer directly from the API.
If the language you are looking for is not yet available, please [visit this page](/api-reference/resources/locales).
## Customer portal information
### 1. Invoice history
The invoice history section provides a summary of both total invoices (everything that has been invoiced since the beginning) and overdue invoices (all the invoices past their due date, which are due). Your customers can know where they stand in one glance.
The Customer Portal allows your customers to retrieve all past invoices and download them with ease. Lago displays useful billing information such as the issuing date, invoice number, amount, and payment status (paid or unpaid). Additionally, your customers can filter the list and search for a specific invoice.
### 2. Customer information
In addition to viewing their invoice list, customers can retrieve essential billing information, including legal name, tax identification number, billing email, and billing/shipping addresses.
Customers can also update this information directly through the portal, ensuring that their billing details remain synchronized with the latest data.
### 3. Plans and usage information
In addition to viewing their invoices and customer details, customers can access their subscriptions and usage directly through the portal.
For subscription details, they can view key information such as the plan name, recurring fee, and subscription renewal date.
Customers also have real-time access to comprehensive usage details, including:
* Total lifetime usage and the next threshold for subscriptions using progressive billing;
* A detailed usage report, showing the number of units consumed and associated costs; and
* A full breakdown of usage by billing filters and groups.
### 4. Prepaid credits information
The customer portal provides your customers with real-time access to their prepaid credit balance, showing the remaining credits based on their current usage.
Additionally, customers can top up their paid credits, ensuring their wallet is always sufficiently funded.
# Invoice a customer
Source: https://getlago.com/docs/guide/customers/invoice-customer
If a customer has an active subscription, Lago will automatically generate an [invoice](/guide/invoicing/overview) for them at the end of the billing period.
## Bill following your customer's timezone
**Premium feature ✨**:
The timezone feature is only available to users with a premium license. Please **[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago Self-Hosted Premium.
The beginning and end of the billing period depend on the timezone applied to the customer account. The default timezone is UTC but you can define another timezone for your organization, which can be overwritten by the customer's timezone.
To set the customer's timezone through the user interface:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. In the **"Overview"** tab of the customer view, click **"Edit"** above the customer details;
4. Select a timezone from the list; and
5. Click **"Edit customer information"** to confirm.
You can define a specific timezone by using the `timezone` field on a customer.
```bash Set a customer timezone {23} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"address_line2": "",
"city": "Woodland Hills",
"country": "US",
"currency": "EUR",
"email": "dinesh@piedpiper.test",
"legal_name": "Coleman-Blair",
"legal_number": "49-008-2965",
"tax_identification_number": "EU123456789",
"logo_url": "http://hooli.com/logo.png",
"name": "Gavin Belson",
"phone": "1-171-883-3711 x245",
"state": "CA",
"timezone": "Europe/Paris",
"url": "http://hooli.com",
"zipcode": "91364",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"document_locale": "fr",
"vat_rate": 12.5
},
"metadata": [
{
"key": "Name",
"value": "John",
"display_in_invoice": true
}
]
}
}'
```
The dates displayed in the **"Usage"**, **"Invoices"** and **"Credit notes"** tabs of the customer view are based on the customer's timezone.
You can hover over any date in the customer view to see the reference timezones.
## Preferred language
The default language for documents is defined at the organization level ([learn more](/guide/invoicing/download-invoices#translate-invoices)). It can be overwritten at the customer level.
To set the customer's preferred language:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. Open the **"Settings"** tab;
4. Click **"Add a language"**;
5. Select a language from the list; and
6. Click **"Add language"** to confirm.
You can define a specific preferred language by using the `document_locale` field on a customer, inside the `billing_configuration` object.
```bash Set a customer preferred language {32} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"address_line2": "",
"city": "Woodland Hills",
"country": "US",
"currency": "EUR",
"email": "dinesh@piedpiper.test",
"legal_name": "Coleman-Blair",
"legal_number": "49-008-2965",
"tax_identification_number": "EU123456789",
"logo_url": "http://hooli.com/logo.png",
"name": "Gavin Belson",
"phone": "1-171-883-3711 x245",
"state": "CA",
"timezone": "Europe/Paris",
"url": "http://hooli.com",
"zipcode": "91364",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"document_locale": "fr",
"vat_rate": 12.5
},
"metadata": [
{
"key": "Name",
"value": "John",
"display_in_invoice": true
}
]
}
}'
```
Please refer to the API documentation to see the [list of supported languages](/api-reference/resources/locales).
When the customer's preferred language is updated, the change only applies to new PDF files. Existing documents are not affected.
# Automatic dunning
Source: https://getlago.com/docs/guide/dunning/automatic-dunning
Automate customer communications to remind them of overdue invoices and recover outstanding balances through targeted dunning campaigns.
**PREMIUM ADD-ON** ✨
This feature is available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium feature.
## Create campaigns
Automatic dunning uses campaigns that can be applied billing entity-wide or tailored to individual customers. Create multiple campaigns to suit varying thresholds or cadences, all aimed at recovering overdue payments. To set up a new campaign, go to Settings > Dunning and follow these steps:
1. Assign a name, code, and description for easy identification.
2. Set an overdue balance threshold with its designated currency.
3. Add additional currencies for thresholds as needed.
4. Specify the delay between attempts.
5. Define the number of attempts for the campaign.
6. Apply this campaign to a billing entity or a customer.
### Overdue balance threshold
You can define thresholds for all supported currencies. When a customer reaches the specified threshold in their invoiced currency, the dunning campaign is triggered.
If a customer’s invoiced currency is not supported in the campaign, they will not be eligible for it.
### Attempts & delay
A dunning campaign begins when the overdue balance threshold is reached. Subsequent attempts follow the set delay. The campaign ends once the overdue balance is paid or all attempts have been exhausted.
### Apply dunning to a billing entity
Setting a campaign at the billing entity level applies it to all customers that inherit the billing entity’s dunning behavior — except those who either:
* Have a specific campaign assigned to them, or
* Have dunning deactivated.
Alternatively, you can leave the billing entity without a campaign and assign dunning campaigns individually to each customer.
## Automatic dunning on customer
If a campaign is set for the billing entity, it will automatically apply to all customers attached to it. However, you can override this at the customer level by either assigning a different dunning campaign or deactivating dunning for that specific customer.
### Change from one campaign to another
If you change the default campaign or assign a different campaign to a customer, any ongoing dunning process will stop. The new campaign will take precedence and start from the beginning.
## Dunning behaviour
1. **Automatic payment attempt**: Lago will initiate a payment intent for the specified amount via the connected PSP.
2. **Failed payment**: If the payment fails, an email will be sent to the customer with a payment request and a URL to complete the payment (excluding GoCardless).
3. **Successful payment**: Upon success, the attached invoices will automatically reflect a “succeeded” payment status.
1. **Payment request email**: An email will be sent to the customer requesting payment for the overdue balance.
2. **Manual update**: Once the payment is received, you must manually update the payment status of the relevant invoices
## Edit a dunning campaign
You can edit all details of a dunning campaign, but note that changes may directly impact customers linked to the campaign and could trigger new dunning attempts.
## Delete a dunning campaign
Deleting a dunning campaign will immediately stop the current campaign for all associated customers, and no further dunning attempts will be made. If the deleted campaign is not the default, customers linked to it will revert to the billing entity’s settings and may be enrolled in the default dunning campaign, if one is set.
# Manual dunning
Source: https://getlago.com/docs/guide/dunning/manual-dunning
Dunning refers to the process of communicating with customers to remind them of overdue invoices and attempt to recover the outstanding amounts.
## Overdue balance payment
When a customer has some invoices past their due date, their [overdue balance](https://docs.getlago.com/guide/customers/customer-management#monitor-the-customers-billing-status) becomes positive, and you have the ability to request its payment manually.
**Premium feature ✨**
This feature is only available to users with a premium license. Please **[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago Self-Hosted Premium.
In the customer view, a "request payment” link appears within the overdue balance warning.
By clicking on it, a panel opens so you can:
* Review the invoices included in the overdue balance,
* Review the email which will be sent in case the payment fails, or if no payment provider is linked
* Confirm you want to request the payment.
You can create a payment request for the overdue balance from the API, targeting the invoices you want to be paid.
```bash Create a payment request theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/payment_requests/" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
{
"payment_request": {
"lago_invoice_ids": ["4064eff9-e7a6-4692-a289-15d7d5da9b83", "b1f36d2f-8ea6-4192-9407-8e87ba5c28c2"],
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"email": "rebecca@piedpiper.test"
}
}'
```
## Dunning behaviour
1. **Automatic payment attempt**: Lago will initiate a payment intent for the specified amount via the connected PSP.
2. **Failed payment**: If the payment fails, an email will be sent to the customer with a payment request and a URL to complete the payment (excluding GoCardless).
3. **Successful payment**: Upon success, the attached invoices will automatically reflect a “succeeded” payment status.
1. **Payment request email**: An email will be sent to the customer requesting payment for the overdue balance.
2. **Manual update**: Once the payment is received, you must manually update the payment status of the relevant invoices
# Emails
Source: https://getlago.com/docs/guide/emails
Send automatic emails when issuing an invoice or any billing documents.
**PREMIUM FEATURE** ✨
Only users with a premium license can automatically send emails from Lago to their customers. Please **[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago Self-Hosted Premium.
With Lago, sending invoices and credit notes to your customers is simple - you can automatically email them as soon as they are created.
Lago will never ask for payment details or personal information.
## SMTP setup on Lago Cloud
By default, you don't have to worry about SMTP settings with Lago, we take care of it, so you can sit back and relax. However, we also offer custom SMTP for Enterprise customers.
## SMTP setup on Lago Self-hosted Premium
In order to use the email feature, please configure your environment variables [as described here](/guide/lago-self-hosted/docker#smtp-configuration).
## Prerequisites for sending emails
To send emails to your customers, you will need to:
1. Define an organization email in Settings > \[Your billing entity] > General > Information;
2. Optionally, add your organization’s logo;
3. Turn on the relevant email scenarios in Settings > \[Your billing entity] > Email scenarios;
4. Define the customer’s email address during customer creation/edition;
5. To send invoices to multiple recipients, define multiple email addresses at the customer level, separated by commas.
(e.g. `billing@acme.com`,`accounting@acme.com`,`finance@acme.com`)
## Email scenarios
Lago automatically sends email notifications to your customers in three key scenarios:
1. When an invoice is finalized (including subscription invoices, one-off invoices, or credit purchase invoices);
2. When a payment receipt is generated for a successful payment; and
3. When a credit note is issued to adjust or refund an invoice.
By default, all scenarios are switched off. To turn these scenarios on/off:
1. Go to Settings;
2. Open the Emails tab;
3. Toggle each scenario on/off; or
4. Click on a scenario to see the corresponding email; and
5. Use the toggle in the upper-right corner to switch this scenario on/off.
To avoid sending too many notifications to customers, we have deactivated emails for invoices without fees.
Although invoices with `"fees_amount_cents": 0` are not sent to customers by email, they are available in the database and user interface.
## Email locale
The content of the email will be based on the organization or customer's document locale. This means that the email will have the same locale as the invoice sent.
## Email sending address
For the cloud version, Lago uses [no-reply@getlago.com](mailto:no-reply@getlago.com) as the sending email address. Any responses from your customers will be directed to the email address you have established for your organization in the organization settings.
## Email template
As mentioned above, some information in the email template can be customized based on the settings of your account, including:
1. The logo of your organization;
2. The name of your organization; and
3. The email address of your organization.
## Resend emails
If you need to resend an invoice, a credit note or a receipt email, Lago makes it easy to do so with full control over the recipients. To resend an email:
1. Navigate to the specific invoice or credit note you want to resend;
2. Click on the **Resend email** button in the *Actions* menu;
3. In the dialog that appears, customize your recipients:
* **To**: Enter the main recipient email addresses
* **CC**: Add any recipients who should receive a copy
* **BCC**: Add any recipients who should receive a blind copy
4. Click **Resend** to send the email to your selected recipients.
You can send the email to different recipients than the original email. This is useful when you need to forward invoices to different departments or team members.
# Entitlements
Source: https://getlago.com/docs/guide/entitlements
Unify entitlements and billing in one streamlined platform with Lago.
In a billing system, entitlements define what a customer can access and how much they can use, based on their subscription or contract.
This includes feature gates, which control whether a feature is enabled or disabled for a given customer; feature privileges, which determine the level of access within a feature, such as basic or advanced functionality; allowances, which represent the included usage in a plan, like 100 API calls per month; and quotas, which are the maximum usage limits that may trigger overage charges or access restrictions. Together, these components help enforce product limits, manage access, and support accurate usage-based billing.
In addition to the usage-based engine for allowances and quotas, Lago lets you define Features and Entitlements.
## Set up your features
Lago supports the creation of any type of feature to tailor your billing logic. To create a new feature:
1. Navigate to the **Features** section in the sidebar;
2. Click on **Add a Feature** to start a new entry;
3. Give it a unique `code` (used for programmatic actions) and a `name`;
4. Assign one or more **privileges** to the feature (optional); and
5. Click **Create feature** to finalize and save the feature to your instance.
A feature in Lago represents a capability that can be gated behind a plan. It's not necessarily something you bill for directly, but rather something a customer gains access to based on their subscription.
```bash Create a feature theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/features \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"code": "seats",
"name": "Number of seats",
"description": "Number of users that can be added to the account"
}'
```
## Define feature privileges
Additionally, you can define privileges for a specific feature. Privileges allow you to configure more granular access controls across different plans. For example, the invite\_member feature might allow inviting 1 member on the *Free plan*, while offering unlimited invites on the *Pro plan*.
Feature privileges can be associated with the following types:
* **`boolean`** – The privilege value is either `true` or `false`.
* **`integer`** – The privilege value is a numeric limit (e.g., `10 GPUs`).
* **`string`** – The privilege value is freeform text.
* **`select`** – The privilege value is chosen from a predefined list of options.
At this stage, you're only defining the **type** of each privilege. The actual values will be set later, when the feature is entitled to a specific plan or subscription.
You can add an unlimited number of privileges to a feature.
```bash Create feature with privileges theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/features \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"code": "seats",
"name": "Number of seats",
"description": "Number of users that can be added to the account",
"privileges": [
{
"code": "max_",
"name": "Maximum seats",
"value_type": "integer"
},
{
"code": "min",
"name": "Minimum seats",
"value_type": "integer"
},
{
"code": "allow_admin_user",
"name": "Allow admin user",
"value_type": "boolean"
}
]
}'
```
## Map entitled features to your plans
Once your features have been created, they can be added to your plans through a process called **Entitlements**.
This is where you define features that are unlocked for a specific plan and the limits, values or privileges for each feature.
Entitlements define which features a customer is allowed to use based on the plan they are subscribed to. By assigning features to specific plans, you control access to functionality across your pricing tiers.
To assign features to a plan:
1. Create a new plan or edit an existing one;
2. Navigate to the **Advanced Settings** section;
3. Select the features you want to entitle for that plan; and
4. Configure the values for each feature's privileges according to the plan's rules.
```bash Create plan entitlements theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/plans/{code}/entitlements \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"seats": {
"max": 20,
"min": 10,
"allow_admin_user": false
},
"sso": {
"provider": "okta"
}
}'
```
## Override entitlements for a subscription
Some customers may subscribe to a standard plan but negotiate custom entitlements as part of their contract.
Just like charges, **you can override any entitlement value** for a specific subscription.
This creates an **overridden subscription**, where the custom entitlements apply **only** to that particular customer, without affecting the base plan or other subscribers.
```bash Create subscription entitlements theme={"dark"}
curl --request PATCH \
--url https://api.getlago.com/api/v1/subscriptions/{external_id}/entitlements \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"seats": {
"max": 30,
"min": 20,
"allow_admin_user": true
},
"sso": {
"provider": "okta"
}
}'
```
## Get entitlements for a subscription
You can retrieve the current list of entitled features for a subscription by calling the following endpoint:
```bash theme={"dark"}
curl --request GET \
--url https://api.getlago.com/api/v1/subscriptions/{external_id}/entitlements \
--header 'Authorization: Bearer '
```
You can also track entitlement changes through the `subscription.updated` webhook.
# Events list
Source: https://getlago.com/docs/guide/events/events-list
By ingesting events, you can see them flowing in the Lago application by using the events list. It allows you to take a deeper look at ingested events and detect possible warnings.
## Accessing the events list[](#accessing-the-events-list "Direct link to heading")
You can access the events list from the UI by following this path:
1. Go to the **Developers** section in the sidebar;
2. Click the **events** tab;
3. See a list of ingested events; and
4. Reload this list when you ingest new events.
By default, the UI shows you a list of the latest 20 events, but you can load
much more by scrolling down the page.
If an event is not shown in the UI, it has **not** been ingested.
## Accessing a specific event[](#accessing-a-specific-event "Direct link to heading")
In the events list view, by clicking on a specific event, you will have access to 2 main
blocks:
1. **A list of useful properties returned**
* **Time:** timestamp of the received events;
* **Customer ID:** the ID of your customer;
* **Billable metric code:** code of the billable metric linked to the event;
* **Billable metric name:** name of the billable metric linked to the event;
* **Transaction ID:** unique `transaction_id` of the event used as
idempotency key;
* **IP Address:** IP address of the event sender; and
* **Client API:** Lago Client API used to send the event.
2. **A JSON with event's arguments sent in the payload**
## Possible warnings[](#possible-warnings "Direct link to heading")
Some events can be ingested but trigger a bad or unexpected behavior. This is
why Lago displays in the UI two possible warnings:
1. The event `code` is **not related to an existing billable metric**; and
2. The billable metric's **property used for the aggregation is not sent**
through this event.
# Ingesting usage
Source: https://getlago.com/docs/guide/events/ingesting-usage
This guide explains how Lago ingests usage-based events coming from your application.
## Define a billable metric[](#define-a-billable-metric "Direct link to heading")
**Usage events are designed to target very specific
[billable metrics](/guide/billable-metrics/create-billable-metrics) created from the UI**. If you don't understand the
concept of billable metrics, we recommend reading it first.
First things first, you need to define a billable metric from the UI to send
usage measurement events:
1. In the Lago app, go to the **"Billable metrics"** section;
2. Click **"Add a billable metric"**;
3. Add metric information, including:
* `name`
* `code` (used to send events via API)
* `description` (optional)
4. Define whether or not this metric is `recurring`; and
5. Choose an aggregation type to define how usage should be calculated.
Billable metrics represent the features of your product. Events should automatically be sent to Lago by your application
based on your customers' actions.
## Send usage measurements to Lago[](#send-usage-measurements-to-lago "Direct link to heading")
To send usage events to Lago, you need to use the **Lago API**. A measurement
event is JSON with the following fields:
```json theme={"dark"}
{
"transaction_id": "__TRANSACTION_ID__", // (Required) Unique identifier of the event
"external_subscription_id": "__SUBSCRIPTION_ID__", // (Required) Unique identifier of your customer's subscription
"code": "__EVENT_CODE__", // (Required) The billable metric's code
"timestamp": 1650893379, // (Optional) UNIX timestamp of the event
"precise_total_amount_cents": "140", // (Optional) Precise amount cents of the event used for dynamic charge model
"properties": {
"custom_field": 12, // (Optional) Custom variables defined as properties
"operation_type": "add" or "remove" // (Optional) Required only for recurring metric based on the unique count aggregation
}
}
```
The `transaction_id` is very useful to ensure the uniqueness of the events
received. It is mandatory to define on your own a unique `transaction_id` for
each event you send to Lago.
This identifier is used to deduplicate events ingested, making sure we don't
ingest twice the same event (otherwise, this could create billing errors for
your customers).
* If a `transaction_id` is new to Lago, the event is ingested;
* If a `transaction_id` has already been received by Lago, it's ignored and API will return a `422: "Unprocessable Entity"`
If your Lago's organization is configured to use the new Clickhouse-based event pipeline (designed for high-volume processing), the idempotency logic is handled differently.
Event uniqueness is maintained with both `transaction_id` and `timestamp` fields:
* If `transaction_id` and `timestamp` are new to Lago, the event is ingested;
* If `transaction_id` and `timestamp` have already been received by Lago, the event will replace the previous one
**Good practice:**
Send the id of the transaction coming from your backend.
If you do not have an existing id for a transaction, you can create a unique one
by concatenating the `code` of the Billable metric and the `timestamp` of the
event \*(example: `api_searches_2022-04-01T03:49:23Z`).
This attribute allows Lago to assign the event to the right subscription (and therefore to the right customer).
The `external subscription_id` is required, as it ensures accurate billing.
The event `code` represents the unique code of the Billable metric you want to
start ingest measurements on. This code is required for all events received in
Lago. For instance, you can start ingesting events for Billable metrics with
codes `api_seaches` *(for api products example)*, `storage` *(cloud companies
example)*, `atm_withdrawals` *(fintech example)*, or anything you need to define
as a paying feature.
The event timestamp is the date when the billing event occurs in your
application and sent to Lago. This event must be a
**[UNIX Timestamp](https://www.unixtimestamp.com/).** For instance, you could
define `1650893379` for *Mon Apr 25 2022 13:29:39 GMT+0000* or `1651682217`for
*Wed May 04 2022 16:36:57 GMT+0000*.
You can ingest usage event in seconds or milliseconds. (more information about the timestamp [here](#event-timestamp))
**This `timestamp` is not mandatory to send the event**. If you do not specify a
timestamp on your own, Lago automatically defines the reception date of the
event as the event timestamp.
The event’s precise amount in cents refers to the amount sent to Lago when using a dynamic charge model.
This value must be specified in cents.
**The precise\_total\_amount\_cents is not mandatory when sending the event.** If you do not specify an amount, Lago will automatically set it to 0, and the event will not be included in the charge aggregation.
Event properties are useful to send more context in usage events. Moreover, they
are also very useful when you need to aggregate a Billable metrics for `SUM`,
`MAX` and `UNIQUE COUNT`. Event properties can be `strings`, `integers`,
`floats`, `uuids` or `timestamps`.
In case of an aggregation type `UNIQUE COUNT` for a metric that is `recurring`
, the `operation_type` is required.
By sending `add`, you will add a value. By sending `remove`, you will remove a value.
If you were using the `external_customer_id` to send usage measurement, note
that this field is deprecated and is no longer supported or maintained. Please
use the `external_subscription_id` instead.
## Idempotency and retries[](#idempotency-and-retries "Direct link to heading")
By using a unique `transaction_id`, you can send events to Lago as much as you want
without worrying about sending twice the same event. Duplicates will be ignored
by our system. This ensures that your customers' usage is counted once. In case
of duplicates, we guarantee that only one of the events will be ingested, and
the other ones are ignored.
In case you are not sure if an event has been ingested, we recommend you to send
it multiple times (or to replay it). Once again, with the uniqueness of the
`transaction_id`, your customers won't be badly affected.
If your Lago's organization is configured to use the new Clickhouse-based event pipeline (designed for high-volume processing), the idempotency logic is handled differently.
Event uniqueness is maintained with both `transaction_id` and `timestamp` fields:
* If `transaction_id` and `timestamp` are new to Lago, the event is ingested;
* If `transaction_id` and `timestamp` have already been received by Lago, the event will replace the previous one
## Event timestamp
We typically **log usage-based events using timestamps in seconds**, such as `1741219251`, which represents the number of seconds since January 1, 1970 (the Unix epoch).
However, when higher precision is required, **you can also use a timestamp with millisecond accuracy** in the format `1741219251.590`. Here, the dot acts as the decimal separator, clearly distinguishing the whole seconds from the fractional milliseconds (590 ms in the previous example).
This format minimizes ambiguity and ensures consistency when sending usage-based events.
## User action trigger or periodic trigger[](#user-action-trigger-or-periodic-trigger "Direct link to heading")
With Lago, you can define when you need to trigger events based on the actions
your customers make in your application. There are 2 ways of tracking billing
events with Lago.
### User action trigger[](#user-action-trigger "Direct link to heading")
Anytime a user performs an action in your product, this sends an event to Lago.
This can be useful for companies tracking usage with a lot of granularity. As we
do the math for you, you can send events whenever you need and don't compute
hard calculations on your own.
For instance, think of a *fintech company* tracking user action. Each time a
customer withdraw money at an ATM, you send an event to Lago. We aggregate the
usage of a billable period based on what you defined in a Billable metric called
`atm_withdrawals`.
### Periodic trigger[](#periodic-trigger "Direct link to heading")
Some companies, such as infrastructure or cloud ones, often use periodic
triggers to calculate consumption. Think of the example of a thermometer to
measure fever. We would probably track the temperature once per hour (at a
periodic time). This is the same for cloud companies selling computation. You
could send an event to Lago each single minute measuring the CPU consumption of
a customer.
## Batching events
In Lago, event batching allows for the efficient ingestion of multiple events through a single API call.
This capability enhances data throughput and reduces the number of API requests needed for event management.
* **Batching multiple events:** Users can aggregate multiple events into a single batch. This consolidation enables the ingestion of numerous events simultaneously, significantly optimizing the data transmission process.
* **API call limitation:** Lago supports batching of up to 100 events per API call. This feature is designed to balance between high-volume data handling and system performance.
* **Validation process:** If any event within the batch does not meet the structural requirements, the entire batch will be rejected. This ensures data integrity and consistency. Users are advised to verify the structure of each event before batching to prevent rejections.
## Designed for flexibility[](#designed-for-flexibility "Direct link to heading")
Lago is designed to ingest a high number of events. By defining aggregation
rules, you can define any billing use cases your company might want to track.
Whether you need to send **[user action triggered](#user-action-trigger)**
events or **[periodic triggered](#periodic-trigger)** events, Lago does the math
on your own so you don't have to query heavy databases before charging your
customers.
## Next steps[](#next-steps "Direct link to heading")
Once you defined your Billable metrics (with their aggregation rules), and
started ingesting events to track usage, you are able to define how much your
customers will pay for it. This has to be specified in
**[Plans](/guide/plans/overview)**.
# Metering ingestion sources
Source: https://getlago.com/docs/guide/events/metering-source
Here is a list of sources you can use to ingest usage data. Some of these sources are capable of handling up to 15,000 events per second with default settings.
## Free sources
Here is the list of usage ingestion and metering sources available in the free version of Lago.
Establishes a connection to a server and continuously sends requests for a specific message.
## Premium sources
Here is the list of usage ingestion and metering sources available in the premium version of Lago.
**PREMIUM ADD-ON** ✨
Premium ingestion sources are available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium feature.
Receives messages from multiple Kinesis streams.
Fetches objects from an S3 bucket, with optional prefix filtering, either by listing items or through real-time upload notifications.
Retrieves and processes messages from an AWS SQS queue using a specified URL.
Transmits usage and metering data via Azure CosmosDB, Queue Storage, or Table Storage.
Monitors a CockroachDB Core Changefeed and creates a message for each received row.
Reads data from one or more CSV files
Transmits usage and metering data via GCP Big Query or Cloud Storage bucket.
Establishes a connection to Kafka brokers and consumes messages from one or more topics.
Runs a query in MongoDB and produces a message for every document returned.
Transmits usage and metering data via Redis Scan or Streams.
Transmits usage and metering data via SQL raw or select.
Establishes a connection to a websocket server and continuously sends usage for incoming messages.
# Retrieving usage
Source: https://getlago.com/docs/guide/events/retrieve-usage
Learn how to retrieve usage data for both current and past billing periods.
## Retrieve current usage
The [current usage endpoint](../../api-reference/customer-usage/get-current) retrieves real-time usage data for the current open billing period.
Because this billing period is still ongoing, invoice details are subject to change as new usage continues to accrue.
Whether it's fetched from the UI or the API, the response includes:
1. Aggregated usage data for the current period: Total units consumed and total customers' cost (so far)
2. Detailed breakdowns per metric: Units and amounts by metric and optional sub-breakdowns by filters or groupings (e.g., per project, environment, or AI models)
Note: Since the billing period is not yet finalized, the retrieved data should be treated as provisional. Final invoice values may differ.
Notice that if the events were sent with a timestamp in the future, they are taken into account in current usage. Yet, if you terminate the
subscription before the timestamp of this event, it will be ignored in the termination invoice.
```bash Retrieve current usage theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_CUSTOMER_ID="__EXTERNAL_CUSTOMER_ID__"
EXTERNAL_SUBSCRIPTION_ID="__EXTERNAL_SUBSCRIPTION_ID__"
curl --location --request GET "$LAGO_URL/api/v1/customers/$EXTERNAL_CUSTOMER_ID/current_usage?external_subscription_id=$EXTERNAL_SUBSCRIPTION_ID" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
## Retrieve projected usage
Another endpoint provides an estimate of usage and billing amounts projected through the end of the current billing period.
It uses current consumption trends and billing configuration to forecast the likely totals at period close. Projected usage is listed under the [projected usage endpoint](../../api-reference/customer-usage/get-projected).
Whether it's fetched from the UI or the API, the response includes:
1. Projected total usage units and estimated billing amount for the full billing period
2. Per-metric projections, including: Forecasted units and amounts for each billable metric and projections broken down by optional sub-filters or groups (e.g., per project, environment, or AI models)
Note: Recurring metrics, such as Seats, typically remain stable over time, unlike metered metrics which fluctuate. Therefore, the projected usage for a recurring metric is assumed to be equal to its current usage.
```bash Retrieve projected usage theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_CUSTOMER_ID="__EXTERNAL_CUSTOMER_ID__"
EXTERNAL_SUBSCRIPTION_ID="__EXTERNAL_SUBSCRIPTION_ID__"
curl --location --request GET "$LAGO_URL/api/v1/customers/$EXTERNAL_CUSTOMER_ID/projected_usage?external_subscription_id=$EXTERNAL_SUBSCRIPTION_ID" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
## Retrieve past usage
The [past usage endpoint](../../api-reference/customer-usage/get-past) allows you to retrieve customer usage data for closed billing periods.
Once a billing period has ended and is marked as closed, the associated usage data becomes final and immutable, ensuring consistency in billing and reporting.
Modifying the price of a metric, or even deleting a metric, has no effect on past usage or previously issued invoices.
Once a billing period is closed and its associated invoice is finalized, the past usage quantities, pricing, and resulting fees are locked.
```bash Retrieve current usage theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_CUSTOMER_ID="__EXTERNAL_CUSTOMER_ID__"
EXTERNAL_SUBSCRIPTION_ID="__EXTERNAL_SUBSCRIPTION_ID__"
curl --location --request GET "$LAGO_URL/api/v1/customers/$EXTERNAL_CUSTOMER_ID/past_usage?external_subscription_id=$EXTERNAL_SUBSCRIPTION_ID" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
# Integration testing
Source: https://getlago.com/docs/guide/integration-testing
This step-by-step integration guide will help you get started with Lago.
## Foreword[](#foreword "Direct link to heading")
At the moment, each Lago account is associated with a unique environment. It is
currently not possible to have your test environment and production environment
in the same account.
However, we can suggest different workarounds:
1. **Create two accounts** to get access to two environments, one that could be
called "Company Staging" and another one that could be called "Company
Production"; or
2. **Leverage our two hosting solutions** to use Lago Cloud as a test
environment and Lago Open Source as a production environment (or vice versa).
Please note that the above workarounds will require you to replicate the same
setup in both environments.
In the future, you will be able to get access to a test environment and a
production environment with the same Lago account.
## 1. Define a billable metric[](#1-define-a-billable-metric "Direct link to heading")
To define a billable metric through the user interface:
1. In the side menu, select **"Billable metrics"**;
2. Click **"Add a billable metric"** in the upper right corner;
3. Fill in the form ([learn more about billable metrics](/guide/billable-metrics/create-billable-metrics)); and
4. Click **"Add billable metric"** to save.
## 2. Create a plan (with charges)[](#2-create-a-plan-with-charges "Direct link to heading")
To create a plan through the user interface:
1. In the side menu, select **"Plans"**;
2. Click **"Add a plan"** in the upper right corner;
3. Fill in the form ([learn more about plans](/guide/plans/overview)); and
4. Click **"Add plan"** to save.
## 3. Create a customer[](#3-create-a-customer "Direct link to heading")
To create a customer through the user interface:
1. In the side menu, select **"Customers"**;
2. Click **"Add a customer"** in the upper right corner;
3. Fill in the form in the pop-up window
([learn more about customers](/guide/customers/customer-management)); and
4. Click **"Add customer"** to save.
You can also create customers through the API, as described in the
[documentation](/api-reference/customers/create).
## 4. Start a subscription[](#4-start-a-subscription "Direct link to heading")
To start a subscription, you need to assign a plan to an existing customer. To
do so through the user interface:
1. In the side menu, select **"Customers"**;
2. Select a customer from the list;
3. On the right-hand side, click **"Add a plan"**;
4. Select the plan you would like to assign to your customer; and
5. Click **"Add plan"** to confirm.
A success toast will be displayed and the new subscription will appear in the
customer view.
You can also start a subscription through the API, as described in the
[documentation](/api-reference/subscriptions/assign-plan).
## 5. Send usage-based events[](#5-send-usage-based-events "Direct link to heading")
Events sent from your backend to Lago will be automatically aggregated according
to the predefined billable metrics. To start sending usage-based events, please
refer to the [documentation](/guide/events/ingesting-usage).
## 6. Invoice your customers[](#6-invoice-your-customers "Direct link to heading")
At the end of the billing period, Lago will automatically generate an invoice
for each customer. Invoices will be sent to your application using webhooks. To
define the URL to which the webhooks will be sent:
1. In the side menu of the user interface, select **"Developers"**;
2. On the right-hand side, click **"Add a webhook"**;
3. Enter the URL of your application; and
4. Click **"Add webhook"** to confirm.
To learn more about webhooks and invoices, please refer to the
[API documentation](/api-reference/invoices/invoice-object).
# Welcome to Lago
Source: https://getlago.com/docs/guide/introduction/welcome-to-lago
Lago is an open-source software for metering and usage-based billing. It's the best alternative to Chargebee, Recurly or Stripe Billing for companies that need to handle complex billing logic.
This library will allow you to build an entire billing system from scratch. Lago is a real-time, event-based solution made for usage-based billing, subscription-based billing, and all the nuances of pricing in between.
You can use the [self-hosted version](/guide/lago-self-hosted/docker) to deploy Lago on your existing infrastructure or [request access to Lago Cloud](https://getlago.com/book-a-demo) to start using our solution immediately.
## Five-step billing workflow[](#five-step-billing-workflow "Direct link to heading")
### 1. Usage ingestion[](#1-event-ingestion "Direct link to heading")
[Events](/guide/events/ingesting-usage) provide information about your customers'
consumption, with the highest level of granularity. Any product feature for
which you want to charge your customers should correspond to a specific event.
An event can be triggered by an action or can be sent periodically. Lago is able
to ingest events at scale while preventing duplicates.
### 2. Metrics aggregation[](#2-metrics-aggregation "Direct link to heading")
The aggregation process consists of converting events into
[billable metrics](/guide/billable-metrics/create-billable-metrics). There are 4 aggregation types:
| Aggregation | Description | Type |
| -------------- | ------------------------------------------------------------------------------------------------------ | -------------------- |
| `COUNT` | Counts the number of times an incoming event occurs | Metered |
| `COUNT_UNIQUE` | Returns the number of unique values of a predefined property for incoming events | Metered or Recurring |
| `LATEST` | Returns the latest value of a predefined property for incoming events | Metered |
| `MAX` | Returns the maximum value of a predefined property for incoming events | Metered |
| `SUM` | Calculates the sum of a predefined property for incoming events | Metered or Recurring |
| `WEIGHTED SUM` | Calculates the sum of a predefined property for incoming events prorated based on time used per period | Metered or Recurring |
### 3. Pricing and packaging[](#3-pricing "Direct link to heading")
Creating [plans](/guide/plans/overview) allows you to define how much your customers
should pay for using your product. You can then combine plans and billable
metrics to implement any billing model (i.e. subscription-based, usage-based, or
hybrid). Billable metrics may be priced differently depending on the associated
plan.
### 4. Invoicing[](#4-invoicing "Direct link to heading")
Lago automatically generates [invoices](/guide/invoicing/overview) for each customer
according to the plan model: the subscription fee can be billed at the beginning
or at the end of the billing period while usage-based charges are always
calculated at the end of the billing period. Invoices include fees, taxes and
customer information.
### 5. Payments[](#5-payments "Direct link to heading")
When an invoice is emitted and finalized, it's ready for payment collection.
Connect payment providers through [native integrations](/guide/payments/payment-providers) or
trigger payments on any PSPs using the invoice payload created by Lago.
# Why billing is a nightmare
Source: https://getlago.com/docs/guide/introduction/why-billing-is-a-nightmare
The original version of this article is available on [our
blog](https://www.getlago.com/blog/why-billing-systems-are-a-nightmare-for-engineers).
> *"On my first day, I was told: 'Payment will come later, shouldn't be hard
> right?'*
>
> *I was worried. We were not selling and delivering goods, but SSDs and CPU
> cores, petabytes and milliseconds, space and time. Instantly, via API.
> Fungible, at the smallest unit. On all continents. That was the vision.*
>
> *After a week, I felt like I was the only one really concerned about the long
> road ahead. In ambitious enterprise projects, complexity compounds quickly:
> multi-tenancy, multi-users, multi-roles, multi-currency, multi-tax codes,
> multi-everything. These systems were no fun, some were ancient, and often
> 'spaghetti-like'.*
>
> *What should have been a one-year R\&D project ended up taking seven years of
> my professional life, in which I grew the billing team from 0 to 12 people. So
> yes, if you ask me, billing is hard. Harder than you think. It's time to solve
> that once and for all."*
>
> Kevin Deldycke, former VP Engineering at Scaleway
This is a typical conversation we have with engineers on a daily basis.
After my last post about my
['pricing hack'](https://www.getlago.com/blog/pricing-my-only-growth-hack-at-qonto),
some of you asked me why billing was that complex. My co-founder Raffi took up
the challenge of explaining why it's still an unsolved problem for engineers.
We also gathered insights from other friends who went through the same painful
journey, including Algolia, Segment, Pleo... don't miss them! Passing the mic to
Raffi.
When you're thinking about automating billing, this means your company is
getting traction. That's good news!
You might then wonder: should we build it in-house? It does not look complex,
and the logic seems specific to your business.
Our team at Lago still has some painful memories of Qonto's internal billing
system, that we had to build and maintain. Why was it so painful? In this
article, I will provide a high-level view of the technical challenges we faced
while implementing hybrid pricing (based on subscription and usage) and what we
learned during this journey.
## TL;DR: Billing is just 100x harder than you will ever think[](#tldr-billing-is-just-100x-harder-than-you-will-ever-think "Direct link to heading")
"Let's bill yearly as well, should be pretty straightforward" claims the Revenue
team. Great! Everyone is excited to start working on it. Everyone, except the
Tech team. When you start building your internal billing system, it's hard to
think of all the complexity that will pop up down the road, unless you've
experienced it before.
It's common to start a business with a simple pricing. You define one or two
price plans and limit this pricing to a defined number of features. However,
when the company is growing, your pricing gets more and more complex, just like
your entire codebase.
At Qonto, our first users could only onboard on a €9 plan. We quickly decided to
add plans, and 'pay-as-you-go' features (e.g. ATM withdrawals, foreign currency
payments, capital deposit, etc.) to grow revenue.
Also, as Qonto is a neobank, we wanted to charge our customers' wallets
directly, through a ledger connected to our internal billing system. The team
started from a duo of full-time engineers building a billing system (which is
already a considerable investment) to a dedicated cross-functional Pricing team.
This is not specific to Qonto of course. Pleo, another fintech unicorn from
Denmark faced similar issues:
> *"I've learned to appreciate that billing systems are hard to build, hard to
> design, and hard to get working for you if you deviate from 'the standard'
> even by a tiny bit."*
>
> Arnon Shimoni, Product Billing Infrastructure Lead at Pleo
This is not even specific to fintechs. The Algolia team ended up creating a
whole pricing department, now led by Djay, a pricing and monetization veteran
from Twilio, VMWare, Service Now. They switched to a 'pay-as-you-go' pricing
model based on the number of monthly API searches.
> *"It looks easy on paper — however, it's a challenge to bring automation and
> transparency to a customer, so they can easily understand. There is a lot of
> behind-the-scenes work that goes into this, and it takes a lot of engineering
> and investment to do it the right way."*
>
> Bernardette Nixon, CEO at Venture Beat
## Dates[](#dates "Direct link to heading")
When implementing a billing system, dealing with dates is often the number 1
complexity. Somehow, all your subscriptions and charges are based on a number of
days. Whether you make your customers pay weekly, monthly or yearly, you need to
define the billing period.
Here is a non-exhaustive list of difficulties for engineers:
1. How to deal with leap years?
2. Do your subscriptions start at the beginning of the month or at the creation
date of the customer?
3. How many days/months of trial do you offer?
4. Who decided February only holds 28 days?
5. Wait, point 1 is also important for February...
6. How to calculate usage-based charges (price per second, hour, day)?
7. Do I resume the consumption or do I stack it month over month? Year over
year?
8. Do I apply a pro-rata based on the number of days consumed by my customer?
Although every decision is reversible, billing cycle questions are often the
most important source of customer support tickets, and iterating on them is
quite complex. For instance, Qonto switched from 'anniversary' dates to calendar
dates for its billing periods (see
[here](https://medium.com/qonto-way/biller-migration-how-we-changed-our-billing-cycle-cf3c4cdd7cf4)).
This change was not trivial.
## Upgrades & Downgrades[](#upgrades--downgrades "Direct link to heading")
You need to allow your customers to upgrade or downgrade their subscriptions.
Moving from plan A to plan B seems pretty easy, but it's not. Let's zoom in on
potential edge cases.
What should we do when the user:
1. Upgrades or downgrades in the middle of a period;
2. Has paid for the original plan in advance;
3. Needs to pay for the original plan in arrears;
4. Downgrades from a yearly plan to a monthly plan;
5. Upgrades from a monthly plan to a yearly plan;
6. Upgrades or downgrades from a plan paid in advance to a plan paid in arrears
(and vice-versa); or
7. Has a discount and upgrades/downgrades?
We did not have a free trial period at the time at Qonto, but Arnon from Pleo
describes this situation
[here](https://arnon.dk/5-things-i-learned-developing-billing-system/).
## Usage-based computations[](#usage-based-computations "Direct link to heading")
Subscription-based billing is the first step when implementing a billing system.
Each customer needs to be affiliated with a plan in order to start charging the
right amount at the right time.
But for a growing number of companies, like Qonto, other charges come alongside
this subscription. These charges are based on what customers really consume.
This is what we call 'usage-based billing'. Most companies end up having a
hybrid pricing model: a monthly subscription fee and 'add-ons' or
'pay-as-you-go' charges on top of it.
These consumption-based charges are tough to track at scale, because they often
come with calculation rules performed on a high volume of events.
Here are some examples:
Segment's pricing is based on the number of monthly tracked users. This means
that they need to count the distinct number of users each month and reset this
value to zero for the next billing period. In order to retrieve the number of
unique visitors, they need to apply a 'distinct' function to deduplicate them.
Algolia tracks the number of API searches per month. This means they need to sum
the number of monthly searches for each customer and reset this value to zero
for the next billing period.
It becomes even more complex when you start calculating charges based on a
timeframe. For instance, Snowflake charges for the compute usage of a data
warehouse per second. This means that they sum the number of gigabytes or
terabytes consumed, multiplied by the number of seconds of compute time.
Consider the example of a utility company that charges \$10 per kilowatt of
electricity per hour. The illustration below shows what needs to be modeled and
automated by the billing system.
* **Hour 1**: 10 KW used for 0.5 hour = 5 KW (10 x 0.5)
* **Hour 2**: 20 KW used for 1 hour = 20 KW (20 x 1)
* **Hour 3**: 0 KW used for 1 hour = 0 KW (0 x 1)
* **Hour 4**: 30 KW used for 0.5 hour = 15 KW (30 x 0.5)
* **TOTAL** = 40 KW used x $10 ⇒ $40
## Idempotency done right[](#idempotency-done-right "Direct link to heading")
Billing errors sometimes occur. Charging a user twice for the same product is
obviously bad for the customer experience, but failing to charge when needed
hurts revenue. That's partly why Finance and BI teams spend so much time on
revenue recognition.
For 'pay-as-you-go' companies, the billing system will process a high volume of
events. When an event needs to be replayed, it needs to happen without billing
the user again. Engineers call it 'idempotency', which means the **ability to
apply the same operation multiple times without changing the result beyond the
first try**.
It's a simple design principle, however, maintaining it at all times is hard.
## The case for a Cash Collection Officer[](#the-case-for-a-cash-collection-officer "Direct link to heading")
Cash collection is the process of collecting the money that customers owe you.
The pet peeve of cash collection is dunning: when payments fail, the merchant
needs to persist and make repeated payment requests to their customers, while
trying not to damage the relationship.
At Qonto, we called these 'waiting funds'. A client's status was 'waiting funds'
when they successfully went through the sign-up, KYC and KYB process but their
account balance was still 0.
For a neobank, the impact is twofold: you can't charge your service fees (e.g.
monthly subscription) and your customer does not generate interchange revenues
(e.g. when you make a payment of $100 with your card, the card issuer earns
$0.5-\$1 of interchange revenue through the merchant's fees).
Therefore, your two main revenue streams are 'null' but you did pay to acquire,
onboard, KYC the user and then to produce and send them a card. We often
half-joked about the need to hire a 'chief waiting funds officer': the financial
impact of this is just as high as the problem is underestimated.
All companies face dunning challenges. For engineers, on top of the billing
architecture, this means that they need to design and build:
1. A **'retry logic'** to ask for a new payment intent;
2. An **invoice reconciliation system** (e.g. if several months of charges are
recovered);
3. An **app logic to disable access** to the service; and
4. An **emailing workflow** to urge a user to proceed to the payment.
Some SaaS are even on a mission to fight dunnings and have built full-fledged
companies around cash collection, such as Upflow, which is used by successful
B2B scale-ups, including Front and Lattice.
> *"Sending quality and personalized reminders took us a lot of time and, as
> Lattice was growing fast, it was essential for us to scale our cash collection
> processes. We use Upflow to personalize how we ask our customers for money,
> repeatedly, while keeping a good relationship. We now collect 99% of our
> invoices, effortlessly."*
>
> Jason Lopez, Controller at Lattice
## The labyrinth of taxes and VAT[](#the-labyrinth-of-taxes-and-vat "Direct link to heading")
Taxes are challenging and depend on multiple dimensions. Taxes depend on what
you are selling, your home country and your customer's home country. In the
simplest situations, your tax decision tree should look like this:
Now, imagine that you sell different types of goods/services to different types
of customers in 100+ countries. If you think the logic on paper looks complex,
the engineering challenge is tenfold. Engineers need to think of an entire tax
logic within the application. This pyramidal logic is based on customers and
products, including:
1. **Taxes at company level**: your company will have a general tax rate that
applies to all customers by default;
2. **Taxes at customer level**: the default tax rate can be overridden for each
customer, depending on the dimensions mentioned above (see illustration); and
3. **Taxes at feature level**: this is mostly the case for the banking industry.
At Qonto for instance, banking fees are not subject to taxes but a 20% VAT
rate applies to non-banking features.
With billing, the devil's in the detail, which is why I always cringe when I see
engineering teams build a home-made system, just because they think "it's not
that complex".
If you've already tackled the topics listed above and think it's a good
investment of your engineering time, go ahead and build it in-house, but make
sure to budget for the maintenance work that is always needed. Another option is
to rely on existing billing platforms, built by specialized teams.
To solve this problem at scale, we've adopted a radical approach: we're building
an open-source billing API for product-led SaaS. Our API and architecture are
open, so that you can embed, fork and customize them as much as your pricing and
internal processes require.
If you're interested, you can [get started](https://www.getlago.com/get-started)
here or [book a demo](https://getlago.com/book-a-demo).
# Credit note metadata
Source: https://getlago.com/docs/guide/invoicing/credit-notes/credit-note-metadata
Metadata on a credit\_note object allows you to store additional structured information and context. This is especially useful when integrating Lago with external systems.
For example, after creating a credit note, you can save your government-issued credit note ID, the synchronization status with your ERP, or any internal reference needed for your workflows.
Metadata is stored in the `credit_note` object but is **not** displayed on the PDF file.
## Add metadata on credit note
To add metadata:
1. Go to the credit note detail page for the credit note you want to update.
2. Click **“Add metadata.”**
3. Enter your key–value pairs.
4. Click **Save** to confirm.
```bash Add metadata when creating a credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOU_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/credit_notes" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"credit_note": {
…
"metadata": {
"sync_to_netsuite": "false",
"sync_to_salesforce": "false"
}
}'
```
```bash Add metadata to an existing credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOU_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/credit_notes/:lago_id/metadata" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"metadata": {
"sync_to_netsuite": "false",
"sync_to_salesforce": "false"
}
}'
```
## Edit metadata on credit note
To edit metadata on a credit note:
1. Navigate to the credit note detail page.
2. Click **“Edit metadata.”**
3. Add, update key–value pairs.
4. Save your changes.
```bash Edit or add metadata on a credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOU_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request PATCH "$LAGO_URL/api/v1/credit_notes/:lago_id/metadata" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"metadata": {
"sync_to_netsuite": "true",
"netsuite_id": "cn_1234567890"
}
}'
```
```bash Replace all metadata on a credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOU_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/credit_notes/:lago_id/metadata" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"metadata": {
"sync_to_netsuite": "true",
"netsuite_id": "cn_1234567890"
"sync_to_salesforce": "false"
}
}'
```
## Delete metadata on credit note
To delete metadata on a credit note:
1. Open the credit note detail page.
2. Click **“Edit metadata.”**
3. Click the trash icon next to the key–value pair you want to remove.
4. Save your changes.
```bash Delete a specific metadata key theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOU_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/credit_notes/:lago_id/metadata/:key" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
```bash Delete all metadata on a credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOU_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request DELETE "$LAGO_URL/api/v1/credit_notes/:lago_id/metadata" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
## Credit note metadata limitations
1. A maximum of 50 metadata key–value pairs is allowed per credit note.
2. Keys must be strings of up to 40 characters.
3. Values must be strings of up to 255 characters.
# Overview
Source: https://getlago.com/docs/guide/invoicing/credit-notes/overview
**PREMIUM FEATURE** ✨
Lago may automatically generate a credit note when a subscription is upgraded or
downgraded. However, only users with a premium license can manually generate
credit notes via the user interface or the API. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
Use credit notes to correct an invoice while keeping your financial records accurate.
Credit notes can be issued for **all invoice types**.
## Access credit notes creation flow[](#create-credit-notes "Direct link to heading")
Credit notes can only be issued for invoices with status `finalized` and an amount **greater than zero**.
To create a credit note from the Dashboard:
1. Open the invoice
2. Go to the **Credit notes** tab
3. Click **Issue a credit note**
The available methods depend on the payments recorded on the invoice:
* Credit the full invoice amount (tax included) for future use
* Refund the paid amount
* Offset the remaining invoice amount due
For **subscription invoices**, prepaid credits and applied credit notes cannot be refunded.
They can only be credited back to the customer’s account for future use.
Coupons are non-refundable and cannot be credited back.
### Prepaid credit invoices
Prepaid credit invoices follow specific rules:
* **If a payment is recorded:** You can refund the available wallet balance. This immediately voids the credits from the wallet.
* **If no payment is recorded:** You can only offset the invoice. The wallet transaction is not settled and the wallet balance remains unchanged.
## Issue a credit note
1. Select a reason from the list (e.g. duplicate charge, order cancelation,
etc.);
2. Add an internal note (optional);
3. Select the item(s) and enter the amount(s) you want to credit;
4. Select the credit method(s) (only available for paid invoices -
[learn more](#credit-methods)); and
5. Click **"Issue credit note"** to confirm.
For each item, you must enter a credit amount equal to or less than the
initial amount of the item, excluding tax. The total amount of the credit note
cannot exceed the total amount of the invoice.
```bash Create a credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/credit_notes" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"credit_note": {
"invoice_id": "**LAGO_INVOICE_ID**",
"reason": "duplicated_charge",
"credit_amount_cents": 10,
"refund_amount_cents": 5,
"offset_amount_cents": 0,
"items": [
{
"fee_id": "__LAGO_FEE_ID__",
"amount_cents": 10
},
{
"fee_id": "__LAGO_FEE_ID__",
"amount_cents": 5
}
]
}
}'
```
Once created, the credit note:
* Appears in the Credit notes tab of the customer and invoice views
* Triggers a `credit_note.created` [webhook](/api-reference/webhooks/messages)
You can issue **multiple credit notes** on a single invoice.
Each credit note has a unique number and can be downloaded as a PDF.
## Credit methods[](#credit-methods "Direct link to heading")
### Offset[](#offset "Direct link to heading")
If the invoice has an amount due greater than zero, you can offset it.
This reduces the invoice amount due. Once it reaches zero, Lago automatically marks `invoice.payment_status` as `succeeded`.
### Refund[](#refund "Direct link to heading")
If a payment has been recorded, you can refund the paid amount.
* If the customer is connected to a payment provider, Lago automatically triggers the refund.
* The credit note includes a `refund_status`, updated to `pending`, `succeeded`, or `failed`.
If no payment provider is connected, refund handling and `refund_status` updates are the user’s responsibility.
### Credit note wallet[](#credit-note-wallet "Direct link to heading")
You can credit an amount for future use instead of refunding it.
The credited amount is stored in a single credit note wallet and visible in the customer’s Credit notes tab.
This balance is automatically applied to future subscription invoices.
Credit note wallets are different from wallets associated with [prepaid credits](/guide/wallet-and-prepaid-credits).
The total amount available in the credit note wallets will be deducted from the
subtotal of the customer's next invoice(s), after tax (see below).
```
## EXAMPLE OF INVOICE
All subscriptions fee $50.00
All usage-based fees $20.00
Coupons -$10.00
-------------------------------
Subtotal (excl. tax) $60.00
Tax (10%) $ 6.00
-------------------------------
Subtotal (incl. tax) $66.00
Credit notes $20.00
Prepaid credits $30.00
-------------------------------
Total $16.00
```
When a credit note wallet is created, its initial `credit_status` is set to `available`.
Once the wallet balance reaches zero, the status automatically changes to consumed.
## Void available credit[](#void-credit-note "Direct link to heading")
You can still void any remaining credit linked to a specific credit note when needed. To do so:
1. Go to the **"Customers"** section;
2. Select a customer to open the customer view;
3. Open the **"Credit notes"** tab;
4. Click a credit note to see its details; and
5. Select **"Void credit available"** from the **"Actions"** dropdown (upper
right corner).
When voiding a credit note wallet, the remaining credit amount will be lost
and the `credit_status` will switch to `voided`. This action cannot be
canceled.
```bash Void a credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
CREDIT_NOTE_ID="__YOU_CREDIT_NOTE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/credit_notes/$CREDIT_NOTE_ID/void" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
# Download invoices
Source: https://getlago.com/docs/guide/invoicing/download-invoices
When a new invoice is `finalized`, Lago will automatically send a
[webhook](/api-reference/webhooks/messages) to notify you. It will also generate a PDF
file that you can download and send to your customer.
To download an invoice through the user interface:
1. Click **"Customers"** in the side menu;
2. Select a customer from the list;
3. Open the **"Invoices"** tab;
4. Click the **ellipsis icon** on the right of the invoice; and
5. Click **"Download invoice"** to open the file in a new tab.
You can also download invoices via API ([learn more](/api-reference/invoices/download)).
```bash Download an invoice PDF theme={"dark"}
LAGO_URL="https://api.getlago.com"
INVOICE_ID="__YOU_INVOICE_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/$INVOICE_ID/download" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json'
```
# Draft invoices
Source: https://getlago.com/docs/guide/invoicing/draft-invoices
A draft invoice is an editable invoice by several ways.
While an invoice is in draft status, you can:
* **Add usage records** by sending events with a valid timestamp within the billing period
* **Edit specific fees** (adjusting total amount or unit count)
* **Apply coupons** to the customer’s account
* **Add credits** to the customer’s wallet or credit note wallet
### Add fees to draft invoice
Since Lago does not generate fees for charges with 0 units, some may not appear in the draft invoice by default.
You can add them either by [sending usage records](../invoicing/draft-invoices#add-usage-records) or manually through the Dashboard:
1. Open the draft invoice details;
2. Click Add a fee (if applicable);
3. Select the charge and filters;
4. Adjust the display name (optional);
5. Choose between `Total amount` or `Total unit`;
6. Input your values — note that `Total amount` overwrites the original fee;
7. If using `Total unit`, Lago recalculates the fee automatically.
Manual fee editing is only available via the Dashboard.
### Edit a specific fee
If a fee has already been added to the draft invoice, you can edit it from the Dashboard:
1. Open the draft invoice details;
2. Click the `three-dot` icon next to the fee;
3. Adjust the display name (optional);
4. Choose `Total amount` or `Total unit`;
5. Input new values — same recalculation logic applies as above.
Manual fee editing is only available via the Dashboard.
### Add usage records
In order to add usage to an invoice that is in `draft` status, the `timestamp`
of the [events](/guide/events/ingesting-usage) must be
within the billing period. Consider the following example:
> Billing period: January 1 – January 31
> Grace period: 3 days
> Today: February 2
>
> A draft invoice was generated on February 1.
>
> To send additional usage for this invoice, the event timestamps must fall between January 1st and 31st.
>
> ✅ Usage event on January 11 (timestamp: `1673457300`) → included
> ❌ Usage event on February 2 (timestamp: `1675354500`) → excluded (will be part of next invoice)
After sending new events, refresh the relevant draft invoice to see the events taken into account.
When the grace period ends, invoices in draft status are automatically finalized.
Alternatively, you can **finalize them manually** via the UI or API.
Once `finalized`, invoices are locked and trigger the `invoice.created` webhook.
Coupons and credits added during the grace period won’t appear on `draft` invoices, but they **will be automatically applied** to the next `finalized` invoice.
# E-Invoicing contributions
Source: https://getlago.com/docs/guide/invoicing/e-invoicing/contributions
Learn how to contribute new E-Invoicing formats and jurisdictions to Lago
## Current state in Lago
Lago currently supports two types of E-Invoicing formats: Cross Industry Invoices (CII) and Universal Business Language (UBL). Both implementations follow the French E-Invoicing structure.
Some EU countries may use different naming conventions, but they generally rely on the same underlying CII or UBL data structures, with country specific additions or removals.
This contribution guide is intended for developers who want to extend Lago's E-Invoicing capabilities to support additional jurisdictions or customize existing formats, especially for Peppol network compliance.
## CII - Cross Industry Invoices (Factur-X)
Cross Industry Invoices represent the hybrid format combining a PDF/A-3 file with an embedded XML file. The XML structure follows the CII standard, which is widely used in Europe, including France's Factur-X implementation.
Lago supports e-invoicing for the following record types:
* `invoice`
* `credit_note`
* `payments`
Each record type has a dedicated `Builder` class responsible for generating the XML document in the required format.
Builder classes are located at:
```bash theme={"dark"}
app/serializers/e_invoices///builder.rb
```
The Factur-X (CII) implementation lives in the Lago API project under:
```bash theme={"dark"}
app/serializers/e_invoices/factur_x
```
### Classes and XML Tags
| Class | XML Tag | Description | Parameters / Notes |
| --------------------------------- | ----------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `FacturX::CrossIndustryInvoice` | `rsm:CrossIndustryInvoice` | Root element for the invoice and its direct children | Requires a Ruby block |
| `FacturX::Header` | `rsm:ExchangedDocument` | Header information for the document | `type_code`: document type `notes`: optional additional information |
| `FacturX::LineItem` | `ram:IncludedSupplyChainTradeLineItem` | Represents a single invoice line item | `data`: `FacturX::LineItem::Data` containing item details |
| `FacturX::TradeAgreement` | `ram:ApplicableHeaderTradeAgreement` | Commercial agreement details | `options`: optional `FacturX::TradeAgreement::Options` `tax_registration`: controls tax registration rendering, default `true` |
| `FacturX::TradeDelivery` | `ram:ApplicableHeaderTradeDelivery` | Delivery information for goods or services | `delivery_date`: date goods or services were delivered |
| `FacturX::TradeSettlement` | `ram:ApplicableHeaderTradeSettlement` | Settlement and payment context | Requires a Ruby block |
| `FacturX::TradeSettlementPayment` | `ram:SpecifiedTradeSettlementPaymentMeans` | Payment means used for settlement | No specific parameters |
| `FacturX::ApplicableTradeTax` | `ram:ApplicableTradeTax` | Tax information applied to the invoice | Multiple tax related parameters |
| `FacturX::TradeAllowanceCharge` | `ram:SpecifiedTradeAllowanceCharge` | Allowances or charges applied to the invoice | Multiple allowance and charge parameters |
| `FacturX::PaymentTerms` | `ram:SpecifiedTradePaymentTerms` | Defines payment terms | No specific parameters |
| `FacturX::MonetarySummation` | `ram:SpecifiedTradeSettlementHeaderMonetarySummation` | Monetary totals and summaries | `amounts`: `FacturX::MonetarySummation::Amounts` with rendered values |
## UBL - Universal Business Language
Universal Business Language (UBL) is another widely adopted E-Invoicing standard, particularly in the Peppol network. UBL invoices are XML-only documents that follow a specific schema defined by OASIS.
The UBL implementation is located in the Lago API project under:
```bash theme={"dark"}
app/serializers/e_invoices/ubl
```
## Contributing new jurisdictions - The example of Germany
### Overview
This guide outlines the steps to contribute a new E-Invoicing format for Germany, specifically the XRechnung and ZUGFeRD formats based on UBL and CII standards.
Germany supports two e-invoicing formats:
This format combines a human readable PDF with embedded XML data. It is the most commonly used option due to lower implementation and operational costs compared to fiscal EDI based processes.
This is a pure XML electronic invoice based on **UBL 2.1.** It follows German XRechnung semantic requirements and is typically transmitted via the PEPPOL network using the **PEPPOL BIS Billing 3.0** specification. It is used for German B2G compliance and EU wide interoperability.
### Implementation notes
**ZUGFeRD 2.3.3** has no differences compared to the French Factur-X implementation. Existing Factur-X code can be fully reused.
**XRechnung** may require additional tags that are not present in the French UBL implementation. These tags should be added under the UBL folder.
Example:
* The `InvoicePeriod` tag is optional in standard UBL but required in XRechnung. It is currently not implemented in the French version.
* Some tags present in the French implementation may not be valid for XRechnung. Rendering of such tags should be controlled via conditional logic based on `billing_entity.country`.
```ruby theme={"dark"}
def serialize
# other mandatory tags
render_specific_tag if conditions_met?
# other tags
end
private
def conditions_met?
["DE"].include?(billing_entity.country)
end
def render_specific_tag
xml["cac"].GermanySpecificTag(value)
end
```
If a completely new and independent tag is required, create a dedicated class to render it. The corresponding `Builder` class should invoke it only when the conditions for the specific country or implementation are met.
# Overview
Source: https://getlago.com/docs/guide/invoicing/e-invoicing/overview
Lago automatically generates e-invoices for your billing entities and customers that comply with local regulations
## E-Invoicing principles
E-Invoicing is the automated exchange of invoice data between businesses in a structured digital format.
Governments require it to prevent tax fraud by tracking transactions in real-time, while businesses benefit from faster payments, fewer errors, and lower processing costs.
Instead of sending PDFs or paper invoices that need manual entry, E-Invoicing systems automatically validate and process invoice data, making the entire billing cycle more efficient.
As more countries make E-Invoicing mandatory, it's becoming the standard way businesses exchange invoices globally.
## Supported E-Invoicing jurisdictions
Lago issues compliant documents for **invoices**, **credit notes**, and **payment receipts** for the following jurisdictions:
| Country | Format | Type | Technical standard | Supported |
| --------------------- | ------------------------ | ------------------------------- | -------------------------------- | -------------- |
| **🇫🇷 France** | Factur-X | Embedded XML (PDF/A-3 with XML) | CII (UN/CEFACT) | ✅ |
| | UBL EN 16931 | XML only | UBL 2.1 | ✅ |
| **🇩🇪 Germany** | XRechnung | XML only | CII or UBL 2.1 (EN 16931) | Soon (Q4 2025) |
| | ZUGFeRD 2.x | Embedded XML (PDF/A-3 with XML) | CII (UN/CEFACT) | Soon (Q4 2025) |
| **🇪🇸 Spain** | Factura-e | XML only | UBL-based | Soon (Q4 2025) |
| | VeriFactu | XML only | UBL 2.1 or CII (format-agnostic) | Soon (Q4 2025) |
| **🇮🇹 Italy** | FatturaPA | XML only | Proprietary XML | Soon (Q4 2025) |
| | SDI format | XML only | Proprietary XML | Soon (Q4 2025) |
| **🇸🇦 Saudi Arabia** | ZATCA Standard Invoice | XML only | UBL 2.1 with ZATCA extensions | Soon (Q4 2025) |
| | ZATCA Simplified Invoice | Embedded XML (PDF/A-3 with XML) | UBL 2.1 with ZATCA extensions | Soon (Q4 2025) |
## Activate E-Invoicing in Lago
You can enable E-Invoicing at the entity level. Each entity can have its own E-Invoicing configuration based on its jurisdiction.
To activate E-Invoicing:
1. Go to **Settings** in your Lago dashboard;
2. **Select the entity** you want to update;
3. In the **General settings** section of this entity, click **Edit**; and
4. At the bottom of the form, toggle **E-invoicing on**.
The E-Invoicing toggle appears only if Lago supports E-Invoicing for the entity's country. If the option is not displayed, the country is currently not supported.
## Formats and contributions
The output type is typically either an **embedded XML file** (PDF/A-3 with XML) or a **standalone XML**, depending on the requirements of each jurisdiction.
Lago supports two standard E-Invoicing formats: **UBL (Universal Business Language)** and **CII (Cross Industry Invoice)**.
Using Lago's core templates for these formats, you can extend or customize them to meet the specific requirements of additional jurisdictions.
If your jurisdiction is not yet supported and you'd like to contribute to a new format, please **[contact us](mailto:hello@getlago.com)** or [visit this page](/guide/invoicing/e-invoicing/contributions).
Here is an example of an Cross Industry Invoice (CII) XML file for Factur-X in France:
```xml theme={"dark"}
urn:cen.eu:en16931:2017TWI-2684-454-00238620250626Invoice ID: ffa7f66d-a23d-4559-b048-499be3668c861creditcredit1.0010.0VATO10.00twilio_euTwilio EU10001Twilio EuropeParisFRDecathlon France75011100 rue decathlonBatiment DParisFR20250527USD30Credit transfer0.00VAT10.00OVATEX-EU-ONet payment term: 0 days2025062610.000.000.0010.000.0010.000.0010.00
```
# Export invoices
Source: https://getlago.com/docs/guide/invoicing/export
Lago enables you to filter invoices and export them as a simple or advanced CSV file, tailored to your needs.
## Invoice filtering options
With Lago, filtering your invoice list is straightforward and customizable. To filter invoices effectively, follow these steps:
1. Go to the **Invoices** section;
2. **Use quick filters** for fast, predefined filtering;
3. Select the **Filters options** for more advanced filtering criteria; and
4. Click **Reset filters** to remove all active filters when needed.
Here is the list of filter options you will encounter in Lago:
* **Amount:** Filter invoices by amount;
* **Currency:** Filter invoices based on the currency in which they are issued;
* **Customer:** Filter by the customer associated with the invoices;
* **Disputed:** Filter invoices to show only those that are disputed or undisputed;
* **Issuing Dates:** Filter invoices by their issuing dates;
* **Overdue:** Filter to display only overdue invoices;
* **Payment Status:** Filter invoices by their payment status;
* **Status:** Filter invoices by their status;
* **Type:** Filter invoices by their type;
* **Billing entity:** Filter invoice by their billing entity; and
* **Metadata:** Filter invoices by their metadata (API option only).
## Basic invoices export
The first option is a basic invoice export. This process generates a CSV file containing one row per invoice, based on the filters you have previously applied.
The exported CSV includes relevant invoice details and is sent to the email address of the user who requested the export.
The download link for the CSV file remains valid for 7 days.
## Detailed invoice fees export
The second option is an advanced invoice export. This process generates a CSV file containing one row per fee (line item of your invoices),
based on the filters you have previously applied. The exported CSV includes detailed information on each fee and line item of your invoices, and is
sent to the email address of the user who requested the export. The download link for the CSV file is valid for 7 days.
## Filter and export Credit notes[](#filter-and-export-credit-notes "Direct link to heading")
Please note that the `Credit Notes` list can be filtered and exported. The behavior aligns with the functionality defined above based on the credit note fields.
# Fees
Source: https://getlago.com/docs/guide/invoicing/fees
A fee is a line item in an invoice.
There are a few types of fees:
* **Subscription fees** which correspond to the plan’s base amount;
* **Fixed charge fees** which apply fixed recurring amounts defined by add-ons in plans;
* **Charge fees** which represent usage-based costs tied to billable metrics in plans and can be linked to a true-up fee;
* **Add-on fees** which appear as line items on one-off invoices;
* **Credits** which reflect the purchase of prepaid credits.
Information about fees includes (but is not limited to):
* Type;
* Amount;
* Currency; and
* Taxes.
The fee object is embedded within an invoice or credit note object, making it retrievable on its own.
This is illustrated below.:
```json theme={"dark"}
{
"lago_id": "294e38f1-898b-49c1-9f85-ce1178388c8b",
"lago_charge_id": null,
"lago_charge_filter_id": null,
"lago_fixed_charge_id": null,
"lago_invoice_id": "4d6b7c5a-ad44-44de-af30-755e4c0470f1",
"lago_true_up_fee_id": null,
"lago_true_up_parent_fee_id": null,
"lago_subscription_id": "c65448a6-a7ed-4037-8ad0-97140fa1a46e",
"external_subscription_id": "34f9febb-f501-4904-8f28-790bdb7c114a",
"lago_customer_id": "42a8e1ff-4518-4c19-aa7a-93299e87cd14",
"external_customer_id": "cus_fixed_charge",
"item": {
"type": "subscription",
"code": "Standard",
"name": "Standard",
"description": "",
"invoice_display_name": null,
"filters": null,
"filter_invoice_display_name": null,
"lago_item_id": "c65448a6-a7ed-4037-8ad0-97140fa1a46e",
"item_type": "Subscription",
"grouped_by": {}
},
"pay_in_advance": true,
"invoiceable": true,
"amount_cents": 355,
"amount_currency": "USD",
"precise_amount": "3.548387096774193",
"precise_total_amount": "3.903225806451612",
"taxes_amount_cents": 36,
"taxes_precise_amount": "0.3548387096774193",
"taxes_rate": 10.0,
"total_aggregated_units": null,
"total_amount_cents": 391,
"total_amount_currency": "USD",
"units": "1.0",
"description": null,
"precise_unit_amount": "3.55",
"precise_coupons_amount_cents": "0.0",
"events_count": null,
"payment_status": "pending",
"created_at": "2026-01-22T09:37:03Z",
"succeeded_at": null,
"failed_at": null,
"refunded_at": null,
"amount_details": {
"plan_amount_cents": 1000
},
"self_billed": false,
"pricing_unit_details": null,
"from_date": "2026-01-21T12:00:00+00:00",
"to_date": "2026-02-01T11:59:59+00:00"
}
```
## Update fee payment status
The `payment_status` of a fee can only be configured if `lago_invoice_id` is
`null`.
This option allows you to define the payment status of a fee yourself. The available options are: `pending`, `succeeded`, `failed`, and `refunded`.
Note that `payment_status` is used to group fees with a `succeeded` status into a specific invoice if `regroup_paid_fee` is set to `invoice`. Outside of this process, the `payment_status` is for your internal use.
## Delete a fee
The deletion of a fee can only be done if `lago_invoice_id` is `null`.
This option allows you to delete a fee that is not linked to any invoice. Please refer to charge [invoiceable or not](/guide/plans/charges/invoiceable-vs-noninvoiceable) for more details.
# Invoice metadata
Source: https://getlago.com/docs/guide/invoicing/invoice-metadata
## Add metadata on invoice
Adding metadata to an `invoice` object can provide additional structured information and context. For example, after finalizing the invoice, you can define a key-value pair in the `invoice` object to store your local invoice ID from your government invoicing system. To do so:
1. Navigate to the Invoice detail page to target a specific invoice;
2. Click on "Add metadata";
3. Add the information (kindly note, a key cannot exist without its corresponding value, and vice versa); and
4. Save to confirm.
The invoice metadata will be included in the `invoice` object but will not be displayed on the PDF file.
## Edit metadata on invoice
**To edit metadata from the user interface:**
1. Navigate to the Invoice detail page to target a specific invoice;
2. Click on "Edit metadata";
3. Add, edit, remove information (kindly note, a key cannot exist without its corresponding value, and vice versa); and
4. Save to confirm.
**To edit metadata using the API:**
1. In your payload, locate the key-value pair with the metadata ID you want to edit; and
2. Modify the key and/or value as needed.
When editing invoice metadata through the API, please make sure to include the existing metadata in your payload to avoid removing it.
## Delete metadata on invoice
**To delete a metadata key-value pair from the user interface:**
1. Navigate to the Invoice detail page for the specific invoice;
2. Click on "Edit metadata";
3. Click on the trash icon next to the metadata you want to remove; and
4. Save to confirm.
**To delete a metadata key-value pair from the API:**
1. Do not include the metadata ID you want to delete in your payload.
## Invoice metadata limitations
1. You can add up to 5 metadata key-value pairs;
2. Keys must be strings of 20 characters maximum; and
3. Values must be strings of 255 characters maximum.
# Empty invoice generation
Source: https://getlago.com/docs/guide/invoicing/invoicing-settings/empty-invoices
Configure whether Lago should generate invoices with a total amount of zero.
## Finalize empty invoices
By default, Lago finalizes all invoices — even those with a total amount of zero. However, some customers may prefer to skip these invoices to avoid generating unnecessary accounting documents.
To support this, you can configure Lago to skip finalizing invoices that are considered **empty**.
### Empty invoices definition
Lago considers an invoice empty if it contains no line items before applying coupons or discounts.
If a discount brings the total amount to zero but the invoice originally contained line items, it will still be finalized, as it is not considered empty under this definition.
### Billing entity level
The setting `finalize_zero_amount_invoice` is enabled (`true`) by default.
You can disable it at the billing entity level under Invoice settings. When set to `false`, Lago will skip finalizing empty invoices for all customers linked to that billing entity — unless a customer-specific override is applied.
To modify this setting from the Lago Dashboard:
1. Go to Settings in your app;
2. Navigate to the Billing entity > Invoices settings; and
3. Update the value in the **'Finalize zero amount invoice'** section according to your preference.
```bash Update the organization's settings theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/billing_entities/{code}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_entity": {
"country": "US",
"finalize_zero_amount_invoice": true
}
}'
```
### Customer level
By default, new customers inherit the `finalize_zero_amount_invoice` setting from the organization.
You can override this setting for individual customers to meet specific needs.
The available options are:
* `inherit`: Follows the billing entity setting;
* `skip`: Skips finalizing empty invoices; or
* `finalize`: Always finalizes invoices, even if empty.
To modify this customer setting from the Lago user interface:
1. Go to a specific customer;
2. Navigate to the Settings section; and
3. Override the value in the **'Finalize zero amount invoice'** section according to your preference.
```bash Update the customer's settings theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "hooli_12345",
"address_line1": "100 Fintech Devcon Street",
"city": "Austin",
"country": "US",
"email": "hooli@fintech.com",
"legal_number": "54321",
"name": "Hooli 12345",
"state": "Texas",
"tax_identification_number": "1234",
"zipcode": "9399",
"finalize_zero_amount_invoice": "skip"
}
}'
```
# Grace period
Source: https://getlago.com/docs/guide/invoicing/invoicing-settings/grace-period
Configure a buffer between invoice generation and finalization to review invoices.
**PREMIUM FEATURE** ✨
This feature is only available to users with a premium license. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
A grace period is the number of days during which invoices remain in `draft` status, allowing you to review and modify them before they are finalized and sent for payment collection.
In the illustration below, the billing period spans one month, followed by a three-day grace period.
## Define a grace period at billing entity level[](#define-a-grace-period-at-organization-level "Direct link to heading")
The grace period set at the billing entity level applies to all customers linked to this entity by default.
To set a grace period from the Lago Dashboard:
1. Access the **"Settings"** section via the side menu;
2. Open the **Billing entity** > **"Invoicing settings"** section;
3. Click **"Edit"** in the **"Grace period"** section;
4. Enter the number of days associated with the grace period; and
5. Click **"Edit grace period"** to confirm.
If you shorten the organization's grace period, some invoices in `draft`
status may be automatically `finalized`. For instance, if the initial grace
period was five days, but then three days into the grace period you decide to
reduce it to two days, then all `draft` invoices will automatically switch to
`finalized`.
You can also modify the entity's grace period at any time through [the API](/api-reference/billing-entities/update).
```bash Add a grace period on the organization {28} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/billing_entities/{code}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"organization": {
"invoice_grace_period": 3
}
}'
```
## Define a grace period at customer level[](#define-a-grace-period-at-customer-level "Direct link to heading")
To define a grace period at customer level through the user interface:
1. Go to the **Customers** section in the side menu;
2. Select a customer;
3. Open the **Settings** tab in the customer view;
4. Click **Add grace period** in the **Grace period** section;
5. Enter the number of grace period days; and
6. Click **Add grace period** to confirm.
If you shorten the customer's grace period, some invoices in `draft` status
may be automatically `finalized`. For instance, if the initial grace period
was five days, but then three days into the grace period you decide to reduce
it to two days, then all `draft` invoices will automatically switch to
`finalized`.
You can also modify the customer's grace period at any time through the Dashboard or [the API](/api-reference/customers/create).
```bash Add a grace period on the customer {28} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"address_line2": "",
"city": "Woodland Hills",
"country": "US",
"currency": "EUR",
"email": "dinesh@piedpiper.test",
"legal_name": "Coleman-Blair",
"legal_number": "49-008-2965",
"tax_identification_number": "EU123456789",
"logo_url": "http://hooli.com/logo.png",
"name": "Gavin Belson",
"phone": "1-171-883-3711 x245",
"state": "CA",
"timezone": "Europe/Paris",
"url": "http://hooli.com",
"zipcode": "91364",
"tax_codes": []
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"document_locale": "fr",
},
"metadata": [
{
"key": "Name",
"value": "John",
"display_in_invoice": true
}
]
}
}'
```
The customer-specific grace period overrides the billing entity’s default grace period. It only applies to the customer it is configured for.
## Application scope and possible actions[](#application-scope-and-possible-actions "Direct link to heading")
The grace period applies exclusively to **subscription** invoices. It does not apply to invoices related to add-ons or credit purchases.
The creation of a `draft` invoice triggers the `invoice.drafted`
[webhook](/api-reference/webhooks/messages).
While an invoice is in draft status, you can:
* **Add usage records** by sending events with a valid timestamp within the billing period
* **Edit specific fees** (adjusting total amount or unit count)
* **Apply coupons** to the customer’s account
* **Add credits** to the customer’s wallet or credit note wallet
Please follow this page to know more about these actions.
# Invoice numbering
Source: https://getlago.com/docs/guide/invoicing/invoicing-settings/invoice-numbering
Define how invoice numbers are generated — per customer or across the billing entity.
## Invoice numbering[](#invoice-numbering "Direct link to heading")
With Lago, invoice numbers are automatically generated each time an invoice is finalized. You can configure how these numbers increment to match your billing entity structure and customer management needs.
* **Per customer**:
Generates a unique invoice sequence for each customer.
This method ensures isolated and traceable numbering per customer, which can simplify customer-level reporting and accounting.
* **Entity-wide numbering**:
Uses a single, continuous sequence across all customers within a billing entity.
This option streamlines invoice tracking at the entity level. The numbering increments monthly, using a YYYYMM pattern to help segment invoices by period.
## Invoice prefix customization[](#invoice-prefix-customization "Direct link to heading")
Lago also allows full control over the prefix applied to documents like invoices and credit notes.
By default, the prefix combines:
* The first three letters of your billing entity’s name, and
* The last four digits of your entity ID.
You can override this with a custom prefix to better reflect your internal conventions or branding needs.
This helps maintain consistency, clarity, and professionalism across your documents.
# Issuing date preferences
Source: https://getlago.com/docs/guide/invoicing/invoicing-settings/issuing_date
Control when your subscription invoices are dated.
## Overview
**By default, Lago dates invoices on the first day of the new billing period** (e.g., November 1st for an October usage and subscription).
Some businesses need invoices dated on the last day of the billing period instead (e.g., October 31st) for accounting or compliance reasons.
This feature gives you control over the issuing date displayed on your invoices.
Note that this is configured at the **Billing Entity level** and applies to all customers under that entity. However, you can override it for specific customers when needed.
## Invoice settings
### Issuing date anchor
This setting determines which **issuing date** appears on your invoice.
| Option | Description | For Oct. billing period |
| ----------------------------------- | ------------------------------------------------------- | ---------------------------- |
| `next_period_start` (default value) | Invoice dated on first day of next billing period | Issuing Date: **November 1** |
| `current_period_end` | Invoice dated on last day of the current billing period | Issuing Date: **October 31** |
### Issuing date adjustment
This setting controls what happens when an invoice is finalized **after** the anchor date, especially when a grace period greater than 0 is configured.
| Option | Description |
| ---------------------------------------- | ---------------------------------------------------------- |
| `align_with_finalization_date` (default) | Invoice date updates to actual finalization date |
| `keep_anchor` | Invoice keeps the anchor date regardless of when finalized |
## Examples
The following examples show how different combinations of settings affect the invoice issuing date for a subscription with a billing period from **October 1st to October 31st**.
The grace period determines when the invoice is finalized after the billing period ends.
| Anchor | Adjustment | Grace Period | Invoice Issuing Date |
| -------------------- | ------------------------------ | ------------ | -------------------- |
| `next_period_start` | `align_with_finalization_date` | 0 days | **November 1** |
| `next_period_start` | `align_with_finalization_date` | 2 days | **November 3** |
| `next_period_start` | `keep_anchor` | 2 days | **November 1** |
| `current_period_end` | `align_with_finalization_date` | 2 days | **November 3** |
| `current_period_end` | `keep_anchor` | 2 days | **October 31** |
## Common use cases
### Standard billing (default)
| Field | Value |
| ---------------------------------------------- | ------------------------------ |
| `subscription_invoice_issuing_date_anchor` | `next_period_start` |
| `subscription_invoice_issuing_date_adjustment` | `align_with_finalization_date` |
Best for most businesses. Invoice dates reflect when invoices are actually issued, which simplifies payment tracking and customer communication.
### Period-end accounting
| Field | Value |
| ---------------------------------------------- | -------------------- |
| `subscription_invoice_issuing_date_anchor` | `current_period_end` |
| `subscription_invoice_issuing_date_adjustment` | `keep_anchor` |
Ideal for businesses that need invoices dated within the same month as the service period for revenue recognition or accounting compliance. Example: An October subscription invoice will always show October 31, even if generated in November.
### Fixed period start dates
| Field | Value |
| ---------------------------------------------- | ------------------- |
| `subscription_invoice_issuing_date_anchor` | `next_period_start` |
| `subscription_invoice_issuing_date_adjustment` | `keep_anchor` |
Useful when you want consistent invoice dates aligned to billing cycle starts, regardless of processing delays. Example: Monthly invoices always dated on the 1st of each month.
# Net payment term
Source: https://getlago.com/docs/guide/invoicing/invoicing-settings/net-payment-term
Number of days a customer has to pay an invoice after it has been finalized
A net payment term refers to the specified number of days within which the end customer is required to settle the invoice after its finalization.
This term not only affects the `payment_due_date` within the invoice payload but also influences the due date mentioned in the downloadable PDF version of the invoice.
To illustrate, consider the following scenario:
a billing cycle spanning one month, accompanied by a net payment term of 15 days.
## Application scope[](#application-scope "Direct link to heading")
The net payment term period applies to all types of invoices, and is used to compute the payment due date.
When the `payment_due_date` has passed, the invoice is flagged as overdue (`payment_overdue` = `true`), and Lago emits an `invoice.payment_overdue`
[webhook message](/api-reference/webhooks/messages).
The invoice stays flagged as overdue until the payment is `succeeded`, or `payment_dispute_lost_at` is applied, or the invoice is voided.
## Define a net payment term at entity level[](#define-a-net-payment-term-at-entity-level "Direct link to heading")
The entity's net payment term applies to all customers linked to this object by default.
To define a net payment term at the entity level via the user interface, follow these steps:
1. Access the **Settings** section using the side menu;
2. Navigate to the **Billing entity** > **Invoicing settings** section;
3. Click **Edit** in the **Net payment term** section;
4. Select the desired number of days for the payment term or opt for a custom duration; and
5. Confirm by clicking **"Edit net payment term"**.
You can also modify the entity’s net payment term at any time through the API
```bash Add a net payment term on the billing entity theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/billing_entities/{code}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_entity": {
"net_payment_term": 15
}
}'
```
## Define a net payment term at customer level[](#define-a-net-payment-term-at-customer-level "Direct link to heading")
To define a net payment term at the customer level through the user interface, follow these steps:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. Open the **"Settings"** tab of the customer view;
4. Click **"Add a net payment term"** in the **"Net payment term"** section;
5. Choose the desired number of days for the payment term or opt for a custom duration; and
6. Click **"Add net payment term"** to confirm.
You can also modify the customer's net payment term at any time through [the API](/api-reference/customers/update).
Define a net payment term in days by using the `net_payment_term argument` within the `customer` object.
```bash Add a net payment term on a customer theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"net_payment_term": 15
}
}'
```
The customer's net payment term supersedes the one defined at the entity level.
It exclusively applies to the associated customer.
# Overview
Source: https://getlago.com/docs/guide/invoicing/invoicing-settings/overview
Define invoice look and feel per entity to match your requierement.
Invoicing settings impact a specific entity and all customers invoices linked to it.
### Add information about your entity
You can modify some of the elements that are included in the PDF invoice, such as information about the entity, its logo and footer.
To update your entity's information and logo:
1. Click **"Settings"** in the side menu;
2. In the **Billing entity** > **General information** section, click **"Edit"** in the **"Information"** block;
3. Choose a file to update the logo and fill out the form to update your entity's information; and
4. Click **"Save edits"** to confirm.
For the logo, you can upload a JPG or PNG file with a maximum size of 800 KB.
### Add a custom invoice section[](#add-custom-invoice-section "Direct link to heading")
A custom invoice section is an additional section displayed above the custom footer on an invoice.
It allows you to set a title and include specific details (e.g. bank details).
Custom invoice sections can be applied at the billing entity level, impacting all customer invoices attached to it, or set per customer for greater granularity.
To create an invoice custom section:
1. Click **"Settings"** in the side menu;
2. Open the **"Invoice section"** tab;
3. Click on **"Add"** in the **"Invoice custom section** block;
4. Provide the necessary details, including the title and content.
5. Click **Preview** to see how the section will appear on an invoice.
6. Apply this invoice custom section to a billing entity or a customer.
You can display multiple custom invoice sections on invoices. Note that they will be sorted alphabetically by the custom section name.
You can override the entity-level setting for specific customers by either assigning a different invoice custom section or deactivating the option for that customer. To do so:
1. Click on a specific customer;
2. Navigate to the **Settings** tab;
3. Click on **Edit** in the Invoice custom section;
4. Add a specific custom invoice section for the customer; or
5. Choose to deactivate the invoice custom section for this customer.
```bash Update the customer invoice custom section theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
…
"skip_invoice_custom_sections": false, // If true, no invoice custom sections will be applied to the customer
"invoice_custom_section_codes": ["eu_bank_details"] // Leave an empty array to use the billing entity-level settings
…
}
}'
```
Once the settings are updated, all newly finalized invoices for the billing entity or specific customer will reflect the changes.
### Add a custom footer
A custom footer is a universal footer applied to all invoices and credit notes across all customers.
It is typically used to display your company’s legal information or other standard details.
If you need granularity per customer, please refer to the **custom invoice section** above.
To update the footer of the invoice:
1. Click **Settings** in the side menu;
2. Open the **Billing entity** > **Invoicing settings** tab;
3. Click on **Edit** in the **Invoice default footer** block;
4. Enter your text (maximum 600 characters); and
5. Click **Save information** to confirm.
You can update the customer footer of invoices by changing the `invoice_footer` in your billing entity endpoint.
```bash Update the customer footer of your invoices theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/billing_entities/{code}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_entity": {
…
"invoice_footer": "footer custom"
}
}'
```
### Translate invoices
To set the default language for documents:
1. Click **"Settings"** in the side menu;
2. Open the **Billing entity** > **Invoicing settings** tab;
3. Select **"Edit"** in the **"Document language"** block;
4. Select your preferred language from the list; and
5. Click **"Edit language"** to confirm.
The entity's default language can be overwritten by the customer's preferred language ([learn more](/guide/customers/invoice-customer#preferred-language)).
You can update the customer footer of invoices by changing the `document_locale` in the `billing_configuration` object of your billing entity endpoint.
```bash Update the documents locale theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/billing_entities/{code}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_entity": {
…
"document_locale": "fr"
}
}'
```
Please refer to the API documentation to see the [list of supported languages](/api-reference/resources/locales).
# Taxes
Source: https://getlago.com/docs/guide/invoicing/invoicing-settings/taxes
When generating invoices, you may need to apply VAT or other taxes. By creating tax objects and applying them to billing entities and/or customers, the corresponding invoices will reflect the appropriate tax rates.
## External integration
Let your tax provider handle the complexity of tax logic! We support integrations that allow seamless tax automation.
If you'd like to explore these integrations or be connected to a provider, feel free to contact us.
}
href="/integrations/taxes/anrok"
>
Anrok is a global sales tax platform built for software companies.
Official
}
href="/integrations/taxes/avalara"
>
AvaTax is a cloud-based tax calculation and compliance platform that helps businesses manage their sales tax obligations.
Official
***
## Create taxes at the organization level
Before applying taxes to invoices, you need to create a tax object at the organization level. You can then assign it to billing entities or specific customers.
**To create a tax:**
1. Go to **Settings** > **Taxes** tab
2. Click **"Add"** (top-right corner)
3. Provide a `name`
4. Set a unique `code` (used as an identifier in your backend)
5. (Optional) Add a `description`
6. Define the applicable `rate` (e.g., 20.00 for 20%)
```bash theme={"dark"}
# Create a tax object
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/taxes" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"tax": {
"name": "French VAT",
"code": "french_vat",
"description": "French standard VAT",
"rate": 20.00
}
}'
```
***
## Edit or delete taxes
Taxes can be edited or deleted even if they are already applied to billing entities or customers. However, any change will affect all draft or upcoming invoices linked to that tax.
**Available actions:**
* **Edit**: Modify the tax name, code, or rate
* **Delete**: Remove the tax from your system (irreversible)
***
## Apply taxes to objects
When generating invoices, taxes can be applied at various levels and will impact all associated fees (subscriptions, usage-based charges, etc.).
***
### At the billing entity level
1. Go to **Settings** > Select your **Billing entity** > **Taxes** tab
2. Click **"Add"** to apply a tax
3. Choose the tax object
4. Repeat to apply multiple taxes
```bash theme={"dark"}
# Add taxes to a billing entity
curl --location --request PUT "$LAGO_URL/api/v1/billing_entities/{code}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billing_entity": {
"tax_codes": ["tax_fr", "tax_it"]
}
}'
```
***
### At the customer level
1. Go to **Customer details** > **Settings**
2. Under **Tax rates**, click **"Add a tax"**
3. Select the appropriate tax
4. Repeat for multiple taxes
```bash theme={"dark"}
# Add taxes to a customer
curl --location --request PUT "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"code": "acme_inc",
"tax_codes": ["tax_fr"]
}
}'
```
***
### At the plan and charge level
1. Ensure your tax objects are created
2. Navigate to **Plans** > **Add a plan**
3. In the plan settings, click **Add a tax rate**
4. For usage-based charges, expand **More options** and click **Add a tax rate**
5. Note: taxes set at the charge level override the plan-level taxes
6. Save and apply the plan to customers
```bash theme={"dark"}
# Add taxes to a plan and its charges
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Starter",
"code": "starter",
"interval": "monthly",
"amount_cents": 9900,
"amount_currency": "USD",
"tax_codes": ["french_standard_vat"],
"charges": [
{
"billable_metric_code": "user_seat",
"charge_model": "standard",
"invoiceable": true,
"pay_in_advance": false,
"prorated": false,
"min_amount_cents": 0,
"tax_codes": ["french_standard_vat"],
"properties": {
"amount": "0.10"
}
}
]
}
}'
```
***
### At the add-on level
1. Make sure taxes are set up in your account
2. Go to **Add-ons** > **Add an add-on**
3. In the add-on settings, click **Add a tax rate**
4. Complete creation and apply to customers via one-off invoices
```bash theme={"dark"}
# Add tax to an add-on
{
"add_on": {
"name": "Setup fee",
"code": "setup_fee",
"amount_cents": 100000,
"amount_currency": "USD",
"tax_codes": ["french_standard_vat"]
}
}
```
Tax rates defined at the add-on level can be overridden when creating a one-off invoice.
***
## Tax hierarchy
### For Subscription Invoices
When generating invoices for subscriptions, taxes are applied in the following order of priority:
1. **Billing entity** taxes apply to all invoice fees (subscriptions and charges)
2. **Customer** taxes override billing entity taxes
3. **Plan** taxes override customer taxes
4. **Charge**-level taxes override plan taxes, but only affect the specific charge
5. If the customer is linked to a **tax provider** (e.g., Anrok), the provider's calculation overrides all other tax levels
***
### For one-off invoices
For one-off invoices, the hierarchy is:
1. **Organization** taxes apply to all fees
2. **Customer** taxes override organization taxes
3. **Add-on** taxes override customer taxes for the add-on only
4. **Fee-level** taxes (set at invoice creation) override add-on-level taxes for the specific fee
***
### For prepaid credit invoices
Prepaid credits are considered upfront payments. Therefore, invoices for credit purchases do **not** include any tax.
***
## Auto-detect european taxes with Lago
Lago supports automatic tax detection for European customers.\
Refer to our [integration guide](/integrations/taxes/lago-eu-taxes) to set it up.
# Overview
Source: https://getlago.com/docs/guide/invoicing/overview
Lago automatically generates invoices for each customer according to the plan model.
When a new invoice is generated, Lago also sends an `invoice.created` webhook
([learn more](/api-reference/webhooks/messages)).
When an invoice is linked to an add-on, another type of webhook is sent, called
`invoice.one_off_created`.
## Invoice object[](#invoice-object "Direct link to heading")
Invoices include (but are not limited to):
* Invoice number;
* Billing period;
* Customer information;
* Fees; and
* Taxes.
You can [download invoices](/guide/invoicing/download-invoices) or use the
[invoice object](/api-reference/invoices/invoice-object) to create your own invoice
template.
You can also use the invoice object to transmit information to your accounting
software or payment service provider.
# Preview an invoice
Source: https://getlago.com/docs/guide/invoicing/previews
With Lago, you can preview invoices even if the customer doesn't exist yet, for pending subscriptions, or for active subscriptions.
✨ This feature is only available via a premium licence. Please contact [hello@getlago.com](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
By using the `/invoices/preview` endpoint, you can generate a preview of an invoice for a potential purchase or to estimate the dry-run invoice of an active subscription.
This preview calculates the total invoice amount, itemizes each charge, and applies any relevant taxes or discounts.
By creating a preview, you can share the projected payment details without generating or finalizing an invoice.
Lago returns an invoice payload detailing all line items, applying any eligible discounts, and calculating the total amount.
## Simple invoice preview
To create a basic invoice preview for an existing customer, provide the appropriate customer `external_id` along with the relevant subscription or plan details.
Lago will then generate a preview invoice on-demand, prorating all line items based on the `billing_time` (calendar or anniversary).
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "hooli_1234"
},
"plan_code": "premium",
"billing_time": "calendar"
}'
```
## Preview an invoice for a specific date
Additionally, you can request an invoice preview for a specific date by including the `subscription_at` field.
This instructs Lago to calculate and prorate all line items according to the date you specify.
```bash {13} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "hooli_1234"
},
"plan_code": "premium",
"billing_time": "calendar",
"subscription_at": "2025-01-25"
}'
```
## Preview an invoice for a pending subscription
You can preview an invoice for a subscription that has already been created but hasn't started yet (status: `pending`). This is useful when you've created a subscription with a future `subscription_at` date and want to estimate the upcoming charges.
This method supports **subscriptions with price overrides**, making it ideal when your plans use zero pricing with subscription-level overrides.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "hooli_1234"
},
"subscriptions": {
"external_ids": [
"subscription_external_id_1"
]
}
}'
```
## Preview for non-existing customers
You can generate an invoice preview for a customer who isn't yet registered in your system or created in Lago.
This is especially useful for showing estimated costs to potential customers evaluating your product. In this scenario, you won't pass a customer `external_id`; instead, provide all relevant customer information you wish to capture.
```bash {8-18} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"name": "Gavin Belson",
"tax_identification_number": "1234567890",
"customer_type": "company",
"shipping_address": {
"address_line1": "100 Hooli Street",
"city": "San Francisco",
"zipcode": "998828",
"country": "US"
}
},
"plan_code": "premium",
"billing_time": "calendar",
"subscription_at": "2025-01-25"
}'
```
## Include taxes in invoice previews
If you have an external tax setup, you can include tax details in the invoice preview payload. Lago will then calculate and apply taxes accordingly.
If Lago is integrated with a tax provider (e.g., Anrok), you only need to pass the relevant integration data in the customer integration payload.
```bash {18-23} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"name": "Gavin Belson",
"tax_identification_number": "1234567890",
"customer_type": "company",
"shipping_address": {
"address_line1": "100 Hooli Street",
"city": "San Francisco",
"zipcode": "998828",
"country": "US"
},
"integration_customers": [
{
"integration_type": "anrok",
"integration_code": "anrok_prod"
}
]
},
"plan_code": "premium",
"billing_time": "calendar",
"subscription_at": "2025-01-25"
}'
```
## Include discounts in invoice previews
You can include discounts in an invoice preview through either of these methods:
1. **Apply an existing coupon or a prepaid credit to the customer:** When a coupon or credit is already associated with the customer, Lago automatically applies the discount to the invoice preview; or
2. **Provide coupon details in the request payload:** Pass your own coupon information directly in the invoice preview payload, and Lago will apply the discount accordingly.
```bash {22-30} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"name": "Gavin Belson",
"tax_identification_number": "1234567890",
"customer_type": "company",
"shipping_address": {
"address_line1": "100 Hooli Street",
"city": "San Francisco",
"zipcode": "998828",
"country": "US"
}
},
"plan_code": "premium",
"billing_time": "calendar",
"subscription_at": "2025-01-25",
"coupons": [
{
"code": "discount_01",
"name": "Discount 01",
"coupon_type": "fixed_amount",
"amount_cents": 1200,
"amount_currency": "USD"
}
]
}'
```
## Dry-run invoices for active subscriptions
You can preview or estimate the total amount and all applicable fees for active subscriptions.
This returns the price that customers will be charged in the next billing period, including fees, taxes and any applicable discounts.
```bash {19-21} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "customer_001",
"name": "test 1",
"shipping_address": {
"address_line1": "77 rue du Chemin Vert",
"city": "Rome",
"zipcode": "75011",
"country": "IT"
},
"tax_identification_number": "1234567890"
},
"subscriptions": {
"external_ids": ["e372c4e4-99ec-41a4-a51b-7c165eb5cb88"]
}
}'
```
## Preview an invoice for subscription termination
You can preview an invoice associated with terminating a subscription by including the `terminated_at` field in the request payload.
```bash {19-22} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "customer_001",
"name": "test 1",
"shipping_address": {
"address_line1": "77 rue du Chemin Vert",
"city": "Rome",
"zipcode": "75011",
"country": "IT"
},
"tax_identification_number": "1234567890"
},
"subscriptions": {
"external_ids": ["e372c4e4-99ec-41a4-a51b-7c165eb5cb88"],
"terminated_at": "2025-03-01T00:00:00Z"
}
}'
```
## Preview an invoice for upgrades and downgrades
To preview invoices generated by upgrading or downgrading an active subscription, include a new `plan_code` in the request payload:
```bash {19-22} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/preview" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "customer_001",
"name": "test 1",
"shipping_address": {
"address_line1": "77 rue du Chemin Vert",
"city": "Rome",
"zipcode": "75011",
"country": "IT"
},
"tax_identification_number": "1234567890"
},
"subscriptions": {
"external_ids": ["e372c4e4-99ec-41a4-a51b-7c165eb5cb88"],
"plan_code": "new_plan",
}
}'
```
# Void invoices
Source: https://getlago.com/docs/guide/invoicing/void
From an accounting standpoint, voiding an invoice serves the same functional purpose as canceling or deleting it, but it is legally accepted and properly documented.
Voiding preserves a paper trail, enabling you to locate the invoice by its number. Voided invoices are considered as having zero value for reporting and are not payable.
Importantly, this status is final, meaning the invoice's status remains unalterable.
Once you void an invoice, it remains accessible through the UI views and shows a status `voided` indicating it has been voided.
To void an invoice using the user interface:
1. Go to the **"Invoices"** list;
2. Click the **ellipsis icon** on the right, on the line corresponding to the invoice;
3. Select **"Void invoice"**; and
4. Confirm to void the invoice.
```bash Void an existing invoice theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
INVOICE_ID="__YOUR_INVOICE_ID__"
curl --location --request POST "$LAGO_URL/api/v1/invoices/$INVOICE_ID/void" \
--header "Authorization: Bearer $API_KEY"
```
## Restrictions on voiding invoices
Here is the list of restrictions on voiding invoices:
* The invoice is in `draft` status, as it hasn't been finalized yet; or
* The invoice has already been voided.
## Refund options when voiding an invoice
When you void an invoice, you can choose how to handle the associated refund, depending on your preference and the invoice's payment status:
### 1. Void without credit note (default)
* The invoice is marked as voided;
* Only prepaid credits used to pay the invoice will be refunded to the customer's balance (as they have been prepaid); and
* No credit note is issued for this voided invoice.
### 2. Void and generate a credit note
* The invoice is marked as voided;
* A credit note is created for the voided invoice;
* If the invoice was already paid, you can optionally refund the original payment method using the credit note; and
* Alternatively, the credit note can be retained on the customer's credit note account and used toward future invoices.
```bash Refund options when voiding an invoice theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/invoices/{lago_id}/void \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"generate_credit_note": true,
"refund_amount": 2000,
"credit_amount": 1150
}'
```
## Regenerate a voided invoice
When accessing a voided invoice, you can choose to regenerate it directly from the UI. This is a **UI-only feature** designed to simplify invoice recreation.
The original line items and fees from the voided invoice will be pre-filled to help you quickly generate a new invoice.
You can modify the pre-filled values as needed:
1. Change the number of units;
2. Change the amount; and
3. Add new fee line items.
The regenerated invoice will be **linked to the original voided invoice** for traceability and accounting purposes. Note that you cannot change the service period of the regenerated invoice.
Please note the following:
* Voided prepaid credit invoices can only be regenerated by initiating a new wallet transaction. This is why you are redirected to the wallet transaction flow;
* Voided one-off invoices must be recreated by generating a new one-off invoice. Accordingly, you are redirected to the one-off invoice creation flow; and
* Voided subscription and usage invoices are regenerated through a dedicated invoice regeneration view, where you can add or edit the fees from the original invoice.
Prepaid credits, coupons, or credit note balances available at the customer level may be applied to the regenerated invoice, so ensure the final amount matches the expected total after taxes and discounts.
# Lago Cloud
Source: https://getlago.com/docs/guide/lago-cloud
Lago Cloud is the fully hosted version of our open-source billing API.
With a cloud account:
1. You don't have to maintain the solution;
2. You can start building your billing system immediately; and
3. You benefit from automatic updates.
[Request access to Lago Cloud](https://getlago.com/book-a-demo) to get started.
# Lago OpenAPI
Source: https://getlago.com/docs/guide/lago-open-api
Using our Open API is a great way to explore and interact with Lago's API documentation.
## Prerequisites[](#prerequisites "Direct link to heading")
Before you start using our Open API, here are some important prerequisites and useful links:
1. Create a free [Postman](https://postman.com) account;
2. Use the [Swagger](https://swagger.getlago.com/) for Lago's API documentation;
3. Open a Lago account to get your API key; and
4. Check out our public [GitHub repository](https://github.com/getlago/lago-openapi).
## Using Lago Open API with Postman[](#using-lago-open-api-with-postman "Direct link to heading")
The Swagger used to document Lago's API can be imported directly into Postman. To do so:
1. **Copy the following link:** [https://swagger.getlago.com/openapi.yaml](https://swagger.getlago.com/openapi.yaml) (this link can also be found on the Swagger's page);
2. In Postman, under **Import > Link**, paste the URL above;
3. Click **Continue**;
4. Click the **Import** button; and
5. In the menu, under **API**, find the newly created **Lago API documentation**.
It only takes a few seconds to complete the import. You can then use this API to generate a new collection.
Please don't forget to enter the API key associated with your organization's Lago account to authenticate your API requests.
# Useful commands
Source: https://getlago.com/docs/guide/lago-self-hosted/commands
Useful commands for self-hosted users.
Below is a compilation of essential commands tailored for open-source enthusiasts, primarily designed for managing invoicing tasks,
whether for immediate processing or scheduling.
These commands are designed to execute a Rails console (rails c) within a Docker container named api, which is managed by Docker Compose.
```
docker-compose exec api rails c
```
## Dry-run invoice in the future
Use this to simulate a dry run invoice for a future date. Ensure to specify the correct subscription `external_id` and the targeted invoice issuance date.
```ruby theme={"dark"}
# In the rails Console
subscription = Subscription.find_by(external_id: 'YOUR_SUB_EXTERNAL_ID')
date = DateTime.parse('2024-10-01').to_i
BillSubscriptionJob.perform_later([subscription], date)
```
## Issue invoice immediately
Use this to issue an invoice immediately. Ensure to specify the correct subscription `external_id` and the current date.
```ruby theme={"dark"}
# In the rails Console
subscription = Subscription.find_by(external_id: 'YOUR_SUB_EXTERNAL_ID')
timestamp = DateTime.parse('2024-04-01').to_i
BillSubscriptionJob.perform_now([subscription], timestamp, invoicing_reason: :subscription_periodic)
```
## Remove cache for a subscription
Use this to remove the cache on a specific subscription.
```ruby theme={"dark"}
# In the rails Console
Subscriptions::ChargeCacheService.expire_for_subscription(Subscription.find('YOUR_SUB_EXTERNAL_ID'))
```
To remove the cache for all subscriptions, you can alternatively use this command:
```ruby theme={"dark"}
# In the rails Console
Subscription.find_each {|s| Subscriptions::ChargeCacheService.expire_for_subscription(s) }
```
## Audit logs of a subscription
Use this to view all changes applied to a subscription and identify which membership made those changes.
```ruby theme={"dark"}
# In the rails Console
subscription = Subscription.find_by(external_id: 'YOUR_SUB_EXTERNAL_ID')
subscription.versions
```
# Compatibility Matrix
Source: https://getlago.com/docs/guide/lago-self-hosted/compatibility-matrix
Supported technologies and versions for Lago self-hosted deployments.
This document outlines the supported technologies and their versions for Lago self-hosted deployments. Use this matrix to ensure your infrastructure meets the requirements for your target Lago version.
## Core Dependencies by Version
| Lago Version | PostgreSQL | Redis | Valkey | Kubernetes | Notes |
| ---------------- | ---------- | ----- | ------ | ---------- | ----------------------------------- |
| ≥ 1.0 | 14+ | 6.2+ | 7.0+ | - | Safe baseline for existing installs |
| ≥ 1.30 | 15+ | 7.x | 7.2+ | - | Recommended for new installs |
| ≥ Latest Release | 15+ | 7.x | 7.2+ | 1.26+ | Production-grade setup |
**For PostgreSQL, the [pg\_partman](https://github.com/pgpartman/pg_partman) extension should be installed on the server.**
Check [the repository](https://github.com/getlago/lago/blob/main/docs/database_partitioning.md) for more details.
## Analytics & Streaming Dependencies
These components are required for specific Lago features.
| Category | Technology | Supported Version | Purpose |
| ------------ | ---------- | ----------------- | ----------------------------------------- |
| Analytics DB | ClickHouse | 25.6+ | Required for analytics features |
| Streaming | Redpanda | 25.2+ | Required for event streaming capabilities |
## Recommendations
**For new deployments**, we recommend starting with the latest supported versions:
* **PostgreSQL 15+** for full compatibility with recent Lago releases
* **Redis 7.x** or **Valkey 7.2+** for optimal performance and stability
* **Kubernetes 1.26+** if deploying with Helm charts
PostgreSQL 14 is supported for older Lago versions (≥ 1.0) but newer releases target PostgreSQL 15+. If you are running PostgreSQL 14, plan an upgrade before moving to Lago ≥ 1.30.
# Database maintenance
Source: https://getlago.com/docs/guide/lago-self-hosted/database-maintenance
Keeping your Postgres at its best
Lago relies a lot on Postgres. If you're hosting your own instance, you must ensure Postgres is correctly configured.
First, we recommend installing PgHero and keeping an eye on slow queries: [https://github.com/ankane/pghero]().
## `ANALYZE` and `VACUUM`
Postgres needs to [analyze and vacuum](https://www.postgresql.org/docs/current/routine-vacuuming.html#ROUTINE-VACUUMING) regularly for optimal performance.
Postgres can do it automatically for you. Make sure the `autovacuum_analyze_scale_factor`
and `autovacuum_vacuum_scale_factor` are set to a sensible value. We recommend `0.1` by default,
but it depends on the size of your tables.
```sql theme={"dark"}
SELECT
current_setting('autovacuum_analyze_scale_factor') AS analyze_scale_factor,
current_setting('autovacuum_vacuum_scale_factor') AS vacuum_scale_factor;
```
```sql theme={"dark"}
ALTER SYSTEM
SET autovacuum_vacuum_scale_factor = 0.1;
ALTER SYSTEM
SET autovacuum_analyze_scale_factor = 0.1;
SELECT pg_reload_conf();
```
Some tables need extra attention and usually much lower values: `events`, `invoices`, `charges` and `fees`.
Configure custom override values for these tables.
For example, the `events` table should use a value lower than `0.01`.
Because this factor is a ratio, it's expected to lower it from time to time as your table size grows.
```
ALTER TABLE events
SET (
autovacuum_vacuum_scale_factor = 0.01,
autovacuum_analyze_scale_factor = 0.01
);
```
**The most important table to monitor is `events`.** Depending on your implementation, this table can receive big
bursts of data and should be analyzed and vacuumed often.
### When to run manually
If you send events in batch, it's recommended to analyze and vacuum your `events` table after the batch is ingested:
```sql theme={"dark"}
VACUUM ANALYZE events;
```
Most subscriptions are billed on the first of the month, therefore it's also recommended to analyze and vacuum all tables
before and after billing day.
### Monitor your tables
Check the state of your tables with the following query.
```sql theme={"dark"}
SELECT
s.relname AS tname,
(
SELECT
option_value
FROM
pg_options_to_table(c.reloptions)
WHERE
option_name = 'autovacuum_vacuum_scale_factor'
)::float AS autovacuum_vacuum_scale_factor,
(
SELECT
option_value
FROM
pg_options_to_table(c.reloptions)
WHERE
option_name = 'autovacuum_analyze_scale_factor'
)::float AS autovacuum_analyze_scale_factor,
s.last_vacuum,
s.last_autovacuum,
s.last_analyze,
s.last_autoanalyze,
s.n_dead_tup AS dead_tuples,
s.n_live_tup AS live_tuples,
CASE
WHEN s.n_live_tup = 0 THEN 0
ELSE ROUND(s.n_dead_tup::numeric * 100 / s.n_live_tup, 1)
END AS dead_tuple_ratio
FROM
pg_stat_user_tables s
JOIN pg_class c ON s.relid = c.oid
ORDER BY
autovacuum_analyze_scale_factor ASC,
autovacuum_vacuum_scale_factor ASC,
live_tuples DESC;
```
# Docker
Source: https://getlago.com/docs/guide/lago-self-hosted/docker
Docker is the easiest way to get started with the self-hosted version of Lago.
## Requirements[](#requirements "Direct link to heading")
1. Install [Docker](https://docs.docker.com/get-docker/) on your machine;
2. Make sure [Docker Compose](https://docs.docker.com/compose/install/) is
installed and available (it should be the case if you have chosen to install
Docker via Docker Desktop); and
3. Make sure
[Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) is
installed on your machine.
## Run the Lago App
### Run the app with a one-click Docker command
You can start using the app by using a one-click Docker command in a shell:
```shell theme={"dark"}
docker run -d --name lago -p 80:80 -p 3000:3000 getlago/lago:latest
```
You can now open your browser and go to [http://localhost](http://localhost) to
connect to the application. Just after
[signing up](#signing-up), Lago's API is exposed
at [http://localhost:3000](http://localhost:3000).
### Run the app with advanced Docker commands
If you don't want to use the one-click Docker command, you can start using Lago by running more advanced commands in a shell:
```shell theme={"dark"}
# Get the code
git clone https://github.com/getlago/lago.git
# Go to Lago folder
cd lago
# Fetch all tags
git fetch --tags
# Get the latest tag and checkout
git checkout $(git describe --tags --abbrev=0)
# Set up environment configuration
echo "LAGO_RSA_PRIVATE_KEY=\"`openssl genrsa 2048 | base64 | tr -d '\n'`\"" >> .env
source .env
# Start all the components
docker compose up
```
You can now open your browser and go to [http://localhost](http://localhost) to
connect to the application. Just after
[signing up](#signing-up), Lago's API is exposed
at [http://localhost:3000](http://localhost:3000).
## Signing up[](#signing-up "Direct link to heading")
It's mandatory to create your organization by signing up to Lago. This
organization is the core object of your biller as it's used to invoice your
customers.
1. Write down your `organization name`;
2. Use the main billing `email` of your company; and
3. Define the admin `password` for this email.
You will be able to **invite other email addresses within the application**. If
you already have an account, you can also log in. Once you are able to access
the app, you can retrieve your API key.
## Find your API Key[](#find-your-api-key "Direct link to heading")
Your API Key can be found directly in the UI:
1. Access the **Developer** section from the sidebar;
2. The first tab of this section is related to your **API keys**; and
3. Click the **Copy** button to copy it to clipboard.
## Configuration[](#configuration "Direct link to heading")
### Version[](#version "Direct link to heading")
Docker images are always updated to the last stable version in the
`docker-compose.yml` file. You can use a different tag if needed by checking the
[releases list](https://github.com/getlago/lago/releases).
We recommend avoiding the usage of `latest` tag, you should use the last
tagged version, you can track the latest versions on Dockerhub
* lago-api :
[https://hub.docker.com/repository/docker/getlago/api](https://hub.docker.com/repository/docker/getlago/api)
* lago-front :
[https://hub.docker.com/repository/docker/getlago/front](https://hub.docker.com/repository/docker/getlago/front)
### Environment variables[](#environment-variables "Direct link to heading")
Lago uses the following environment variables to configure the components of the
application. You can override them to customise your setup.
| Variable | Default value | Description |
| ------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `POSTGRES_HOST` | db | (*With Docker compose*) Host name of the postgres server |
| `POSTGRES_DB` | lago | (*With Docker compose*) Name of the postgres database |
| `POSTGRES_USER` | lago | (*With Docker compose*) Database user for postgres connection |
| `POSTGRES_PASSWORD` | changeme | (*With Docker compose*) Database password for postgres connection |
| `POSTGRES_PORT` | 5432 | (*With Docker compose*) Port the postgres database listens to |
| `POSTGRES_SCHEMA` | public | Name of the postgres schema |
| `DATABASE_URL` | | (*Without docker compose*) Full url to the postgres server |
| `DATABASE_POOL` | 10 | Max number of connection opened to the postgres database per api, worker and clock instances |
| `DATABASE_PREPARED_STATEMENTS` | true | Enable or disable prepared statements in the postgres database |
| `REDIS_HOST` | redis | Host name of the redis server |
| `REDIS_PORT` | 6379 | Port the redis database listens to |
| `REDIS_PASSWORD` | | Password of the redis server |
| `LAGO_REDIS_CACHE_HOST` | redis | Host name of the redis cache server |
| `LAGO_REDIS_CACHE_PORT` | 6379 | Port the redis cache server listens to |
| `LAGO_REDIS_CACHE_PASSWORD` | | Password of the redis cache server |
| `LAGO_REDIS_CACHE_POOL_SIZE` | 5 | Max number of connections in the redis cache connection pool |
| `LAGO_MEMCACHE_SERVERS` | | Comma-separated list of memcache servers |
| `LAGO_FRONT_URL` | [http://localhost](http://localhost) | URL of the Lago front-end application.Used for CORS configuration |
| `FRONT_PORT` | 80 | Port the front-end application listens to |
| `LAGO_API_URL` | [http://localhost:3000](http://localhost:3000) | URL of the Lago back-end application |
| `API_URL` | [http://localhost:3000](http://localhost:3000) | URL of the Lago back-end application defined for the front image |
| `API_PORT` | 3000 | Port the back-end application listens to |
| `SECRET_KEY_BASE` | your-secret-key-base-hex-64 | Secret key used for session encryption |
| `SENTRY_DSN` | | Sentry DSN key for error and performance tracking on Lago back-end |
| `SENTRY_DSN_FRONT` | | Sentry DSN key for error and performance tracking on Lago front-end |
| `LAGO_RSA_PRIVATE_KEY` | | Private key used for webhook signatures |
| `LAGO_SIDEKIQ_WEB` | | Activate the Sidekiq web UI, disabled by default |
| `LAGO_ENCRYPTION_PRIMARY_KEY` | your-encryption-primary-key | Encryption primary key used to secure sensitive values stored in the database |
| `LAGO_ENCRYPTION_DETERMINISTIC_KEY` | your-encryption-deterministic-key | Encryption deterministic key used to secure sensitive values stored in the database |
| `LAGO_ENCRYPTION_KEY_DERIVATION_SALT` | your-encryption-derivation-salt | Encryption key salt used to secure sensitive values stored in the database |
| `LAGO_WEBHOOK_ATTEMPTS` | 3 | Number of failed attempt before stopping to deliver a webhook |
| `LAGO_USE_AWS_S3` | false | Use AWS S3 for files storage |
| `LAGO_AWS_S3_ACCESS_KEY_ID` | azerty123456 | AWS Access Key id that has access to S3 |
| `LAGO_AWS_S3_SECRET_ACCESS_KEY` | azerty123456 | AWS Secret Access Key that has access to S3 |
| `LAGO_AWS_S3_REGION` | us-east-1 | AWS S3 Region |
| `LAGO_AWS_S3_BUCKET` | bucket | AWS S3 Bucket name |
| `LAGO_AWS_S3_ENDPOINT` | | S3 compatible storage endpoint. Should be set only if you are using another storage provider than AWS S3 |
| `LAGO_USE_GCS` | false | Use Google Cloud Service Cloud Storage for file storage, ⚠️ If you want to use GCS, you have to pass the credentials json key file to the api and worker service |
| `LAGO_GCS_PROJECT` | | GCS Project name |
| `LAGO_GCS_BUCKET` | | GCS Bucket Name |
| `LAGO_GCS_CREDENTIALS` | | GCS Credentials JSON file path |
| `LAGO_GCS_IAM` | false | GCS IAM Authentication |
| `LAGO_GCS_GSA_EMAIL` | | GCS GSA Email |
| `LAGO_PDF_URL` | [http://pdf:3000](http://pdf:3000) | PDF Service URL on your infrastructure |
| `LAGO_DISABLE_SIGNUP` | | Disable Sign up when running Lago in self-hosted |
| `LAGO_RAILS_STDOUT` | true | Set to true to activate logs on containers |
| `LAGO_DISABLE_WALLET_REFRESH` | | Disable automatic refresh of wallet ongoing balance |
| `LAGO_DISABLE_PDF_GENERATION` | false | Disable automatic PDF generation for invoices, credit notes, and receipts. As a result, the corresponding download endpoints will be unavailable |
| `GOOGLE_AUTH_CLIENT_ID` | | Client ID for Google auth Single Sign On |
| `GOOGLE_AUTH_CLIENT_SECRET` | | Client Secret for Google auth Single Sign On |
We recommend that you change `POSTGRES_PASSWORD`, `SECRET_KEY_BASE`,
`LAGO_RSA_PRIVATE_KEY`, `LAGO_ENCRYPTION_PRIMARY_KEY`,
`LAGO_ENCRYPTION_DETERMINISTIC_KEY` and `LAGO_ENCRYPTION_KEY_DERIVATION_SALT` to
improve the security of your Lago instance:
* `SECRET_KEY_BASE` can be generated using the `openssl rand -hex 64` command.
* `LAGO_RSA_PRIVATE_KEY` can be generated using the
`openssl genrsa 2048 | base64` command.
* `LAGO_ENCRYPTION_PRIMARY_KEY`, `LAGO_ENCRYPTION_DETERMINISTIC_KEY` and
`LAGO_ENCRYPTION_KEY_DERIVATION_SALT` can all be generated using the
`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` command.
### Components[](#components "Direct link to heading")
Lago uses the following containers:
| Container | Role |
| ------------ | --------------------------------------------------------------------- |
| `front` | Front-end application |
| `api` | API back-end application |
| `api_worker` | Asynchronous worker for the API application |
| `api_clock` | Clock worker for the API application |
| `db` | Postgres database engine used to store application data |
| `redis` | Redis database engine used as a queuing system for asynchronous tasks |
| `pdf` | PDF generation powered by Gotenberg |
You can also use your own database or Redis server. To do so, remove the `db`
and `redis` configurations from the `docker-compose.yml` file and update the
environment variables accordingly.
### SSL Support[](#ssl-support "Direct link to heading")
Lago Front application can be configured to support SSL certificates. You have
two options to achieve this:
* by using a self-signed certificate
* by using a signed certificate generated by Let's Encrypt
#### Self Signed Certificate[](#self-signed-certificate "Direct link to heading")
* Run the script to generate the certificates
```shell theme={"dark"}
# Be sure to be in your lago folder
./extra/init-selfsigned.sh
# This should create certificates in the ./extra/ssl/ folder
```
* Take a look at the `docker-compose.yml` file and uncomment the part related to
the Self-Signed certificate
```yaml theme={"dark"}
volumes:
- ./extra/nginx-selfsigned.conf:/etc/nginx/conf.d/default.conf
- ./extra/ssl/nginx-selfsigned.crt:/etc/ssl/certs/nginx-selfsigned.crt
- ./extra/ssl/nginx-selfsigned.key:/etc/ssl/private/nginx-selfsigned.key
- ./extra/ssl/dhparam.pem:/etc/ssl/certs/dhparam.pem
```
* You can now start the front application with a self signed SSL certificate
support
```shell theme={"dark"}
docker-compose up front
```
#### Let's Encrypt Certificate[](#lets-encrypt-certificate "Direct link to heading")
* Edit the file `extra/init-letsencrypt.sh`
* You must replace `lago.example` with your domain name
* You must enter a valid email address
* Edit the file `extra/nginx-letsencrypt.conf`
* You must replace `lago.example` with your domain name
* Uncomment the [Cerbot lines](https://github.com/getlago/lago/blob/5d08b61f4f174f445b258005854aaa18ca049266/docker-compose.yml#L124-L129) in the `docker-compose.yml` file
* Run the following script
```shell theme={"dark"}
# Be sure to be in your lago folder
./extra/init-letsencrypt.sh
# You will be asked to provide some information
# After that you should be able to see the extra/certbot folder
```
* Take a look at the `docker-compose.yml` file and uncomment all the parts
related to the Let's Encrypt's support
```yaml theme={"dark"}
command:
'/bin/sh -c ''while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx
-g "daemon off;"'''
---
volumes:
- ./extra/nginx-letsencrypt.conf:/etc/nginx/conf.d/default.conf
- ./extra/certbot/conf:/etc/letsencrypt
- ./extra/certbot/www:/var/www/certbot
```
* You can now start the front application with the signed certificate support
```shell theme={"dark"}
docker-compose up front
```
### Storage[](#storage "Direct link to heading")
By default, Lago uses the internal storage of the container. You can customize
it by defining different environment variables.
We currently support :
* AWS S3
* AWS S3 Compatibles Endpoints
* Google Cloud Service Cloud Storage
If you use S3 compatibles endpoints, you should set the `LAGO_AWS_S3_REGION`
to a default value (e.g., `us-east-1`), it is required to work properly!
#### AWS S3[](#aws-s3 "Direct link to heading")
You have to set these variables to use AWS S3.
| Name | Description |
| ------------------------------- | --------------------------------------- |
| `LAGO_USE_AWS_S3` | Set to "true" if you want to use AWS S3 |
| `LAGO_AWS_S3_ACCESS_KEY_ID` | AWS S3 Credentials Access Key Id |
| `LAGO_AWS_S3_SECRET_ACCESS_KEY` | AWS S3 Credentials Secret Access Key |
| `LAGO_AWS_S3_REGION` | AWS S3 Region |
| `LAGO_AWS_S3_BUCKET` | AWS S3 Bucket |
#### AWS S3 Compatible Endpoints[](#aws-s3-compatible-endpoints "Direct link to heading")
You have to set these variables to use AWS S3 Compatible Endpoints.
| Name | Description |
| ------------------------------- | ------------------------------------------------------------ |
| `LAGO_USE_AWS_S3` | Set to "true" if you want to use AWS S3 Compatible Endpoints |
| `LAGO_AWS_S3_ENDPOINT` | AWS S3 Compatible Endpoint |
| `LAGO_AWS_S3_ACCESS_KEY_ID` | AWS S3 Credentials Access Key Id |
| `LAGO_AWS_S3_SECRET_ACCESS_KEY` | AWS S3 Credentials Secret Access Key |
| `LAGO_AWS_S3_BUCKET` | AWS S3 Bucket |
| `LAGO_AWS_S3_REGION` | Not used but required by the AWS SDK |
#### Google Cloud Service Cloud Storage[](#google-cloud-service-cloud-storage "Direct link to heading")
You have to set those variables to use GCS Cloud Storage.
| Name | Description |
| ---------------------- | -------------------------------------------------- |
| `LAGO_USE_GCS` | Set to "true" if you want to use GCS Cloud Storage |
| `LAGO_GCS_PROJECT` | GCS Project name |
| `LAGO_GCS_BUCKET` | GCS Bucket name |
| `LAGO_GCS_CREDENTIALS` | GCS Credentials JSON file path |
| `LAGO_GCS_IAM` | GCS IAM Authentication |
| `LAGO_GCS_GSA_EMAIL` | GCS GSA Email |
In the `docker-compose.yml` file, you must uncomment the lines and pass the
correct GCS credentials json file.
```yaml theme={"dark"}
# Example using GCS Credentials File
api:
volumes:
- gcs_keyfile.json:/app/gcs_keyfile.json
api-worker:
volumes:
- gcs_keyfile.json:/app/gcs_keyfile.json
```
### SMTP Configuration[](#smtp-configuration")
In order to use the email feature, you need to configure some environment variables.
In addition to this configuration, defining an organization email in Settings > Organization is mandatory; without it, emails will not be sent.
| Name | Description |
| -------------------- | -------------------------------------------------------------------------------- |
| `LAGO_FROM_EMAIL` | Required to send emails (i.e: [noreply@getlago.com](mailto:noreply@getlago.com)) |
| `LAGO_SMTP_ADDRESS` | Address of the SMTP server |
| `LAGO_SMTP_PORT` | Port of the SMTP Server |
| `LAGO_SMTP_USERNAME` | Username of the SMTP Server |
| `LAGO_SMTP_PASSWORD` | Password of the SMTP Server |
#### Single Sign On using Google authentication[](#single-sign-on-using-google-authentication)
In order to enable Google authentication for single sign on, you have to set those variables.
| Name | Description |
| --------------------------- | -------------------------------------------- |
| `GOOGLE_AUTH_CLIENT_ID` | Client ID for Google auth Single Sign On |
| `GOOGLE_AUTH_CLIENT_SECRET` | Client Secret for Google auth Single Sign On |
# Overview
Source: https://getlago.com/docs/guide/lago-self-hosted/overview
Deploy Lago seamlessly on your infrastructure, compatible with both free and premium editions.
Lago provides versatile hosting options: on your local computer, a dedicated server, or in the cloud.
## Officially Supported
Install Lago on your infrastructure with Docker Compose for easy deployment.
Utilize official Helm charts for deploying Lago on Kubernetes.
# Tracking & Analytics
Source: https://getlago.com/docs/guide/lago-self-hosted/tracking-analytics
## Why does Lago need data?[](#why-does-lago-need-data "Direct link to heading")
We decided to open-source the billing API we would have dreamt to use. As a
consequence of building a self hosted product, we are not able to easily collect
any usage metrics or insights to help us build a better product. This analytics data
helps us understand crucial behaviors and ship better quality to serve your
needs.
We decided to track, by default, some basic behaviors and metrics that are
important to understand the usage of Lago. We have built a minimum required
tracking plan to minimize the security impact of collecting those events. All
the metrics collected are listed in a further section. We make this as
transparent as possible, and we don't track financial information (amounts of
invoices, for instance).
The metrics are collected through the server side Ruby source from
[Segment.com](https://segment.com/docs/connections/sources/catalog/libraries/server/ruby/).
Lago will not collect any financial information about your customers or your
invoices.
## Opting out[](#opting-out "Direct link to heading")
As detailed previously, we ask you to keep as much as possible those tracked
metrics, unless you have a specific reason to opt out. Keeping the metrics
enabled is the easiest way for Lago to get feedback based on product usage.
In the case you need to remove it, we've created a very easy process to opt out.
In the environment variables, by passing the field `LAGO_DISABLE_SEGMENT` to
`true`, you prevent the entire tracking logic from running in your application.
## Detail of events collected by Lago[](#detail-of-events-collected-by-lago "Direct link to heading")
This event flow enables Lago to understand the full activation flow, from the
registration to the first invoice generated.
* `organization_registered`: when you create your organization by signing up to Lago
* `billable_metric_created`: whenever you create a new billable metric
* `plan_created`: whenever you create a new plan
* `customer_created`: whenever a customer is created in Lago
* `subscription_created`: when a subscription is assigned to a customer
* `coupon_created`: whenever a new coupon is created
* `applied_coupon_created`: when a coupon is assigned to a customer
* `add_on_created`: whenever a new add-on is created
* `invoice_created`: when a new invoice is emitted for a specific customer
* `payment_status_changed`: when the payment status of an invoice changes
* `credit_note_issued`: when a new credit note is issued for a customer
* `billable_metric_deleted`: when a billable metric is deleted
* `plan_deleted`: when a plan is deleted
* `customer_deleted`: when a customer account is deleted
## Detail of data collected about your organization[](#detail-of-data-collected-about-your-organization "Direct link to heading")
By default, we collect data of your organization that you used in the signup
form:
* Your organization's **email**; and
* Your organization's **name**.
By [opting out](#opting-out), your organization's data
won't be tracked anymore.
## Examples of collected payloads[](#examples-of-collected-payloads "Direct link to heading")
### billable\_metric\_created[](#billable%5Fmetric%5Fcreated "Direct link to heading")
```javascript theme={"dark"}
Analytics.track(
user_id: 'membership/f37a6b2e-1e79-4710-b0e2-9e451b532461',
event: 'billable_metric_created',
properties: {
aggregation_property: 'amount',
aggregation_type: 'sum_agg',
code: 'atm',
description: '',
hosting_type: 'self',
name: 'ATM',
organization_id: '7c868af7-201c-4ebc-9829-ca902e289e5f',
version: DateTime.iso8601('2022-07-27T00:00:00.000Z')
}
)
```
### customer\_created[](#customer%5Fcreated "Direct link to heading")
```javascript theme={"dark"}
Analytics.track(
user_id: 'membership/4ad5b91f-2a42-4a58-9786-6c07fa03a3d4',
event: 'customer_created',
properties: {
created_at: DateTime.iso8601('2022-08-10T09:34:37.479Z'),
customer_id: '29a17eed-021c-485e-b3fa-93d27db31c95',
hosting_type: 'cloud',
organization_id: '0d173830-9017-4f57-9d11-e3e83b3e38fe',
payment_provider: 'stripe',
version: DateTime.iso8601('2022-08-09T00:00:00.000Z')
}
)
```
### invoice\_created[](#invoice%5Fcreated "Direct link to heading")
```javascript theme={"dark"}
Analytics.track(
user_id: 'membership/f37a6b2e-1e79-4710-b0e2-9e451b532461',
event: 'invoice_created',
properties: {
hosting_type: 'cloud',
invoice_id: '0e31afd2-8e15-49e1-a6fb-11895fa03c97',
invoice_type: 'subscription',
organization_id: 'b3e35674-c3d1-4279-8ef1-271271b6cafb',
version: DateTime.iso8601('2022-07-27T00:00:00.000Z')
}
)
```
# Versions update
Source: https://getlago.com/docs/guide/lago-self-hosted/update-instance
Lago's speed is rapidly increasing—remarkably fast. Billing updates occur frequently, precisely every 1 or 2 weeks. Over the course of a year, we've completed over 70 releases, culminating in approximately 30 comprehensive product updates. Maintaining the currency of your self-hosted instance is paramount for optimal billing engine functionality and alignment with the newest features. Below is a guide to achieve this seamlessly, all within the span of just 5 seconds.
## Why update your Lago self-hosted instance?
### Bug fixes and security enhancements
Updating your Lago open source instance serves a key purpose: resolving bugs and enhancing security protocols.
Just like any software, glitches may emerge, impacting operations and even jeopardizing security.
This is particularly vital in intricate tasks like metering, billing calculations, tax application, and managing financial statements.
By keeping up with updates, you guarantee your instance remains unaffected by recognized problems and vulnerabilities.
This proactive approach maintains a resilient and secure operational landscape for your company.
### Access to new features
Lago consistently evolves to meet the needs of its users. Each update introduces a host of new features aimed at enhancing the user
experience and expanding the capabilities of the platform. Some notable new features that updates might bring include core billing
enhancements, tax-related features, and additional settings options. By updating regularly, you can take advantage of these features and
streamline your workflows.
## Determining update frequency
The frequency of updates varies based on the development cycle of Lago. Generally, updates are released approximately once a week.
Keeping an eye on the [release notes](https://github.com/getlago/lago/releases) provided by the Lago team will give you insight into when updates are available and what changes they
entail. Regularly monitoring these release notes will allow you to stay informed and plan your updates accordingly. Billing updates occur
frequently, precisely every 1 or 2 weeks. Over the course of a year, we've completed over 70 releases, culminating in approximately
30 comprehensive [product updates](https://www.getlago.com/changelog).
## A seamless update process
Updating your Lago open source instance doesn't have to be a daunting task. With a clear procedure in place, you can ensure
a smooth transition to the latest version. Here's a step-by-step guide to help you navigate the update process:
### 1. Access your instance repository
Navigate to the repository where your Lago open source instance is stored. This is typically where you initially cloned or
downloaded the instance.
### 2. Check your current version
In the repository directory, execute the following command to check the current Lago version:
```bash theme={"dark"}
git describe --tags --abbrev=0
```
### 3. Check for the bridge releases
Bridge releases are released as mandatory intermediary releases that must be installed before upgrading to higher versions.
Check the migration guides for (bridge releases)\[[https://getlago.com/docs/guide/migration](https://getlago.com/docs/guide/migration)] and follow the update instructions for each intermediary releases.
### 4. Fetch the latest release
Still in the repository directory, execute the following command to pull the latest release from the remote repository:
```bash theme={"dark"}
# Fetch all tags
git fetch --tags
# Checkout the latest tag
git checkout $(git describe --tags --abbrev=0)
```
This command fetches the most recent release from the remote repository and merges them into your local instance.
To fetch the code of a specific release, use the following command:
```bash theme={"dark"}
git checkout v1.29.0 # Replace with the right version number
```
### 5. Restart the updated instance
Once the code is up-to-date, navigate to the directory containing your Docker Compose file.
Execute the following command to start the updated instance:
```bash theme={"dark"}
docker compose up
```
This command will rebuild and launch your Lago instance with the latest changes.
### 6. Testing new features
After the instance restarts, you can now test our new features and give feedback to the team.
## Addressing concerns about breaking changes
It's natural to be cautious about updates, especially if you fear breaking changes that might disrupt your operations. However, the Lago team understands this concern and takes proactive measures to ensure a smooth update experience. By applying careful consideration to database and UI migrations, Lago mitigates the risk of breaking your application during updates. This thoughtful approach ensures that your workflows and user interfaces remain consistent even after applying the latest updates.
In conclusion, updating your Lago open source instance is a proactive step toward maintaining a secure and feature-rich environment for your operations. By staying current with bug fixes, security enhancements, and new features, you can harness the full potential of the platform. With a well-defined update process and the Lago team's commitment to stability, you can confidently keep your instance up-to-date, ensuring a seamless and productive experience.
# Migration to v1.2.0
Source: https://getlago.com/docs/guide/migration/migration-to-v1.2.0
Dear Lago Community, 👋
We're writing to inform you of upcoming changes in the Lago API that may impact your workflows.
# Why are we doing this?
We understand that change can sometimes be challenging. However, we believe it's essential for growth and improvement.
In our continuous efforts to improve Lago's scalability and flexibility, we are updating our API to streamline the delivery of multiple features. This approach allows us to deliver more value to you and will pave the way for exciting new releases, including:
1. **Infinite Dimension Structure:** With filters, enjoy unlimited depth in dimension structures, enabling you to merge multiple billable metrics into a single event code;
2. **High Usage Ingestion System:** Overcome scalability issues with the ability to send over 10,000 events per second;
3. **Current/Past Usage Performance Improvements:** Experience near-real-time data query with enhanced performance for current and past usage endpoints;
4. **Alerting Scenarios:** Set up custom alerts for critical events such as unpaid invoices, reaching wallet credit thresholds, and many more;
5. **Workflow Creation:** Seamlessly trigger actions within Lago based on custom scenarios, like pausing subscriptions or upgrading plans based on alerts; and
6. **Entitlements Scenarios:** Utilize Lago's aggregated usage data to manage access to product features based on custom rules.
# Timeline
We will maintain the current API logic until **July 9, 2024**. However, after this date, previous versions will no longer be supported. We kindly ask you to update your integration before that day to avoid any potential breaking change.
# What are the changes?
## 1. Transition from `group` to `filters`
We're introducing a new method for building infinite levels of dimensions in Lago with the concept of `filters`.
Creating or editing billable metrics or plans via the user interface will result in the creation of `filters`.
Therefore, you may encounter issues if you make changes via the interface but still use `groups` when creating or editing objects via API.
### Impact on billable metrics
* Introducing `billable_metrics.filters`
* Deprecating `billable_metrics.group`
**Deprecating "billable\_metrics.group"**
The `group` object is deprecated and will be removed from the `billable_metric` object on July 9, 2024.
Please update all integrations currently using `billable_metrics.group` (see example below).
```diff "billable_metrics.group" with 1 level theme={"dark"}
{
"billable_metric": {
…
- "group": {
- "key": "provider",
- "values": ["AWS", "Google", "Azure"]
- }
+ "filters": [
+ {
+ "key": "provider",
+ "values": ["AWS", "Google", "Azure"]
+ }
+ ]
}
}
```
```diff "billable_metrics.group" with 2 levels theme={"dark"}
{
"billable_metric": {
…
- "group": {
- "key": "provider",
- "values": [
- {
- "name": "AWS",
- "key": "region",
- "values": ["Europe", "Africa", "Asia"]
- },
- {
- "name": "Google",
- "key": "region",
- "values": ["Europe", "North America"]
- },
- {
- "name": "Azure",
- "key": "region",
- "values": ["North America", "Asia"]
- }
- ]
- }
+ "filters": [
+ {
+ "key": "provider",
+ "values": ["AWS", "Google", "Azure"]
+ },
+ {
+ "key": "region",
+ "values": ["Europe", "Africa", "Asia", "North America"]
+ }
+ ]
}
}
```
Note that the billable\_metric object will only display filters and groups if
applicable.
### Impact on API endpoints
* Deprecating `List all billable metric groups`.
The endpoint `List all billable metric groups` is deprecated. It will be supported until July 9, 2024 and will then be removed.
```
GET https://api.getlago.com/api/v1/billable_metrics/{code}/groups
```
### Impact on plans
* Introducing `plans.charges.filters`
* Deprecating `plans.charges.group_properties`
**Deprecating "billable\_metrics.groups" with one level**
The `group_properties` object is deprecated and will be removed from `plans.charges` on July 9, 2024.
Please update all integrations currently using `plans.charges.group_properties` (see example below).
```diff theme={"dark"}
{
"plans": {
…
"charges": [
{
…
"properties": {
"amount": "0",
},
- "group_properties": [
- {
- "group_id": "__GROUP_ID__",
- "invoice_display_name": "AWS in Europe",
- "values": {
- "amount": "15",
- }
- },
- {
- "group_id": "__GROUP_ID__",
- "invoice_display_name": "Google in Europe",
- "values": {
- "amount": "20",
- }
- }
- ]
+ "filters": [
+ {
+ "values": {
+ "provider": "AWS",
+ "region": "Europe"
+ },
+ "invoice_display_name": "AWS in Europe"
+ "properties": { "amount": "15" }
+ },
+ {
+ "values": {
+ "provider": "Google",
+ "region": "Europe"
+ },
+ "invoice_display_name": "Google in Europe"
+ "properties": { "amount": "20" }
+ }
+ ]
}
}
}
```
Note that the plan object will only display filters and group\_properties if
applicable.
### Impact on fees
* Introducing `fees.lago_charge_filter_id`
* Deprecating `fees.lago_group_id`
**Deprecating "billable\_metrics.groups" with one level**
The `lago_group_id` field is deprecated and will be removed from `fees` on July 9, 2024.
Please update all integrations currently using `fees.lago_group_id` or `invoice.fees.lago_group_id` (see example below).
```diff theme={"dark"}
{
"fees": {
…
- "lago_group_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
+ "lago_group_id": null,
+ "lago_charge_filter_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
…
}
}
```
This change also affects the invoice object.
### Impact on customer usage
* Introducing `customer_usage.charges_usage.filters`
* Deprecating `customer_usage.charges_usage.groups`
**Deprecating "billable\_metrics.groups" with one level**
The `charges_usage.groups` field is deprecated and will be removed from `customer_usage` on July 9, 2024.
Please update all integrations currently using `customer_usage.charges_usage.groups` (see example below).
```diff theme={"dark"}
{
"customer_usage": {
…
"charges_usage": [
…
{
- "groups": [
- {
- "lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
- "key": "null",
- "value": "europe",
- "units": "0.9",
- "amount_cents": 1000,
- "events_count": 10
- }
- ]
+ "filters": [
+ {
+ "values": {
+ "provider": "AWS",
+ "region": "Europe"
+ }
+ "units": "0.9",
+ "amount_cents": 1000,
+ "events_count": 10
+ }
+ ]
}
]
…
}
}
```
## 2. Mandatory `external_subscription_id` field in event payloads
To enable real-time functionalities, event payloads must include `external_subscription_id`.
Events that only include `external_customer_id` will not be taken into account when aggregating usage in upcoming versions.
* Making `events.external_subscription_id` required
**Making "events.external\_subscription\_id" required**
Sending `event.external_subscription_id` will be mandatory starting July 9, 2024.
Please update all integrations currently using `POST /events` (see example below).
```diff theme={"dark"}
{
"event": {
"transaction_id": "__UNIQUE_ID__",
- "external_customer_id": "__YOUR_CUSTOMER_ID__",
+ "external_subscription_id": "__YOUR_SUBSCRIPTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"timestamp": $(date +%s),
"properties": {
"custom_field": 12
}
}
}
```
## 3. Deprecated fields
We will remove the following deprecated fields in order to preserve the quality of the API and for clarity.
| Deprecated field | Substitution field |
| ---------------------------------------------------- | ---------------------------------------------------- |
| `applied_coupon.expiration_date` | `applied_coupon.expiration_at` |
| `billable_metric.group` | `billable_metric.filters` |
| `coupon.expiration_date` | `coupon.expiration_at` |
| `credit.before_vat` | `credit.before_taxes` |
| `credit.item.lago_id` | `credit.item.lago_item_id` |
| `credit_note.balance_amount_currency` | `credit_note.currency` |
| `credit_note.credit_amount_currency` | `credit_note.currency` |
| `credit_note.refund_amount_currency` | `credit_note.currency` |
| `credit_note.sub_total_vat_excluded_amount_currency` | `credit_note.currency` |
| `credit_note.sub_total_vat_excluded_amount_cents` | `credit_note.sub_total_excluding_taxes_amount_cents` |
| `credit_note.total_amount_currency` | `credit_note.currency` |
| `credit_note.vat_amount_currency` | `credit_note.currency` |
| `credit_note.vat_amount_cents` | `credit_note.taxes_amount_cents` |
| `credit_note.vat_amount_currency` | `credit_note.currency` |
| `customer.billing_configuration.vat_rate` | `customer.taxes[].rate` |
| `customer_usage.amount_currency` | `customer_usage.currency` |
| `customer_usage.charge_usages.groups` | `customer_usage.charge_usages.filters` |
| `customer_usage.from_date` | `customer_usage.from_datetime` |
| `customer_usage.to_date` | `customer_usage.to_datetime` |
| `customer_usage.total_amount_currency` | `customer_usage.currency` |
| `customer_usage.vat_amount_cents` | `customer_usage.taxes_amount_cents` |
| `customer_usage.vat_amount_currency` | `customer_usage.currency` |
| `event_error.input_params.code` | `event_error.event.code` |
| `event_error.input_params.external_customer_id` | `event_error.event.external_customer_id` |
| `event_error.input_params.external_subscription_id` | `event_error.event.external_subscription_id` |
| `event_error.input_params.properties` | `event_error.event.properties` |
| `event_error.input_params.timestamp` | `event_error.event.timestamp` |
| `event_error.input_params.transaction_id` | `event_error.event.transaction_id` |
| `fee.unit_amount_cents` | `fee.precise_unit_amount` |
| `fee.vat_amount_cents` | `fee.taxes_amount_cents` |
| `fee.vat_amount_currency` | `fee.amount_currency` |
| `invoice.amount_currency` | `invoice.currency` |
| `invoice.amount_cents` | `invoice.fees_amount_cents` |
| `invoice.credit_amount_currency` | `invoice.currency` |
| `invoice.credit_amount_cents` | `invoice.credits[].amount_cents` |
| `invoice.fees.group_invoice_display_name` | `invoice.fees.filter_invoice_display_name` |
| `invoice.fees.lago_group_id` | n/a |
| `invoice.legacy` | n/a |
| `invoice.sub_total_vat_excluded_amount_cents` | `invoice.sub_total_excluding_taxes_amount_cent`s |
| `invoice.sub_total_vat_included_amount_cents` | `invoice.sub_total_including_taxes_amount_cent`s |
| `invoice.total_amount_currency` | `invoice.currency` |
| `invoice.vat_amount_cents` | `invoice.taxes_amount_cents` |
| `invoice.vat_amount_currency` | `invoice.currency` |
| `organization.billing_configuration.vat_rate` | `organization.taxes[].rate` |
| `plan.charges.group_properties` | `plan.charges.filters` |
| `subscription.subscription_date` | `subscription.subscription_at` |
| `wallet.balance` | `wallet.balance_cents` |
| `wallet.expiration_date` | `wallet.expiration_at` \` |
# Get involved
Your feedback is important to us. If you have any questions, encounter issues, or have suggestions, please reach out to us via the Slack community.
We understand that breaking changes may require you to adapt, so we apologize for any inconvenience caused. Our team is committed to providing support throughout this transition process to minimize disruptions.
Thanks for your understanding and continued support.
The Lago Team
# Migration to v1.20.0
Source: https://getlago.com/docs/guide/migration/migration-to-v1.20.0
Dear Lago Community, 👋
We will soon release a new version of Lago, including infrastructure improvements to ensure scalability.
# What changes will be made?
One of the changes concerns zero fees, which have no accounting value but still require compute resources. In the next and subsequent versions, Lago will no longer generate these fees.
We know that some of our users have been relying on the `invoice.fees.from_date` and `invoice.fees.to_date` fields linked to zero fees for certain internal processes.
Therefore, we have introduced a new `invoice.billing_periods` field to provide you with the dates of the billing period for each type of charge (see example below).
```diff theme={"dark"}
{
"webhook_type": "invoice.created",
"object_type": "invoice",
"invoice": {
"lago_id": "__INVOICE_ID__",
// TRUNCATED
+ "billing_periods": [
+ {
+ "lago_subscription_id": "__SUBSCRIPTION_ID__",
+ "external_subscription_id": "__EXT_SUBSCRIPTION_ID__",
+ "lago_plan_id": "__PLAN_ID__",
+ "subscription_from_datetime": "2024-12-21T00:00:00Z",
+ "subscription_to_datetime": "2025-01-20T23:59:59Z",
+ "charges_from_datetime": "2024-12-21T00:00:00Z",
+ "charges_to_datetime": "2025-01-20T23:59:59Z",
+ "invoicing_reason": "subscription_periodic"
+ }
+ ]
// TRUNCATED
}
}
```
In addition, if you are running a self-hosted instance of Lago, upgrading it will trigger a migration to delete existing zero fees.
This migration may take some time, so if your database contains a large volume of fees, we recommend that you perform the migration before deploying the new version (see steps below).
Cloud users do not need to follow the instructions below, as the migration will be performed by the Lago Team.
# What should self-hosted users do?
## 1. Check the number of fees
You can run the following SQL query to check the number of fee objects that will be removed from the database.
If the result is greater than 1M (one million), you should perform the migration before deploying the new version.
```
SELECT count(fees.id)
FROM fees
INNER JOIN invoices ON fees.invoice_id = invoices.id
WHERE
invoices.status IN (1, 2, 6) -- finalized, voided and closed
AND fees.fee_type = 0 -- charge
AND fees.amount_cents = 0
AND fees.units = 0
AND fees.pay_in_advance = false
AND fees.true_up_parent_fee_id IS NULL
AND fees.id NOT IN (
SELECT f.true_up_parent_fee_id
FROM fees f
WHERE f.true_up_parent_fee_id IS NOT NULL
)
AND fees.id NOT IN (
SELECT fee_id
FROM adjusted_fees
WHERE adjusted_fees.fee_id IS NOT NULL
)
```
## 2. Remove zero fees
To delete existing zero fees, open a Rails console in a production instance using `bundle exec rails c` and run the following script:
```
class FeesTax < ApplicationRecord; end
sql = <<~SQL
SELECT fees.id FROM fees
INNER JOIN invoices ON fees.invoice_id = invoices.id
WHERE
invoices.status IN (1, 2, 6) -- finalized, voided and closed
AND fees.fee_type = 0 -- charge
AND fees.amount_cents = 0
AND fees.units = 0
AND fees.pay_in_advance = false
AND fees.true_up_parent_fee_id IS NULL
AND fees.id NOT IN (
SELECT f.true_up_parent_fee_id
FROM fees f
WHERE f.true_up_parent_fee_id IS NOT NULL
)
AND fees.id NOT IN (
SELECT fee_id
FROM adjusted_fees
WHERE adjusted_fees.fee_id IS NOT NULL
)
LIMIT 1000
SQL
while (ids = ActiveRecord::Base.connection.select_all(sql).rows.map(&:first)).any?
FeesTax.where(fee_id: ids).delete_all
Fee.where(id: ids).delete_all
puts "Deleted #{ids.size} fees - #{Time.current.iso8601}"
end
puts "All fees have been removed - #{Time.current.iso8601}"
```
It can take a long time to complete this operation. In case of error, you can retry until the script outputs `All fees have been removed - {time}`.
# What is the timeline?
In order to streamline the billing process, we recommend that you perform the migration as soon as possible, and deploy `v1.20.0` as soon as it's available (we will release it **before the end of January**).
Please let us know if you have any questions, we will be happy to help. Thanks!
The Lago Team
# Migration to v1.25.0
Source: https://getlago.com/docs/guide/migration/migration-to-v1.25.0
Dear Lago Community, 👋
We're writing to inform you about important changes in Lago v1.25.0 that will enhance performance and enable new features.
# Why are we doing this?
We are making these changes to:
1. Improve performance by populating the existing `organization_id` field on fees for historical data, which will optimize database queries
2. Enable new features by adding `billing_entity_id` to fees, which will support upcoming functionality
# What are the changes?
## 1. Populating `organization_id` on fees
While the `organization_id` field already exists on fees, we need to populate it for historical data to improve query performance and prepare for upcoming features. This change requires a data migration to populate the field for existing fees.
## 2. Adding `billing_entity_id` to fees
We're introducing the `billing_entity_id` field to fees to support new features in the pipeline. This change also requires a data migration to populate the field for existing fees.
# What should self-hosted users do?
Cloud users do not need to follow these instructions, as the migration will be performed by the Lago Team.
If you're upgrading to v1.25.0, you must complete all the migration steps below to ensure data consistency and proper functionality.
If you're upgrading to v1.25.1 or newer, you must first:
1. Upgrade to v1.25.0
2. Complete all the migration steps below
3. Only then proceed with upgrading to v1.25.1 or newer
This sequence is required to ensure data consistency and proper functionality.
## Migration Steps
1. Install the new version of Lago (v1.25.0)
2. Open the Rails console on your API server:
```bash theme={"dark"}
rails c
```
3. Run the following commands in sequence:
All fees are processed in background jobs, with 1000 fees per batch. You can monitor the progress in the Sidekiq console by checking the batch number argument in the job details.
a. Populate organization\_id from invoices:
```ruby theme={"dark"}
DatabaseMigrations::PopulateFeesWithOrganizationFromInvoiceJob.perform_later
```
Wait for all jobs in Sidekiq to be executed.
Expected processing speed is at least 15 minutes per 1M fees. The actual time may vary depending on your system's resources and database size.
You can verify that the job is fully executed by running:
```ruby theme={"dark"}
Fee.unscoped.where(organization_id: nil).where.not(invoice_id: nil).count
```
This should return 0 when all fees have been processed.
b. Populate organization\_id from subscriptions:
```ruby theme={"dark"}
DatabaseMigrations::PopulateFeesWithOrganizationFromSubscriptionJob.perform_later
```
Wait for all jobs in Sidekiq to be executed.
Expected processing speed is at least 20 minutes per 1M fees. The actual time may vary depending on your system's resources and database size.
You can verify that the job is fully executed by running:
```ruby theme={"dark"}
Fee.unscoped.where(organization_id: nil).where.not(subscription_id: nil).count
```
This should return 0 when all fees have been processed.
c. Verify that all fees have organization\_id:
```ruby theme={"dark"}
Fee.unscoped.where(organization_id: nil).count
```
This should return 0.
d. Populate billing\_entity\_id:
```ruby theme={"dark"}
DatabaseMigrations::PopulateFeesWithBillingEntityIdJob.perform_later
```
Wait for all jobs in Sidekiq to be executed.
Expected processing speed is at least 15 minutes per 1M fees. The actual time may vary depending on your system's resources and database size.
e. Verify that all fees have billing\_entity\_id:
```ruby theme={"dark"}
Fee.where(billing_entity_id: nil).count
```
This should return 0.
# Timeline
We recommend performing this migration as soon as possible after the release of v1.25.0 to ensure optimal performance and access to new features.
# Get involved
If you have any questions or encounter issues during the migration, please reach out to us via the Slack community. Our team is here to help you through this transition.
Thanks for your continued support!
The Lago Team
# Migration to v1.28.1
Source: https://getlago.com/docs/guide/migration/migration-to-v1.28.1
Dear Lago Community, 👋
We're writing to inform you about important changes in Lago v1.28.1 that will enhance data consistency and prepare for upcoming features.
# Why are we doing this?
We are making these changes to:
1. Ensure data consistency by aligning `billing_entity_sequential_id` with `organization_sequential_id` in invoices
2. Prepare for upcoming features that will rely on consistent sequential IDs across the system
# What are the changes?
## Populating `billing_entity_sequential_id` in invoices
We're introducing a data migration to ensure that `billing_entity_sequential_id` matches `organization_sequential_id` for all invoices. This change will maintain data consistency and prepare the system for future enhancements.
# What should self-hosted users do?
Cloud users do not need to follow these instructions, as the migration will be performed by the Lago Team.
If you're upgrading to v1.28.1, you must complete all the migration steps below to ensure data consistency and proper functionality.
## Migration Steps
1. Install the new version of Lago (v1.28.1)
2. Open the Rails console on your API server:
```bash theme={"dark"}
rails c
```
3. Run the following command:
All invoices are processed in background jobs, with 1000 invoices per batch. You can monitor the progress in the Sidekiq console by checking the batch number argument in the job details.
```ruby theme={"dark"}
DatabaseMigrations::PopulateInvoicesBillingEntitySequentialIdJob.perform_later
```
Wait for all jobs in Sidekiq to be executed.
Expected processing speed is at least 1-2 seconds per 1K invoices. The actual time may vary depending on your system's resources and database size.
You can verify that the job is fully executed by running:
```ruby theme={"dark"}
Invoice
.where("organization_sequential_id != 0 AND billing_entity_sequential_id IS NULL")
.or(Invoice.where("organization_sequential_id != 0 AND billing_entity_sequential_id != organization_sequential_id"))
.count
```
This should return 0 when all invoices have been processed.
# Timeline
We recommend performing this migration as soon as possible after the release of v1.28.1 to ensure optimal performance and access to new features.
# Get involved
If you have any questions or encounter issues during the migration, please reach out to us via the Slack community. Our team is here to help you through this transition.
Thanks for your continued support!
The Lago Team
# Migration to v1.29.0
Source: https://getlago.com/docs/guide/migration/migration-to-v1.29.0
Dear Lago Community, 👋
We’re writing to inform you of upcoming changes in the Lago API that may impact your workflows.
## TLDR;
Deprecation on **November 12, 2025** of:
* `PUT /organization` endpoint
* `applied_to_organization` field in `POST /taxes`
* `applied_to_organization` field in `PUT /taxes`
If you’re using a version below `v1.20.0`, please first follow the migration steps for [v1.20.0](/guide/migration/migration-to-v1.20.0), then for [v1.25.0](/guide/migration/migration-to-v1.25.0), then for [v1.28.1](/guide/migration/migration-to-v1.28.1).
Only after completing those should you proceed to v1.29.0.
## Why are we doing this?
In our efforts to improve Lago’s scalability and flexibility, we’re updating our API to streamline feature delivery and maintain relevant endpoints.
This sets the stage for supporting multiple billing entities within a single Lago account.
## Timeline
We will maintain the current API logic until **November 12, 2025**. However, after this date, previous versions will no longer be supported.
We kindly ask you to update your integration before that day to avoid any potential breaking change.
## What are the changes
### 1. From `PUT /organization` to `PUT /billing_entities/{code}`
**Impact:**
* Introducing `PUT /billing_entities/{code}`
* Deprecating `PUT /organization`
In the initiative of supporting multiple billing entities within a single Lago account, the organization object won’t carry any invoicing settings and information.
To update them you’ll have to target the `PUT /billing_entities/{code}`.
```diff "PUT /organization" theme={"dark"}
{
- "organization": {
- "webhook_url": "https://webhook.brex.com",
- "country": "US",
- "address_line1": "100 Brex Street",
- "address_line2": null,
- "state": "NYC",
- "zipcode": "10000",
- "email": "brex@brex.com",
- "city": "New York",
- "legal_name": null,
- "legal_number": null,
- "net_payment_term": 30,
- "tax_identification_number": "US123456789",
- "timezone": "America/New_York",
- "default_currency": "USD",
- "document_numbering": "per_customer",
- "document_number_prefix": "LAGO-INV",
- "email_settings": [
- "invoice.finalized",
- "credit_note.created"
- ],
- "billing_configuration": {
- "invoice_footer": "This is my customer footer",
- "invoice_grace_period": 3,
- "document_locale": "en",
- "vat_rate": 12.5
- }
- }
}
```
```diff "PUT /billing_entities/code" theme={"dark"}
{
+ "billing_entity": {
+ "country": "US",
+ "address_line1": "100 Brex Street",
+ "address_line2": null,
+ "state": "NYC",
+ "zipcode": "10000",
+ "email": "brex@brex.com",
+ "city": "New York",
+ "legal_name": null,
+ "legal_number": null,
+ "net_payment_term": 30,
+ "tax_identification_number": "US123456789",
+ "timezone": "America/New_York",
+ "default_currency": "USD",
+ "document_numbering": "per_customer",
+ "document_number_prefix": "LAGO-INV",
+ "email_settings": ["invoice.finalized", "credit_note.created"],
+ "invoice_footer": "This is my customer footer",
+ "invoice_grace_period": 3,
+ "document_locale": "en",
+ "tax_codes": []
}
}
```
### 2. From `applied_to_organization` field in `POST|PUT /taxes` to `PUT /billing_entities/{code}`
**Impact:**
* Introducing `PUT /billing_entities/{code}`
* Deprecating `applied_to_organization` in `POST /taxes` and `PUT /taxes`
In the initiative of supporting multiple billing entities within a single Lago account, the organization object won’t carry any invoicing settings and information.
You won’t be able to apply a tax to the organization anymore, you’ll have to add these values to a targeted billing entity using `PUT /billing_entities/{code}`.
```diff "PUT /organization" theme={"dark"}
{
"tax": {
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"name": "TVA",
"code": "french_standard_vat",
"description": "French standard VAT",
"rate": 20,
- "applied_to_organization": true,
"created_at": "2023-07-06T14:35:58Z"
}
}
```
```diff "PUT /billing_entities/code" theme={"dark"}
{
"billing_entity": {
"country": "US",
"address_line1": "100 Brex Street",
"address_line2": null,
"state": "NYC",
"zipcode": "10000",
"email": "brex@brex.com",
"city": "New York",
"legal_name": null,
"legal_number": null,
"net_payment_term": 30,
"tax_identification_number": "US123456789",
"timezone": "America/New_York",
"default_currency": "USD",
"document_numbering": "per_customer",
"document_number_prefix": "LAGO-INV",
"email_settings": ["invoice.finalized", "credit_note.created"],
"invoice_footer": "This is my customer footer",
"invoice_grace_period": 3,
"document_locale": "en",
+ "tax_codes": []
}
}
```
## Get involved
Your feedback is important to us. If you have any questions, encounter issues, or have suggestions, please reach out to us via the Slack community.
We understand that breaking changes may require you to adapt, so we apologize for any inconvenience caused.
Our team is committed to providing support throughout this transition process to minimize disruptions.
Thanks for your understanding and continued support.
The Lago Team
# Migration to v1.31.0
Source: https://getlago.com/docs/guide/migration/migration-to-v1.31.0
Dear Lago Community, 👋
We're writing to inform you about important changes in Lago v1.31.0 that will enhance data consistency. application performances and prepare upcoming features.
# What are the changes?
## Filling `organization_id` on every tables of the application
The `organization_id` column was recently added on every tables related to an organization.
Since filling this column is an heavy task, no migration was backfilling it for existing records. It was only populated on newly created records.
As we now need to be able to rely on this column in the application, we have to make sures that every single records has an `organization_id` value.
# Why are we doing this?
These changes are made to increase the performannces of the application and to ease the development on future features.
# What should self-hosted users do?
Cloud users do not need to follow these instructions as the migration will be performed by the Lago Team.
If you’re using a version below `v1.20.0`, please first follow the migration steps for [v1.20.0](/guide/migration/migration-to-v1.20.0), then for [v1.25.0](/guide/migration/migration-to-v1.25.0), then for [v1.28.1](/guide/migration/migration-to-v1.28.1), then for [v1.29.0](/guide/migration/migration-to-v1.29.0).
Only after completing those should you proceed to v1.31.0.
## Migration Steps
1. Install the Lago version 1.30.0
2. Open a shell (bash) on your API server
3. Run the migration task:
```bash theme={"dark"}
bundle exec rails migrations:fill_organization_id
```
The task will:
* Check for all database table to identify the ones that require a migration
* Enqueue jobs for each tables needing a backfill
* Loop over all migrating tables until all records are updated
All resources are processed in background jobs, with 1000 records per batch.
The task will monitor the values and give you the number of remaing records.
```bash theme={"dark"}
##################################
Starting filling organization_id
#### Checking for resource to fill ####
"- Checking AddOn::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking AdjustedFee: 🔎"
" -> Nothing to do ✅"
"- Checking AppliedCoupon: 🔎"
" -> Nothing to do ✅"
"- Checking AppliedInvoiceCustomSection: 🔎"
" -> Nothing to do ✅"
"- Checking AppliedUsageThreshold: 🔎"
" -> Nothing to do ✅"
"- Checking BillableMetricFilter: 🔎"
" -> Nothing to do ✅"
"- Checking BillingEntity::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking ChargeFilterValue: 🔎"
" -> Nothing to do ✅"
"- Checking ChargeFilter: 🔎"
" -> Nothing to do ✅"
"- Checking Charge::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking Charge: 🔎"
" -> Nothing to do ✅"
"- Checking Commitment::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking Commitment: 🔎"
" -> Nothing to do ✅"
"- Checking CouponTarget: 🔎"
" -> Nothing to do ✅"
"- Checking CreditNoteItem: 🔎"
" -> Nothing to do ✅"
"- Checking CreditNote::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking CreditNote: 🔎"
" -> Nothing to do ✅"
"- Checking Credit: 🔎"
" -> Nothing to do ✅"
"- Checking Metadata::CustomerMetadata: 🔎"
" -> Nothing to do ✅"
"- Checking Customer::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking DataExportPart: 🔎"
" -> Nothing to do ✅"
"- Checking DunningCampaignThreshold: 🔎"
" -> Nothing to do ✅"
"- Checking Fee::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking IdempotencyRecord: 🔎"
" -> Nothing to do ✅"
"- Checking IntegrationCollectionMappings::BaseCollectionMapping: 🔎"
" -> Nothing to do ✅"
"- Checking IntegrationCustomers::BaseCustomer: 🔎"
" -> Nothing to do ✅"
"- Checking IntegrationItem: 🔎"
" -> Nothing to do ✅"
"- Checking IntegrationMappings::BaseMapping: 🔎"
" -> Nothing to do ✅"
"- Checking IntegrationResource: 🔎"
" -> Nothing to do ✅"
"- Checking Metadata::InvoiceMetadata: 🔎"
" -> Nothing to do ✅"
"- Checking InvoiceSubscription: 🔎"
" -> Nothing to do ✅"
"- Checking PaymentRequest::AppliedInvoice: 🔎"
" -> Nothing to do ✅"
"- Checking Invoice::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking PaymentProviderCustomers::BaseCustomer: 🔎"
" -> Nothing to do ✅"
"- Checking Payment: 🔎"
" -> Nothing to do ✅"
"- Checking Payment: 🔎"
" -> Nothing to do ✅"
"- Checking Plan::AppliedTax: 🔎"
" -> Nothing to do ✅"
"- Checking RecurringTransactionRule: 🔎"
" -> Nothing to do ✅"
"- Checking Refund: 🔎"
" -> Nothing to do ✅"
"- Checking Subscription: 🔎"
" -> Nothing to do ✅"
"- Checking UsageThreshold: 🔎"
" -> Nothing to do ✅"
"- Checking WalletTransaction: 🔎"
" -> Nothing to do ✅"
"- Checking Wallet: 🔎"
" -> Nothing to do ✅"
"- Checking Webhook: 🔎"
" -> Nothing to do ✅"
#### All good, ready to Upgrade! ✅ ####
```
4. Install Lago v1.31.0
# Get Involved
If you have any questions or encounter issues during the migration, please reach out to us via the Slack community. Our team is here to help you through this transition.
Thanks for your understanding and continued support.
The Lago Team
# Migration to v1.32.0
Source: https://getlago.com/docs/guide/migration/migration-to-v1.32.0
Dear Lago Community, 👋
We're writing to inform you about important changes in Lago v1.32.0 that will enhance your payments and subscriptions management experience and introduce a new unified upgrade process.
# What are the changes?
## New Pages and Enhanced Functionality
This version introduces several new pages including payments and subscriptions with enhanced search and filtering capabilities. The new interfaces provide detailed information and improved user experience for managing records.
**Important:** To ensure the payments page displays correctly and search functionality works properly, you must run the post-upgrade rake task described below.
## Unified Upgrade Process
Starting from this version, all post-upgrade tasks will be executed using a single rake task: `bundle exec rails upgrade:perform_required_jobs`, simplifying the upgrade process and ensuring consistency across all installations.
# Why are we doing this?
These changes are made to:
1. Provide better management capabilities for payments and subscriptions with advanced search and filtering
2. Ensure proper data indexing and display for the new payment search functionality
3. Streamline the upgrade process by consolidating all post-upgrade tasks into a single command
4. Improve user experience and system maintainability
# What should self-hosted users do?
Cloud users do not need to follow these instructions as the migration will be performed by the Lago Team.
If you're using a version below `v1.20.0`, please first follow the migration steps for [v1.20.0](/guide/migration/migration-to-v1.20.0), then for [v1.25.0](/guide/migration/migration-to-v1.25.0), then for [v1.28.1](/guide/migration/migration-to-v1.28.1), then for [v1.29.0](/guide/migration/migration-to-v1.29.0), then for [v1.31.0](/guide/migration/migration-to-v1.31.0).
Only after completing those should you proceed to v1.32.0.
## Migration Steps
1. Install Lago v1.32.0
2. Open a shell (bash) on your API server
3. Run the unified upgrade task:
```bash theme={"dark"}
bundle exec rails upgrade:perform_required_jobs
```
This task will automatically execute all required post-upgrade jobs for this version, including the necessary data indexing for the payments page search functionality. The process runs in the background and may take some time depending on your data size.
All resources are processed in background jobs to ensure system stability during the upgrade process.
# Timeline
We recommend performing this migration as soon as possible after the release of v1.32.0 to ensure optimal performance and access to the new payment and subscription management features.
# Get Involved
If you have any questions or encounter issues during the migration, please reach out to us via the Slack community. Our team is here to help you through this transition.
Thanks for your understanding and continued support.
The Lago Team
# Migration to v1.43.0
Source: https://getlago.com/docs/guide/migration/migration-to-v1.43.0
Dear Lago Community, 👋
We're writing to inform you about important changes in Lago v1.43.0 that will enforce data consistency on charges and fixed charges.
# What are the changes?
## Adding NOT NULL constraint on `code` for charges and fixed charges
The `code` column on `charges` and `fixed_charges` tables will now be required (NOT NULL constraint).
Previously, this column was nullable and only populated on newly created records. Starting from v1.43.0, the database will enforce that every charge and fixed charge has a `code` value.
The backfill tasks (available since v1.42.0) will:
* Populate `charges.code` using the associated billable metric's code
* Populate `fixed_charges.code` using the associated add-on's code
* When duplicates exist within the same plan, a suffix (`_2`, `_3`, etc.) is appended to ensure uniqueness
# Why are we doing this?
These changes are made to ensure data integrity and enable the ability to independently update a charge or a fixed charge via the API. The `code` serves as a unique identifier within a plan, which is required by the new dedicated endpoints for managing charges and fixed charges.
# What should self-hosted users do?
Cloud users do not need to follow these instructions as the migration will be performed by the Lago Team.
If you're using a version below `v1.20.0`, please first follow the migration steps for [v1.20.0](/guide/migration/migration-to-v1.20.0), then for [v1.25.0](/guide/migration/migration-to-v1.25.0), then for [v1.28.1](/guide/migration/migration-to-v1.28.1), then for [v1.29.0](/guide/migration/migration-to-v1.29.0), then for [v1.31.0](/guide/migration/migration-to-v1.31.0), then for [v1.32.0](/guide/migration/migration-to-v1.32.0).
Only after completing those should you proceed to v1.43.0.
## Migration Steps
1. Install Lago v1.42.0
2. Open a shell (bash) on your API server
3. Run the upgrade task:
```bash theme={"dark"}
bundle exec rails upgrade:perform_required_jobs
```
The task will:
* Backfill `code` on all charges that have a NULL value
* Backfill `code` on all fixed charges that have a NULL value
* Process records in batches of 1,000
All resources are processed in background jobs. The task will monitor progress and confirm when all records have been updated.
4. Install Lago v1.43.0
# Get Involved
If you have any questions or encounter issues during the migration, please reach out to us via the Slack community. Our team is here to help you through this transition.
Thanks for your understanding and continued support.
The Lago Team
# Create add-ons
Source: https://getlago.com/docs/guide/one-off-invoices/create-add-ons
Add-ons let you apply one-time fixed fees to plans or one-off invoices. They are commonly used for setup fees, one-off charges, or customer success fees.
Add-ons represent non-recurring fixed charges. Once created, they can be:
* Added to a plan as a [fixed charge](/guide/plans/charges/fixed-charges), or
* Applied directly to a customer through a [one-off invoice](/guide/one-off-invoices/create-one-off-invoices)
To create an add-on from the dashboard:
1. Open the **Add-ons** section from the side menu
2. Click **Add an add-on**
3. Enter a name, code, and optional description
4. Define the default amount and currency *(these values can be overridden when issuing an invoice)*
5. Click **Add add-on** to confirm
```bash Create a Setup Fee add-on theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/add_ons" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"add_on": {
"name": "Setup Fee",
"code": "setup",
"amount_cents": 50000,
"amount_currency": "USD",
"description": "Charge a setup fee for new customers."
}
}'
```
## Use an add-on
Once created, an add-on can be:
* Added to a **plan** as a fixed charge, or
* Applied to a **specific customer** through a one-off invoice
## Manage add-ons
From the **Add-ons** section, you can edit or delete existing add-ons using the ellipsis menu.
* **Editing** lets you update the name, code, description, and default values
* **Deleting** permanently removes the add-on from all plans and subscriptions where it is used *(this action cannot be undone)*
# Issue one-off invoices
Source: https://getlago.com/docs/guide/one-off-invoices/create-one-off-invoices
One-off invoices allow you to bill immediately one or several add-ons to a customer. This guide will show you how to create a one-off invoice for a specific customer using the add-ons.
## Create a one-off invoice
To create a one-off invoice for a specific customer:
1. Select the customer from the list of customers; and
2. Click the **"Actions"** button located in the upper-right corner and select **"Create one-off invoice"**.
## Adding add-ons to one-off invoices
Now that you have started the flow to create a one-off invoice, it's time to add one or several add-ons to it:
1. Click **"Add an add-on"** to add a new add-on to the invoice;
2. Edit the number of units applied for a specific add-on;
3. Define the billing period of the add-on, this period can be set in the past, now or in the future;
4. Edit the unit price of a specific add-on (you can define it as 0 if needed);
5. Edit the description of the add-on displayed on the invoice; and
6. Click **"Create"** to issue your one-off invoice.
```bash Assign add-ons to create a one-off invoice theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/invoices" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"invoice": {
"external_customer_id": "hooli_1234",
"currency": "USD",
"fees": [
{
"add_on_code": "setup_fee",
"units": 1,
"unit_amount_cents": 50000,
"description": "Implementation fee with a solution engineer",
"from_datetime": "2025-01-01T00:00:00Z",
"to_datetime": "2025-12-31T23:59:59Z"
},
{
"add_on_code": "customer_success",
"units": 2,
"unit_amount_cents": 100000,
"description": "One off customer success fee",
"from_datetime": "2025-01-01T00:00:00Z",
"to_datetime": "2025-12-31T23:59:59Z"
}
]
}
}'
```
## Application scope of one-off invoices
Here are a few things to keep in mind about one-off invoices:
* One-off invoices are issued immediately and can include the same add-on multiple times.
* If the currency of the customer is already defined, the currency of the one-off invoice must be the same.
* You can use the same add-on to create one-off invoices for multiple customers whose subscriptions don't have the same currency or to apply a different amount for one of these customers.
* Coupons or prepaid credits (discounts) **do not apply** to one-off invoices.
* One-off invoices are subject to taxes, as defined in the customer view.
Note that when using the API endpoint, if the amount and currency are null, Lago will apply the default amount and currency defined in the UI.
## Invoicing
As mentioned previously, a **one-off invoice is invoiced straight away**. You are able to find one-off invoices via a webhook message called `invoice.one_off_created`.
# Payment pre-authorization
Source: https://getlago.com/docs/guide/payments/payment-authorization
Learn how to validate payment methods before creating, upgrading, or downgrading customer subscriptions.
**Stripe Integration Only**
While Lago supports multiple payment providers, payment pre-authorization is currently only available with Stripe.
## Introduction
By default, when creating a subscription, Lago follows this process:
1. Creates and activates the subscription (unless scheduled for the future or it's a downgrade);
2. Generates the invoice asynchronously; and
3. Processes the payment asynchronously.
This means it's possible to create an active subscription for a customer even if the payment later fails. While this behavior is intentional, it may not be ideal for all use cases.
To address this, Lago now offers payment pre-authorization, **allowing you to verify the validity of a payment method for a specific amount before creating the subscription.**
**Important**: If the pre-authorization fails, the entire process is aborted and no subscription is created.
## How Pre-Authorization Works
Pre-authorization creates a Payment Intent in Stripe to verify that the payment amount can be collected. When successful, the amount is temporarily held on the customer's account but not captured.
**Note**: The held funds are automatically released immediately after successful verification.
Pre-authorization can fail for several reasons:
* Invalid card details;
* Insufficient funds; and
Please note that if 3DS is required during pre-authorization, the card is considered valid and the subscription is created.
## Understanding the limitations
While pre-authorization helps reduce payment failures, it cannot guarantee successful invoice payment because:
1. Conditions may change between pre-authorization and actual payment:
* Customer's account balance may decrease
* Card may be blocked or expired
2. A bank might approve the pre-authorization but still require 3D Secure authentication for the actual payment
## Implementation guide
To implement pre-authorization, use the `POST /api/v1/subscriptions` endpoint with additional parameters. The standard `subscription` parameters remain unchanged.
You must manually specify the amount to authorize, as the final amount (including taxes) is only calculated during invoice generation.
### Request format
```json theme={"dark"}
{
"authorization": {
"amount_cents": 100, // Amount in cents (e.g., 100 = 1 EUR)
"amount_currency": "EUR"
},
"subscription": {
// Standard subscription parameters
}
}
```
### Response format
```json theme={"dark"}
{
"status": 422,
"error": "Unprocessable Entity",
"code": "provider_error",
"provider": {
"code": "stripe_code"
},
"error_details": {
"code": "error_code",
"message": "error_message",
"request_id": "request_id",
"http_status": "http_status",
"http_body": {
// Complete Stripe error response
}
}
}
```
# Payment methods (Beta)
Source: https://getlago.com/docs/guide/payments/payment-methods
Customer’s payment instrument (card, bank account, direct debit mandate, etc.), managed by an external Payment Service Provider (PSP).
This feature is currently in beta and requires a data migration. To get access, please [contact us](mailto:hello@getlago.com).
A payment method in Lago is a stored reference to a customer’s payment instrument (card, bank account, direct debit mandate, etc.), managed by an external Payment Service Provider (PSP).
Lago does not store raw payment details. Instead, it stores:
* A **provider\_customer\_id**, linking the Lago customer to their PSP record (e.g., cus\_abc123 in Stripe)
* A **provider\_method\_id**, which identifies the specific payment instrument stored in the PSP
When a payment is required (invoice, wallet top-up, etc.), Lago delegates the charge to the PSP using the stored provider\_customer\_id and targets the appropriate provider\_payment\_id. The PSP then processes the payment using the selected payment method.
## How payment methods are created
There are four ways a payment method can be created and stored.
### 1. Checkout URL
This is the primary path for new customers. When a customer is created in Lago with a payment provider assigned and `sync_with_provider` set to `true`, Lago:
1. Creates a corresponding customer record in the PSP.
2. Emits a `customer.checkout_url_generated` webhook containing a checkout URL.
3. You redirect the customer to this URL.
4. The customer completes the form — no funds are collected at this stage.
5. Once confirmed, the PSP securely stores the payment method for future transactions.
The checkout URL expires after **24 hours**.
For **GoCardless**, the checkout flow collects a direct debit mandate rather than a card. The mandate must be validated by GoCardless before the first payment can be processed, which can take up to six business days. The currency of the mandate must match the currency of the customer's subscription plan.
### 2. Syncing an existing PSP customer
If the customer already exists in the PSP with a payment method on file, you can link them to Lago without going through the checkout flow.
By setting `sync_with_provider` to `false` and providing the existing `provider_customer_id`, Lago will retrieve the default payment method stored in the PSP and attach it to the customer. No checkout URL is generated.
This is useful when migrating customers from another billing system, or when the customer and their mandate/card already exist in Adyen or GoCardless.
### 3. Generate a new checkout URL
Once the customer is connected to a PSP, you can generate a new checkout URL at any time to capture new payment method:
To generate a new checkout URL:
1. Navigate to the customer's information tab;
2.In **payment methods** section, click on **Add a payment method**
2. Click **Generate link** — Lago requests a new checkout URL from the PSP;
3. Copy the generated URL and share it with your customer.
The checkout URL expires after **24 hours**.
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers/:external_id/checkout_url" \
--header "Authorization: Bearer $API_KEY"
```
### 4. Auto-capture from Payment link
When an invoice has a `pending` or `failed` payment status, you can generate a one-off payment checkout link:
```
POST /api/v1/invoices/{lago_id}/payment_url
```
When the customer pays through this link, Lago **automatically captures and stores** the payment method used in the transaction. This means future invoices can be charged automatically without requiring a separate checkout step.
This path is natively supported for **Stripe** and **Adyen** integrations.
## How payment methods are assigned to billing objects
You can define a payment method when creating:
* A subscription
* A one-off invoice
* A wallet top-up (purchased or recurring)
If no payment method is specified, Lago falls back to the default payment method defined in Lago (not necessarily the PSP default).
You can also select **Manual payment** as a payment method.
For example, a subscription can use a stored card, while a one-off invoice is marked as manual — you'll have to record a manual payment to mark the invoice as paid.
### Inactive payment methods
You can mark a payment method as **inactive**. They cannot be selected or attached to any billing object.
If the default payment method becomes inactive, Lago will automatically switch the related billing object to **Manual payment**. This prevents unintended charges using another stored method. You must then update the billing object with a valid payment method.
### Multiple subscriptions with different payment methods
By default, Lago groups multiple subscription invoices for the same customer into a single invoice when they are generated on the same day.
Now that each subscription can have its own payment method, Lago automatically splits invoices by payment method — and groups invoices accordingly.
# Payment providers integrations
Source: https://getlago.com/docs/guide/payments/payment-providers
Automatically collect payments from Payment Providers by using native integrations or webhook messages.
## Native payment providers integrations
Lago provides native, first-class integrations with leading payment providers. With these integrations, you can:
* Automatically **synchronize customer information** between Lago and your payment gateway;
* Automatically **trigger payment intents** in your payment provider;
* Generate **shareable payment or checkout links** for your customers;
* Automatically **update invoice payment statuses** in Lago; and
* Automatically **initiate refunds** in your payment provider for credit notes.
Below is the exhaustive list of payment providers natively supported by Lago:
}
href="/integrations/payments/gocardless-integration"
>
GoCardless is the global leader of direct debits bank payments.
Official
}
href="/integrations/payments/stripe-integration"
>
Stripe is a suite of APIs powering online payment processing, especially
card payments.
Official
}
href="/integrations/payments/adyen-integration"
>
Adyen is an omnichannel payment processing company providing multiple ways
to accept payments.
Official
}
href="/integrations/payments/cashfree-integration"
>
Cashfree Payments is India's leading payments and API banking company.
Community
}
href="/integrations/payments/moneyhash-integration"
>
Moneyhash is the leading payment infrastructure software in Africa and the Middle East.
Community?
}
href="/integrations/payments/custom-payment-integration"
>
This guide helps you integrate Lago with a custom payment provider. Build your own integration by following these steps.
Community
## Payment collection process
To collect payments from your customers, you can:
* Use our native [Payment Providers integrations](/integrations/introduction#payments-integrations); or
* Use the [webhooks](/api-reference/webhooks/messages) sent by Lago to transmit billing information to your PSP (e.g. Paddle, Razorpay, Authorize.net, internal ledger, etc.).
# Payment retries
Source: https://getlago.com/docs/guide/payments/payment-retries
## Retry an invoice payment
Whether you use one of our native integrations or rely on our [webhooks](/api-reference/webhooks/messages) to collect payments, you have the ability to manually resend payments for collection when needed.
To re-trigger the payment process through the user interface:
1. Access the **"Invoices"** section via the side menu;
2. Open the **"Outstanding"** tab;
3. Find the invoice for which you would like to collect payment;
4. Click the **ellipsis icon** on the right; and
5. Select **"Resend for collection"**.
In the **"Outstanding"** and **"Overdue"** tabs of the **"Invoices"** section, you can also click **"Resend for collection"** in the upper right corner to re-trigger the payment process for all invoices in the respective lists.
Invoices that are overdue are available both on the **"Outstanding"** and the **"Overdue"** tabs. Make sure you resend for collection from the **"Overdue"** tab if you wish to collect payment for past due invoices only.
When you resend a payment for collection, Lago automatically attempts to process the payment.
* If the payment **succeeds**, an `invoice.payment_status_updated` webhook is sent.
* If the payment **fails**, an `invoice.payment_failure` webhook is sent.
* If the customer **doesn’t have a payment method** available for Lago to retry, an `invoice.payment_failure` webhook is also sent.
It is also possible to trigger payment retries via the API ([learn more](/api-reference/invoices/retry)).
## Generate a payment url
If you’re using a payment provider integration, you can generate a payment URL [for unpaid invoices](/api-reference/invoices/payment-url) or [unpaid wallet transactions](/api-reference/wallets/wallet-transaction-payment-url) to share with the end customer. This URL initiates a checkout flow where the customer can pay the invoice or wallet transaction by providing a payment method.
To prevent duplicate payments, the generated URL is idempotent. It remains valid and unchanged for 24 hours, regardless of how many times the endpoint is called. After this period, a new URL will be issued upon the next call to the endpoint, valid for the following 24 hours.
# Payment receipts
Source: https://getlago.com/docs/guide/payments/receipts
Lago automatically generates payment receipts for each payment processed, whether manual or through payment provider integrations.
**PREMIUM ADD-ON** ✨
This feature is available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium feature.
## Receipt object
Payment receipts include (but are not limited to):
* Receipt number;
* Payment date;
* Customer information;
* Payment amount;
* Remaining due payment amount;
* Reference to impacted invoices; and
* Fees, taxes and total amount.
You can **download receipts** or use the receipt object to create your own receipt template.
## Multiple receipts per invoice
An invoice can have multiple receipts associated with it, especially in cases where:
* Partial payments are made over time; or
* Manual payments are recorded alongside automatic payments.
This flexibility allows you to accurately track all payments made towards an invoice, maintaining a clear audit trail of the payment history.
For accounting and compliance purposes, Lago maintains the integrity of finalized invoices by never modifying them. Instead, payment receipts track all payment activities and remaining balances.
## Downloading receipts
You can download payment receipts directly from the payment details page in the Lago dashboard.
## Receipt email notifications
Lago automatically sends email notifications containing the payment receipt and the corresponding invoices to the customer's email address when a payment is processed. This ensures that your customers have immediate access to their payment documentation and can easily track their payment history.
1. Go to **Settings** in the Lago dashboard;
2. Select the **Emails** tab;
3. Find the "Payment receipt" email scenario; and
4. Toggle the switch to enable email notifications for payment receipts.
Once enabled, customers will automatically receive an email with their payment receipt and corresponding invoices whenever a payment is processed.
# Record manual payments
Source: https://getlago.com/docs/guide/payments/record-manual-payments
On top of our native integrations with leading payment providers, you can also record manual payments.
For manual or non-Lago-native payment methods, you can record payments via the API or UI.
Both partial and full payments can be recorded; however, an invoice's payment status will only update to succeeded when it is fully settled.
To record a payment:
1. Navigate to an unpaid invoice;
2. Click the “Record Payment” button;
3. Select the payment date;
4. Enter the payment reference;
5. Specify the payment amount (partial or full); and
6. Confirm to record the payment.
```bash Record a manual payment theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/payments \
--header 'Authorization: Bearer ' \
--header 'Content-Type: application/json' \
--data '{
"payment": {
"invoice_id": "486b147a-02a1-4ccf-8603-f3541fc25e7a",
"amount_cents": 100,
"reference": "ref1",
"paid_at": "2025-02-20"
}
}'
```
# Arrears vs Advance
Source: https://getlago.com/docs/guide/plans/charges/arrears-vs-advance
Usage-based charges can be either charged in advance or in arrears
You have the flexibility to define the nature of charges associated with your products or services. Specifically, you can
**determine whether a charge has to be paid in arrears (at the end of the period), or in advance (immediately on event ingestion)**.
## Charges paid in arrears[](#charges-arrears "Direct link to heading")
If you opt for charges to be settled in arrears, they will be invoiced at the end of the billing period based on
the actual usage during that period. This payment option is ideal for usage types like storage, API calls, or compute,
where it is more practical to wait until the end of the period before billing. By default, all charges are configured to be
billed in arrears.
You can easily manage this billing settings through the user interface. Within the UI, you will find options to customize
the invoice cadence by setting a charge as invoiced in arrears.
Define `pay_in_advance : false` on a charge to bill it in arrears:
```bash Define a charge as paid in arrears {16, 22} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Premium",
"code": "premium",
"interval": "monthly",
"description": "Premium plan for SMB companies",
"amount_cents": 50000,
"amount_currency": "USD",
"trial_period": 0.0,
"pay_in_advance": true,
"bill_charges_monthly": true,
"charges": [
{
"billable_metric_id": "1111_2222_3333_4444",
"charge_model": "percentage",
"pay_in_advance": false,
"invoiceable": true,
"min_amount_cents": 100,
"properties": {
"rate": "0.5",
"fixed_amount": "1",
"free_units_per_events": 3,
"free_units_per_total_aggregation": null
}
}
]
}
}'
```
## Charges paid in advance[](#charges-advance "Direct link to heading")
With this payment option, charges are invoiced immediately upon any changes in usage. It is particularly useful for scenarios
where you need to bill customers instantly for usage-based actions, such as new user seat or integrations.
You can easily manage this billing settings through the user interface. Within the UI, you will find options to customize
the invoice cadence by setting a charge as invoiced in advance.
Define `pay_in_advance : true` on a charge to bill it in advance:
```bash Define a charge as paid in advance {16, 22} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Premium",
"code": "premium",
"interval": "monthly",
"description": "Premium plan for SMB companies",
"amount_cents": 50000,
"amount_currency": "USD",
"trial_period": 0.0,
"pay_in_advance": true,
"bill_charges_monthly": true,
"charges": [
{
"billable_metric_id": "1111_2222_3333_4444",
"charge_model": "percentage",
"pay_in_advance": true,
"invoiceable": true,
"min_amount_cents": 100,
"properties": {
"rate": "0.5",
"fixed_amount": "1",
"free_units_per_events": 3,
"free_units_per_total_aggregation": null
}
}
]
}
}'
```
# Custom price
Source: https://getlago.com/docs/guide/plans/charges/charge-models/custom-price
**Premium feature ✨**:
This feature is only available to users with a premium license. Please **[contact us](mailto:hello@getlago.com)** to get access to this feature.
Lago's basic interface and API allow you to configure prices using default price models, such as standard, graduated, or percentage-based models.
However, for more sophisticated products, you may need more complex pricing capabilities than those offered by Lago's default settings.
To meet this need, Lago can parse your custom code (using JSON), enabling you to implement advanced pricing rules for your charges.
This feature provides the flexibility to create tailored pricing models that precisely fit your product's requirements.
By leveraging custom code, you can ensure your pricing strategy is as dynamic and nuanced as your product demands.
This custom pricing can be set using the `custom_properties` attribute for a specific charge.
You can edit this custom price code and even overwrite it for a particular subscription.
Here is an example of a custom price model defining tiers across multiple properties:
```json theme={"dark"}
"properties": {
"custom_properties": {
"ranges": [
{ "from": 0, "to": 10, "storage_eu": "0", "storage_us": "0", "storage_asia": "0" },
{ "from": 10, "to": 20, "storage_eu": "0.10", "storage_us": "0.20", "storage_asia": "0.30" },
{ "from": 20, "to": null," storage_eu": "0.20", "storage_us": "0.30", "storage_asia": "0.40" }
]
}
}
```
# Dynamic
Source: https://getlago.com/docs/guide/plans/charges/charge-models/dynamic
Only the `sum` aggregation type is compatible with the `dynamic` charge model.
If you have a different use case, please reach out to the Lago team for assistance.
Select the dynamic charge model if you calculate the price manually or if prices fluctuate during a billing period (e.g., for SMS APIs, AI models, etc.), and you want to apply a specific **total amount** per event using the property `precise_total_amount_cents`.
Let’s take the example of our AI company. You may want to charge a custom price per event. Consider the following list of events:
| Event | Metric | Unit | Total amount |
| ------------- | ------------------ | ---- | ------------ |
| Transaction 1 | Dedicated Instance | 7 | \$0.70 |
| Transaction 2 | Dedicated Instance | 5 | \$0.55 |
| Transaction 3 | Dedicated Instance | 10 | \$2.20 |
```bash List of events theme={"dark"}
{
"events": [
{
"transaction_id": "transaction_1",
"external_subscription_id": "123456789",
"code": "dedicated_instance",
"timestamp": 1728554400,
"precise_total_amount_cents": "70", //event total amount
"properties": {
"unit": "7"
}
},
{
"transaction_id": "transaction_2",
"external_subscription_id": "123456789",
"code": "dedicated_instance",
"timestamp": 1728558000,
"precise_total_amount_cents": "55", //event total amount
"properties": {
"unit": "5"
}
},
{
"transaction_id": "transaction_3",
"external_subscription_id": "123456789",
"code": "dedicated_instance",
"timestamp": 1728561600,
"precise_total_amount_cents": "220", //event total amount
"properties": {
"unit": "10"
}
}
]
}'
```
At the end of the period, the invoice will generate **one fee of \$3.435** (see example below).
| Item | Unit | Unit price | Amount |
| ------------------ | ---- | ---------- | ------ |
| Dedicated Instance | 22 | \$0,156818 | \$3.45 |
To display more detailed information on fees, please refer to the [custom invoice grouping](/guide/invoicing/overview#custom-invoice-grouping) or the [pay in advance](/guide/plans/charges/arrears-vs-advance#charges-paid-in-advance) option.
Only the `standard` & `dynamic` charge models support the [custom invoice grouping](/guide/invoicing/overview#custom-invoice-grouping).
# Graduated
Source: https://getlago.com/docs/guide/plans/charges/charge-models/graduated
Select the graduated charge model if you want to define **several price tiers**.
This charge model allows you to apply a discount depending on the number of
units consumed. You can also apply a **flat fee** to an entire tier.
Let's take back the example of the API company. You could charge \$1 per unit for
the first 100 units (first 100 API calls), then \$0.50 per unit for the next 100
calls and finally, \$0.10 for any additional unit.
Please refer to the tooltip in the user interface for more information.
# Graduated percentage
Source: https://getlago.com/docs/guide/plans/charges/charge-models/graduated-percentage
Select the graduated percentage model if you want to define several percentage tiers. You can also
apply a **flat fee** per tier in addition to the rate.
Note that the **rate** is the only mandatory value. It's particularly useful for fintech charging graduated rates for a feature.
Consider the following example, where each unit represents an API call:
| Tier | First unit | Last unit | Rate | Flat fee |
| ------ | ---------- | --------- | ---- | -------- |
| Tier 1 | 0 | 1,000 | 1% | \$200 |
| Tier 2 | 1,001 | 10,000 | 2% | \$300 |
| Tier 3 | 10,001 | ∞ | 3% | \$400 |
A first transaction at \$500 would cost (500 units x 1%) + \$200 flat fee = \$205.00;
A second transaction at \$550 would cost \[(500 units x 1%) + (50 units x 2%)] + \$300 flat fee = \$306.00;
A third transaction at \$4,000 would cost (4,000 x 2%) = \$80.00.
Unlike the fixed fee, **the flat fee is applied to the entire tier**, rather than per transaction.
# Package
Source: https://getlago.com/docs/guide/plans/charges/charge-models/package
Select the package charge model if you want to apply a **fixed price to a range
of units**. You also have the ability to offer free units.
Let's take back the example of our API company. You may want to charge \$5 per
100 units and offer the first 100 units. In this example, 201 units would cost
\$0 (first 100 units) + \$5 (next 100 units) + \$5 (last unit) = \$10.
# Percentage
Source: https://getlago.com/docs/guide/plans/charges/charge-models/percentage
Select the percentage charge model if you want to apply a **percentage and a
fixed fee on transactions** (e.g. bank transfers, ATM withdrawals, etc.).
This charge model is generally used with billable metrics that allow users to
calculate the total amount of transactions (e.g. `sum` aggregation type and
`amount` defined as the event property -
[learn more](/guide/billable-metrics/aggregation-types)).
You can define several parameters for the percentage charge model, including:
* **Percentage rate**: charge rate that applies to the total amount (e.g. 1.2%
on transactions);
* **Fixed fee (optional)**: fee that applies to each event ingested during the
billing period (e.g. \$0.10 per transaction);
* **Free units (per event - optional)**: number of events that are not subject to
the fixed fee;
* **Free units (total amount - optional)**: amount that is not subject to the
charge rate;
* **Per-transaction spending minimum (per event - optional)**: sets the minimum amount of spending required for each individual transaction; and
* **Per-transaction spending maximum (per event - optional)**: sets the maximum amount of spending required for each individual transaction.
When free units are defined for both the total amount and number of events, Lago
performs checks each time a new event is ingested to determine whether the free
units still apply. In the illustration below for instance, the first 3 events or
\$500 are free.
**Premium feature ✨**: only users with a premium license can define a per-transaction spending minimum and maximum for the percentage pricing model.
Please **[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago Self-Hosted Premium.
Consider the following list of events:
| Event | Amount | Total number of events | Total amount | Result |
| ------------- | ------ | ------------------------------ | ------------------ | ---------- |
| Transaction 1 | \$200 | 1 free event (out of 3) | \$200 (\$500 free) | No charges |
| Transaction 2 | \$100 | 2 free events (out of 3) | \$300 (\$500 free) | No charges |
| Transaction 3 | \$100 | 3 free events (out of 3) | \$400 (\$500 free) | No charges |
| Transaction 4 | \$50 | 4 events (free units exceeded) | \$450 (\$500 free) | Charge |
Therefore, for the fourth transaction, the charge will be \$0.10 x 1 event + 1.2%
of \$50 = \$0.70.
# Standard
Source: https://getlago.com/docs/guide/plans/charges/charge-models/standard
Select the standard charge model if you want to charge the **same price for each
unit** consumed.
Imagine that your API company charges \$0.05 per API call (i.e. your billable
metric). By selecting the standard charge model, you will define a fixed unit
price. If a customer makes 1,000 API calls during the billing period, the total
invoice amount will be \$0.05 x 1,000 API calls = \$50.
Only the `standard` & `dynamic` charge models support the [custom invoice grouping](/guide/invoicing/overview#custom-invoice-grouping).
# Volume
Source: https://getlago.com/docs/guide/plans/charges/charge-models/volume
Select the volume charge model if you want to define several price tiers but
want to apply a **single unit price based on the total volume**. You can also
apply a **flat fee** in addition to the unit price.
Consider the following example, where each unit represents an API call:
| Tier | First unit | Last unit | Unit price | Fixed fee |
| ------ | ---------- | --------- | ---------- | --------- |
| Tier 1 | 0 | 10,000 | \$0.0010 | \$10 |
| Tier 2 | 10,001 | 50,000 | \$0.0008 | \$10 |
| Tier 3 | 50,001 | 100,000 | \$0.0006 | \$10 |
| Tier 4 | 100,001 | ∞ | \$0.0004 | \$10 |
In this case, 65,000 API calls would cost 65,000 x \$0.0006 + \$10 = \$49.
# Charges with filters
Source: https://getlago.com/docs/guide/plans/charges/charges-with-filters
Charge your customers by leveraging a combination of filters specified in the billable metric.
## Define a price for a combination of filters[](#define-price-for-filters "Direct link to heading")
When a billable metric has defined filters, establish a set of filters to refine an event and assign a price to this combination.
1. Add a charge to a plan (this charge should be associated with a billable metric containing filters);
2. Add a new filter;
3. Choose a combination of filters, either specifying a key and its value or simply the key itself (covering all values);
4. Set a price for this combination of filters; and
5. Optionally, provide an Invoice display name.
Here is an example of a plan you can create:
```bash Charge with filters {22-43} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Standard plan",
"code": "standard_plan",
"interval": "monthly",
"pay_in_advance": false,
"amount_cents": 1000,
"amount_currency": "USD",
"charges": [
{
"billable_metric_id": "5d387072-e1f2-416f-b981-135c2f177069",
"invoice_display_name": null,
"charge_model": "standard",
"properties": {
"amount": "2"
},
"filters": [
{
"values": {
"region": ["africa"],
"provider": ["aws"]
},
"invoice_display_name": "Africa & AWS",
"properties": {
"amount": "1"
}
},
{
"values": {
"region": ["__ALL_FILTER_VALUES__"],
"provider": ["__ALL_FILTER_VALUES__"]
},
"invoice_display_name": "Other regions and providers",
"properties": {
"amount": "0.5"
}
}
]
}
]
}'
```
## Define a default price[](#define-default-price "Direct link to heading")
When a billable metric has filters defined, set a default price on the charge level to cover all the other combination of filters not defined in the charge.
1. Add a charge to a plan (this charge should be associated with a billable metric containing filters);
2. Add a default price;
3. Set a price for this default price
Here is an example of a plan you can create:
```bash Storage theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "Standard plan",
"code": "standard_plan",
"interval": "monthly",
"pay_in_advance": false,
"amount_cents": 1000,
"amount_currency": "USD",
"charges": [
{
"billable_metric_id": "5d387072-e1f2-416f-b981-135c2f177069",
"invoice_display_name": null,
"charge_model": "standard",
"properties": {
"amount": "2"
}
}
]
}'
```
If the default price is not set, Lago will automatically define it as 0 based on the charge model.
## Editing filter pricing mid-period[](#editing-filter-pricing-mid-period "Direct link to heading")
When you update a charge's filter configuration or pricing, for example by adding new filter
combinations, changing per-filter rates, or removing the default price, Lago applies the
updated pricing rules to **all usage in the current open billing period**. Fees are not
locked at event ingestion time. They are evaluated against the active charge configuration
at the time of calculation.
This means that events received earlier in the period are repriced under the new
configuration, not the one that was active when they were ingested.
Once an invoice is finalized, amounts are permanently locked. Charge configuration
changes only affect the current open billing period. To preserve existing pricing
on already-received usage, finalize the invoice before updating the charge.
# Fixed charge
Source: https://getlago.com/docs/guide/plans/charges/fixed-charges
Fixed charges are recurring fees tied to add-ons. They are billed independently of usage events and applied as a fixed amount on invoices.
## Overview of charges[](#overview-of-charges "Direct link to heading")
Fixed charges let you bill recurring fees that are not based on usage.
They are tied to [add-ons](/guide/one-off-invoices/create-add-ons) and sit outside the event stream.
Common examples include platform fees, seat licenses, or support packages.
Unlike usage-based charges, fixed charges are billed as a fixed recurring amount.
The units defined on the fixed charge are used by Lago to generate the fee on the invoice.
## Charge models and billing behavior[](#charge-models "Direct link to heading")
Fixed charges support a limited set of pricing options compared to [usage-based charges](/guide/plans/charges/usage-based-charges).
They can use:
* [Standard](/guide/plans/charges/charge-models/standard) or [graduated](/guide/plans/charges/charge-models/graduated) pricing models
They can be configured to:
* Be billed [in advance or in arrears](/guide/plans/charges/arrears-vs-advance)
* Be billed [in full or prorated](/guide/plans/charges/prorated-vs-full)
## Currency[](#charges-currency "Direct link to heading")
All fixed charges use the same currency as the plan, ensuring consistency across invoices.
## Trial period[](#trial-period-exclusion "Direct link to heading")
Trial periods apply only to the plan’s base amount.
Fixed charges are always billed, even during a trial.
## Decimals precision[](#number-of-decimals "Direct link to heading")
Fixed charges can be defined with up to 15 decimal places (for example: \$0.000123456789123).
Fixed charges are invoiced in `amount_cents`, so Lago automatically rounds values when generating invoices (for example, USD 1102 `amount_cents` = \$11.02).
## Edit a fixed charge[](#edit-fixed-charge "Direct link to heading")
When editing a fixed charge, you can edit the amount and the unit already defined. You can choose when unit changes should apply:
* **Apply now**: The new unit value is applied immediately. If the fixed charge is billed in advance, this may trigger invoice issuance.
* **Apply at next billing period**: The new unit value is applied at the start of the subscription’s next billing period.
This gives you control over whether changes impact current or future billing.
Editing a fixed charge unit may generate invoices when the charge is billed in advance and changes are applied immediately.\
Customers will receive an invoice reflecting this update.
## Delete a fixed charge[](#delete-fixed-charge "Direct link to heading")
You can delete a fixed-charge even if the plan is associated to active [subscriptions](/guide/subscriptions/assign-plan).
Once deleted and saved:
* The fixed-charge is immediately removed from all linked subscriptions
* It is removed from all `draft` invoices.
However, the fixed-charge will still appear on invoices `finalized` before the deletion.
## Invoice display name[](#invoice-display-names "Direct link to heading")
You can customize, during plan creation or edition, how a fixed-charge appears on invoices by setting an `invoice display name`.
This name overrides the default fixed-charge name and is shown everywhere invoices are displayed.
# Group keys
Source: https://getlago.com/docs/guide/plans/charges/grouping
## Pricing group keys
AI and infrastructure platforms often tailor pricing based on variables such as geography, hosting provider, or service tier. Lago's Pricing Group Keys offer a streamlined way to support this kind of dynamic pricing without duplicating product definitions.
With pricing group keys, you can group usage events to a single product based on configurable dimensions—like cloud provider, model type, deployment region, or instance class. This allows you to reflect real-world cost variations while keeping your product catalog clean and manageable.
When setting up a charge, you define the relevant keys. You don't need to predefine every possible value. Instead, Lago intelligently routes each usage event to the correct pricing group based on the attributes provided at runtime.
### Define pricing group keys
To define a pricing group key, you need to:
1. Go to the plan where you want to configure dynamic pricing;
2. Select the charge you want to apply the pricing group key to;
3. In the charge settings, enter a key in the Pricing Group Key field (e.g., region, cloud, instance\_type);
4. Send usage events that include this key in the properties object, using any value without predefining them; and
5. Lago will automatically group usage into the correct pricing bucket based on the key's value.
Pricing group keys are available for all charge models. You can define multiple pricing group keys for a single charge.
### Example of pricing group keys
Let's define a pricing group key called `regions` for a charge used to calculate Storage costs for your customers.
By sending usage events with a `regions` property, you can include any number of region values. Lago will automatically group and aggregate usage based on the values provided in your events.
```json theme={"dark"}
{
"event": {
"transaction_id": "{{$randomUUID}}",
"external_subscription_id": "8546dce0-d9e6-4544-ac8a-fbc77340cd9f",
"code": "storage",
"properties": {
"gb": 20,
"regions": "us-east-1"
}
}
}
```
# Invoiceable vs Uninvoiceable
Source: https://getlago.com/docs/guide/plans/charges/invoiceable-vs-noninvoiceable
In-advance charges can be either invoiceable or not.
**Premium feature ✨**: only users with a premium license can define whether
or not a charge is invoiceable. Please **[contact
us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
If a charge needs to be `paid in advance`, you can choose whether or not it generates an invoice.
The `"invoiceable": false` option is **particularly relevant for fintech companies that want to charge customers instantly
without issuing an invoice**. This feature can be useful for banking transactions like ATM withdrawals, FX transfers and other
similar scenarios.
By setting the invoiceable parameter to false, a fee is created by default, and a webhook `fee.created` is sent immediately upon any changes in usage without generating an invoice. However, you can configure the charge invoicing strategy via `regroup_paid_fees`:
1. `null`: Fees generated never appear on invoices (default behaviour).
2. `invoice`: Groups all paid fees into one invoice at the end of the billing period.
Please note that if `invoice`, all fees generated with a `payment_status` different from `succeeded` won’t appear on invoice generated at the end of the billing period. They will appear on next ones if you manually edit their `payment_status` to `succeeded`.
The invoice generated consolidates paid fees, is marked as paid, and will not be emailed to your end customer if the email feature is activated.
1. Go to a **Plan**;
2. Add a usage-based **charge**;
3. Define a price model;
4. Define this charge as **paid in advance**; and
5. Select the option that best suits your needs from the three available choices.
Use the `invoiceable : false` for a charge paid in advance:
```bash Define a charge as invoiceable or not {23} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Premium",
"code": "premium",
"interval": "monthly",
"description": "Premium plan for SMB companies",
"amount_cents": 50000,
"amount_currency": "USD",
"trial_period": 0.0,
"pay_in_advance": true,
"bill_charges_monthly": true,
"charges": [
{
"billable_metric_id": "1111_2222_3333_4444",
"charge_model": "percentage",
"pay_in_advance": true,
"invoiceable": false,
"regroup_paid_fees" : "invoice"
"min_amount_cents": 100,
"properties": {
"rate": "0.5",
"fixed_amount": "1",
"free_units_per_events": 3,
"free_units_per_total_aggregation": null
}
}
]
}
}'
```
# Metered vs Recurring
Source: https://getlago.com/docs/guide/plans/charges/metered-vs-recurring
Usage-based charges can be either metered or recurring
You have the flexibility to define the nature of charges associated with your products or services. Specifically, you can
**determine whether a charge is metered or recurring**. Understanding the distinction between these two types of charges is crucial for
effectively managing your billing processes. In this documentation, we will delve into the differences between metered and
recurring charges and their implications within the Lago system.
## Metered charges[](#metered "Direct link to heading")
When you create a metered billable metric in Lago by setting the `recurring` parameter to `false`, an important behavior comes into play.
At the end of each billing period, the accumulated number of units associated with the metric is automatically reset to 0.
This means that the counting or measuring of units starts fresh with each new billing cycle. This is ideal for billing components with results
that are not persistent across billing periods.
In the API tab beside, consider the example of a **Storage billing unit**. If you need to **track the Gigabytes stored during a month**,
it's important to note that this value should be reset to 0 at the beginning of each new month.
Create a billable metric with `recurring` set to `false`.
```bash Metered billable metric {13} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Storage",
"code": "storage",
"description": "GB of storage used in my application",
"aggregation_type": "sum_agg",
"recurring": false,
"field_name": "gb",
"group": {
"key": "region",
"value": ["us-east-1", "us-east-2", "eu-west-1"]
}
}
}'
```
## Recurring charges[](#recurring "Direct link to heading")
When you create a recurring billable metric in Lago with the recurring parameter set to true, an important behavior comes
into effect. At the end of each billing period, the accumulated number of units calculated from the previous billing period is
carried forward to the next billing period.
This means that the counting or measurement of units starts based on the last recorded value from the previous billing cycle.
This behavior is particularly useful for billing components or services where the results need to persist from one billing period
to another.
In the API tab, let's consider the example of a **Seats billing unit**. If you need to **track the number of active seats**, it's crucial to
note that this value should persist month over month. The recurring billing behavior ensures that the count of active seats is
maintained and carried forward to subsequent billing periods, providing accurate and continuous tracking of your subscription seats.
Create a billable metric with `recurring` set to `true`.
```bash Recurring billable metric {13} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Seats",
"code": "seats",
"description": "Active seats.",
"aggregation_type": "count_unique",
"recurring": true,
"field_name": "seat_id",
"group": {
"key": "type",
"value": ["admin", "viewer", "editor"]
}
}
}'
```
# Prorated vs Full
Source: https://getlago.com/docs/guide/plans/charges/prorated-vs-full
Usage-based charges can be either billed fully or prorated based on the number of days used.
You can **determine whether a charge is prorated or fully-billed**. Understanding the distinction between these two types of charges is crucial for effectively managing your billing processes. In this documentation, we will delve into the differences between prorated and fully-billed charges and their implications within the Lago system.
## Prorated charges
Only charges that are [recurring](#2-recurring-charges) (billable metric with `recurring` argument set to `true`), invoiced [in arrears](https://docs.getlago.com/guide/plans/charges/arrears-vs-advance), with a `charge_model` defined to `standard`, `graduated` or `volume` can be prorated. If your charge is pay-in-advance, it can only be prorated if the `charge_model` is `standard`.
When creating a prorated charge in Lago with the `prorated` parameter set to `true`, an important behavior is triggered. Adding a new unit during the billing period results in the amount due for that unit being prorated based on the number of days it was used.
This means that your customers will only be charged for the actual number of days they utilized a billing unit. Let's **consider the example of prorated** `Seats`, where each seat costs \$10. If a new seat is added on July 10th, the unit will be prorated for 22 days, resulting in a corresponding prorated charge for that duration. This ensures fair and accurate billing based on the usage period.
*Example: (1 Seat x \$10), used for 22 days = \$7.33*
By leveraging prorated charges in Lago, you can provide transparent and cost-effective billing for services that are added or removed mid-billing cycle, adjusting the charges according to the actual duration of usage.
Create a charge that is prorated by setting `prorated` to `true`.
Only charges that are [recurring](#2-recurring-charges) (billable metric with `recurring` argument set to `true`), invoiced [in arrears](https://docs.getlago.com/guide/plans/charges/arrears-vs-advance), with a `charge_model` defined to `standard`, `graduated` or `volume` can be prorated. If your charge is pay-in-advance, it can only be prorated if the `charge_model` is `standard`.
```bash Prorated charges {25} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Startup",
"code": "startup",
"interval": "monthly",
"description": "This is a basic plan description",
"amount_cents": 10000,
"amount_currency": "USD",
"trial_period": 3.0,
"pay_in_advance": true,
"bill_charges_monthly": false,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "standard",
"pay_in_advance": true,
"invoiceable": true,
"min_amount_cents": 0,
"prorated": true,
"group_properties": [
{
"group_id": "__GROUP_ID__",
"values": {
"amount": "10"
}
}
]
}
]
}
}'
```
## Fully-billed charges
Note that metered charges (billable metrics with `recurring` set to `false`) are automatically fully-billed.
When creating a fully-billed charge in Lago with the `prorated` parameter set to `false`, an important behavior occurs. If a new unit is added during the billing period, the amount due for that unit is billed in full, regardless of the number of days it was used.
This means that your customers will be charged for the entire billing period, even if they only utilized the billing unit for a few days. \*\*Let's consider the example of fully-billed \*\*`Seats`, where each seat costs \$10. If a new seat is added on July 10th, it will be billed for the full billing period. For instance, if there is one seat that was used for 22 days in the billing period, the charge would be calculated as follows:
*(1 Seat x \$10), used for 22 days = \$10.*
By utilizing fully-billed charges in Lago, you ensure that you do not lose revenue by billing customers for the entire billing period, regardless of the actual duration of usage.
Create a charge that is billed fully by setting `prorated` to `false`.
Note that metered charges (billable metrics with `recurring` set to `false`) are automatically fully-billed.
```bash Fully-billed charges theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Startup",
"code": "startup",
"interval": "monthly",
"description": "This is a basic plan description",
"amount_cents": 10000,
"amount_currency": "USD",
"trial_period": 3.0,
"pay_in_advance": true,
"bill_charges_monthly": false,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "standard",
"pay_in_advance": true,
"invoiceable": true,
"min_amount_cents": 0,
"prorated": false,
"group_properties": [
{
"group_id": "__GROUP_ID__",
"values": {
"amount": "10"
}
}
]
}
]
}
}'
```
# Spending minimums
Source: https://getlago.com/docs/guide/plans/charges/spending-minimum
**Premium feature ✨**: only users with a premium license can define a charge spending minimum.
Please **[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago Self-Hosted Premium.
Spending minimum concerns only usage-based charges which billing time is in arrears since these are always paid at the end of the billing period based on the amount of consumption that occurred. This feature allows you to define a spending minimum that a customer needs to commit to.
If your customer spends less than the committed amount, you will **charge a true-up fee equal to the difference between the commitment
and the actual usage**. Please note that this true-up fee is tied to the initial charge but will appear as a separate line item in an
invoice or in a credit note.
**Spending minimums and true-up fees are always prorated based on the number of days used in the subscription**. This ensures
fairness if your customer signs up at the end of the month, upgrades to a new plan, or terminates an ongoing subscription
before the end of the period.
In the example below, a customer is billed based on Monthly Tracked Users (MTU), with a standard pricing of \$0.010 per tracked user.
However, the customer is committed to a spending minimum of \$100. If the total consumption of MTUs for the period is \$50, a true-up fee
of \$50 will be charged.
To define a charge spending minimum:
1. Go to a **Plan**;
2. Add a usage-based **charge**;
3. Define a price model;
4. Click the add a **spending minimum** button; and
5. Define a spending minimum **amount**.
Use the `min_amount_cents` field on a charge:
```bash Spending minimum for a charge {24} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Premium",
"code": "premium",
"interval": "monthly",
"description": "Premium plan for SMB companies",
"amount_cents": 50000,
"amount_currency": "USD",
"trial_period": 0.0,
"pay_in_advance": true,
"bill_charges_monthly": true,
"charges": [
{
"billable_metric_id": "1111_2222_3333_4444",
"charge_model": "percentage",
"pay_in_advance": false,
"invoiceable": true,
"min_amount_cents": 100,
"properties": {
"rate": "0.5",
"fixed_amount": "1",
"free_units_per_events": 3,
"free_units_per_total_aggregation": null
}
}
]
}
}'
```
# Usage based charge
Source: https://getlago.com/docs/guide/plans/charges/usage-based-charges
Usage-based charges let you bill customers based on actual consumption. They are tied to billable metrics and calculated from usage events collected during the billing period.
## Overview of charges[](#overview-of-charges "Direct link to heading")
Usage-based charges allow you to add pay-as-you-go pricing to a plan.
Each charge is linked to an existing [billable metric](/guide/billable-metrics/create-billable-metrics) and calculated from the events collected during the billing period.
Common examples include API calls, active users, transactions, or compute time.
Pricing follows the charge configuration (tiers, aggregation, proration, etc.), ensuring invoices reflect real usage rather than a fixed amount.
## Charge models and billing behavior[](#charge-models "Direct link to heading")
Charges support a set of pricing options compared to the fixed charges.
They can use:
* [All charge models](/guide/plans/charges/charge-models).
They can be configured to:
* Be billed [in advance or in arrears](/guide/plans/charges/arrears-vs-advance);
* Be billed [in full or prorated](/guide/plans/charges/prorated-vs-full);
* Apply [spending minimums](/guide/plans/charges/spending-minimum) depending on the charge model;
* Support [filters](/guide/plans/charges/charges-with-filters) to control which events are included in usage calculations;
* Be grouped by [presentation keys](/guide/plans/charges/grouping) to display related usage together on invoices;
* Be marked as [invoiceable or not](/guide/plans/charges/invoiceable-vs-noninvoiceable) when billed in advance, to avoid generating too many invoices from usage events.
## Currency[](#charges-currency "Direct link to heading")
All usage-based charges use the same currency as the plan, ensuring consistency across invoices.
## Trial period[](#trial-period-exclusion "Direct link to heading")
The trial period applies only to the plan’s base amount and does not cover usage-based charges.
Usage events recorded during the trial are always considered and billed.
## Decimals precision[](#number-of-decimals "Direct link to heading")
Charges can be defined with up to 15 decimal places (for example: \$0.000123456789123).
Charges are invoiced in `amount_cents`, so Lago automatically rounds values when generating invoices (for example, USD 1102 `amount_cents` = \$11.02).
## Delete a charge[](#delete-charge "Direct link to heading")
You can delete a charge even if the plan is associated to active [subscriptions](/guide/subscriptions/assign-plan).
Once deleted and saved:
* The charge is immediately removed from all linked subscriptions
* It no longer appears in customer [current usage](/api-reference/customer-usage/customer-usage-object); and
* It is removed from all `draft` invoices.
However, the charge will still appear on invoices `finalized` before the deletion.
Deleting a charge does not delete the underlying events.\
If the charge is later re-added, previously collected events may be included in billing, depending on the billing period limits.
## Invoice display name[](#invoice-display-names "Direct link to heading")
You can customize, during plan creation or edition, how a charge appears on invoices by setting an `invoice display name`.
This name overrides the default charge name and is shown everywhere invoices are displayed.
# Commitments
Source: https://getlago.com/docs/guide/plans/commitment
**Premium feature ✨**:
This feature is only available to users with a premium license. Please **[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago Self-Hosted Premium.
In your plan configuration, Lago provides the flexibility to define specific spending commitments tailored to your business needs.
These commitments serve as a financial baseline for the services you offer. However, understanding the unique requirements of each customer,
Lago offers the capability to customize these commitments on a per-customer basis at the time of creating a subscription.
## Minimum commitment
### Guidelines
Besides setting [spending minimums per charge](/guide/plans/charges/spending-minimum), Lago also allows you to define minimum invoice totals.
This ensures customers meet a minimum spend per billing period, securing a steady revenue flow and aiding in accurate financial forecasting.
The minimum commitment per invoice set in Lago applies to the total spending in the billing period including -if applicable- the subscription fee and all usage-based fees.
* **Commitment interval:** The minimum commitment is aligned with the billing interval of the plan. For instance, if the plan is billed monthly, the minimum commitment is also established on a monthly basis;
* **Customizable commitments:** When assigning a plan to a customer, you have the option to override the default commitment. This allows for customized minimum commitments per customer, accommodating negotiated contract terms; and
* **Arrears calculation:** The commitment is calculated in arrears, meaning Lago waits until the end of the billing period to assess whether users have met their minimum spending commitment. This approach ensures accurate billing based on actual usage.
### True-up fee
If the total spending falls below the minimum commitment at the end of the billing period, Lago will **apply a true-up fee to adjust the invoice and meet the minimum spending requirement**.
Conversely, if spending exceeds the minimum commitment, Lago will generate an invoice for the actual consumption, without issuing a true-up fee.
The minimum commitment is calculated based on the pre-tax amount and before any discounts (such as coupons or credits) are applied.
### Defining a minimum commitment
To create or update a minimum commitment from the user interface:
1. Access an existing or a new plan **"Plan"**;
2. Navigate below usage based charges;
3. Define a **minimum commitment**; and
4. Click **"Add plan"** to confirm.
The minimum commitment must follow the plan's interval. You can add a specific tax rate for this minimum commitment.
```json Define a minimum commitment {16-22} theme={"dark"}
{
"plan": {
"name": "Basic",
"invoice_display_name": null,
"created_at": "2024-02-23T16:01:04Z",
"code": "basic",
"interval": "monthly",
"description": "",
"amount_cents": 10000,
"pay_in_advance": true,
"bill_charges_monthly": null,
"customers_count": 2,
"active_subscriptions_count": 2,
"draft_invoices_count": 0,
"parent_id": null,
"minimum_commitment": {
"plan_code": "basic",
"invoice_display_name": "Minimum Contract Commitment",
"amount_cents": 50000,
"interval": "monthly",
"taxes": []
},
"charges": [
{
"id": "ca205886-cf09-4e42-aed6-34cb2afd0c29",
"billable_metric_id": "5b320600-715b-4ef5-88c1-4f88c0ec5c50",
"invoice_display_name": "",
"billable_metric_code": "storage",
"created_at": "2024-02-23T16:01:04Z",
"charge_model": "standard",
"invoiceable": true,
"pay_in_advance": false,
"prorated": false,
"properties": {
"amount": "1"
},
"group_properties": [],
"taxes": []
},
{
"id": "1d5c78c6-0e22-424f-af8d-6784f6ff44ec",
"billable_metric_id": "4cbc5940-32fb-48a8-aa39-ad664b34a062",
"invoice_display_name": null,
"billable_metric_code": "seats",
"created_at": "2024-02-23T16:04:09Z",
"charge_model": "standard",
"invoiceable": true,
"pay_in_advance": true,
"prorated": false,
"min_amount_cents": 0,
"properties": {
"amount": "7"
},
"group_properties": [],
"taxes": []
}
],
"taxes": []
}
}
```
### Overwriting a minimum commitment
To overwrite the minimum commitment for a specific customer, follow these instructions:
1. Access a specific customer;
2. Choose to assign a new plan or edit an existing subscription; and
3. Override the default plan's minimum commitment with a new value.
```json Define a minimum commitment theme={"dark"}
{
"subscription": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"plan_code": "premium",
"name": "Repository A",
"external_id": "my_sub_1234567890",
"billing_time": "anniversary",
"subscription_at": "2022-08-08T00:00:00Z",
"plan_overrides": {
"amount_cents": 10000,
"amount_currency": "USD",
"description": "Plan for early stage startups.",
"invoice_display_name": "Startup plan",
"name": "Startup",
"tax_codes": [],
"minimum_commitment": {
"plan_code": "basic",
"invoice_display_name": "Minimum Contract Commitment",
"amount_cents": 50000,
"interval": "monthly",
"taxes": []
}
"charges": []
}
}
}
```
# Custom pricing units
Source: https://getlago.com/docs/guide/plans/custom-pricing-units
A pricing unit works like a custom currency, allowing you to express charges in something other than fiat (e.g., credits or tokens).
**Premium feature ✨**:
Only users with a premium license can activate and use pricing units. Please [**contact us**](mailto:hello@getlago.com) to get access to Lago Cloud and Lago Self-Hosted Premium.
## Create a pricing unit
You can create as many pricing units as needed. Please note that once created, a pricing unit can’t be deleted unless you contact us.
To create a new pricing unit:
1. Go to **Settings**
2. In the **Your organization** section, open the **Invoices** tab
3. Click **Create** next to the **Pricing units** section
4. Define a **name**, **code**, **short name**, and optionally, an internal description
The **short name** acts like a currency symbol on invoices. It’s limited to 3 characters (e.g., `tks` for tokens or `cdt` for credits).
## Associate charges with a pricing unit
Once pricing units are created, you can use them when defining a plan. For now, only charges support pricing units.
1. Open an existing plan or create a new one
2. Add a new charge, existing charges can't be updated
3. In the charge details, pricing unit is set by default in the plan’s currency
4. Switch to a pricing unit by selecting one from the dropdown
5. Set a **conversion rate** to ensure proper invoicing
6. Define your **charge model** based on the selected pricing unit
7. Optionally, set a **spending minimum** in the same pricing unit
```json Associate a pricing unit to a charge {18-21} theme={"dark"}
{
"plan": {
"name": "Standard",
"invoice_display_name": "Standard",
"code": "standard",
"interval": "monthly",
"amount_cents": "0",
"amount_currency": "USD",
"pay_in_advance": "false",
"charges": [
{
"billable_metric_id": "3a038c85-40fa-4ee3-9b22-18b3b6b95654",
"charge_model": "standard",
"pay_in_advance": "false",
"invoiceable": "true",
"prorated": "false",
"min_amount_cents": "3000",
"applied_pricing_unit": {
"code": "credits",
"conversion_rate": "0.50005"
},
"properties": {
"amount": "10"
}
}
]
}
}
```
## Current & past usage
Charges defined in pricing units will be calculated and displayed in two ways: in fiat currency (using the conversion rate set at the charge level) and in the pricing unit itself.
You’ll find this information in the current and past usage data, where amounts are also shown in pricing units.
```json Current & past usage {5-9} theme={"dark"}
{
"customer_usage": {
"charge_usage": [
{
"pricing_unit_details": {
"amount_cents": 10,
"short_name": "CR",
"conversion_rate": "0.50005"
}
}
]
}
}
```
## Invoicing behaviour
Even if prices are expressed in pricing units, invoices will always reflect the equivalent fiat currency amount. The invoicing experience mirrors what’s shown in the current and past usage: amounts are displayed in both fiat and the associated pricing unit.
```json Invoicing behaviour {3-12} theme={"dark"}
{
"fee": {
"pricing_unit_details": {
"lago_pricing_unit_id": "9fb3ad78-9fb3-4f4e-9e27-304c16db6abb",
"pricing_unit_code": "credits",
"short_name": "CR",
"amount_cents": 100000,
"precise_amount_cents": "100000.0",
"unit_amount_cents": 100,
"precise_unit_amount": "1.0",
"conversion_rate": "0.50005"
}
}
}
```
## Wallet and transactions
Pricing units don’t affect wallet behavior. You can use wallets independently or alongside pricing units, depending on your use case.
# Overview
Source: https://getlago.com/docs/guide/plans/overview
If Billable metrics are made to measure customer usage, Plans are made to apply prices to this usage.
## Plan overview[](#plan-overview "Direct link to heading")
A plan defines how your products are priced and billed.
It groups pricing, billing cadence, feature access, commitments, and invoicing rules. Plans often reflect your pricing page, but can also model custom or enterprise agreements.
To bill a customer, a plan must be assigned to a subscription.
## Plan structure[](#plan-structure "Direct link to heading")
A plan defines:
* The features customers can access
* The prices they pay
* How and when they are invoiced
To invoice a customer with Lago, a plan must be assigned to a subscription.
A plan is composed of the following elements:
1. [Basic information](#plan-structure)
* Plan `name`
* Plan `code`
* Plan `description`
* Taxes applied at the plan level
2. [Plan model](/guide/plans/plan-model)
* Billing `interval` (monthly, yearly, etc.)
* Base amount and currency (subscription fee)
* Whether the subscription fee is billed `in advance` or `in arrears`
* Trial period (in days), applied to the subscription fees
3. [Fixed charges (add-ons)](/guide/plans/charges/fixed-charges)
* Charge `model`
* Pricing `properties` defined by the charge model
* Whether the fixed charge is billed `in advance` or `in arrears`
* Taxes applied to the fixed charge (overriding plan-level taxes if needed)
4. [Usage-based charges (billable metrics)](/guide/plans/charges/usage-based-charges)
* Charge `model`
* Pricing `properties` defined by the charge model
* Optional spending minimum
* Whether usage charge is billed `in advance` or `in arrears`
* Taxes applied to the charge (overriding plan-level taxes if needed)
5. [Minimum commitment](/guide/plans/commitment)
* A minimum amount applied across all invoices generated by the plan within a billing period.
6. [Entitlements](/guide/entitlements)
* Feature access and additional metadata attached to the plan.
7. [Progressive billing](/guide/plans/progressive-billing)
* Automatically triggers invoices when cumulative usage reaches predefined thresholds.
```bash Premium Plan Example theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"name": "Startup",
"invoice_display_name": "Startup plan",
"created_at": "2023-06-27T19:43:42Z",
"code": "startup",
"interval": "monthly",
"description": "",
"amount_cents": 10000,
"amount_currency": "USD",
"trial_period": 5,
"pay_in_advance": true,
"bill_charges_monthly": null,
"bill_fixed_charges_monthly": null,
"minimum_commitment": {
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"plan_code": "premium",
"amount_cents": 100000,
"invoice_display_name": "Minimum Commitment (C1)",
"interval": "monthly",
"created_at": "2022-04-29T08:59:51Z",
"updated_at": "2022-04-29T08:59:51Z",
"taxes": [
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"name": "TVA",
"code": "french_standard_vat",
"description": "French standard VAT",
"rate": 20,
"created_at": "2023-07-06T14:35:58Z"
}
]
},
"charges": [
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a91",
"lago_billable_metric_id": "1a901a90-1a90-1a90-1a90-1a901a901a91",
"billable_metric_code": "requests",
"created_at": "2023-06-27T19:43:42Z",
"charge_model": "package",
"invoiceable": true,
"invoice_display_name": "Setup",
"pay_in_advance": false,
"regroup_paid_fees": null,
"prorated": false,
"min_amount_cents": 3000,
"properties": {
"amount": "30",
"free_units": 100,
"package_size": 1000
},
"filters": []
},
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a92",
"lago_billable_metric_id": "1a901a90-1a90-1a90-1a90-1a901a901a92",
"billable_metric_code": "cpu",
"created_at": "2023-06-27T19:43:42Z",
"charge_model": "graduated",
"invoiceable": true,
"invoice_display_name": "Setup",
"pay_in_advance": false,
"regroup_paid_fees": null,
"prorated": false,
"min_amount_cents": 0,
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10,
"flat_amount": "10",
"per_unit_amount": "0.5"
},
{
"from_value": 11,
"to_value": null,
"flat_amount": "0",
"per_unit_amount": "0.4"
}
]
},
"filters": []
},
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a93",
"lago_billable_metric_id": "1a901a90-1a90-1a90-1a90-1a901a901a93",
"billable_metric_code": "seats",
"created_at": "2023-06-27T19:43:42Z",
"charge_model": "standard",
"invoiceable": true,
"invoice_display_name": "Setup",
"pay_in_advance": true,
"regroup_paid_fees": null,
"prorated": false,
"min_amount_cents": 0,
"properties": {},
"filters": [
{
"invoice_display_name": "Europe",
"properties": {
"amount": "10"
},
"values": {
"region": ["Europe"]
}
},
{
"invoice_display_name": "USA",
"properties": {
"amount": "5"
},
"values": {
"region": ["USA"]
}
},
{
"invoice_display_name": "Africa",
"properties": {
"amount": "8"
},
"values": {
"region": ["Africa"]
}
}
]
},
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a94",
"lago_billable_metric_id": "1a901a90-1a90-1a90-1a90-1a901a901a94",
"billable_metric_code": "storage",
"created_at": "2023-06-27T19:43:42Z",
"charge_model": "volume",
"invoiceable": true,
"invoice_display_name": "Setup",
"pay_in_advance": false,
"regroup_paid_fees": null,
"prorated": false,
"min_amount_cents": 0,
"properties": {
"volume_ranges": [
{
"from_value": 0,
"to_value": 100,
"flat_amount": "0",
"per_unit_amount": "0"
},
{
"from_value": 101,
"to_value": null,
"flat_amount": "0",
"per_unit_amount": "0.5"
}
]
},
"filters": []
},
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a95",
"lago_billable_metric_id": "1a901a90-1a90-1a90-1a90-1a901a901a95",
"billable_metric_code": "payments",
"created_at": "2023-06-27T19:43:42Z",
"charge_model": "percentage",
"invoiceable": false,
"invoice_display_name": "Setup",
"pay_in_advance": true,
"regroup_paid_fees": "invoice",
"prorated": false,
"min_amount_cents": 0,
"properties": {
"rate": "1",
"fixed_amount": "0.5",
"free_units_per_events": 5,
"free_units_per_total_aggregation": "500"
},
"filters": []
}
],
"fixed_charges": [
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"lago_add_on_id": "2b802b80-2b80-2b80-2b80-2b802b802b80",
"code": "setup_fee",
"invoice_display_name": "Setup Fee",
"add_on_code": "setup",
"created_at": "2026-01-15T10:30:00Z",
"charge_model": "standard",
"pay_in_advance": true,
"prorated": false,
"properties": {
"amount": "500"
},
"units": 1,
"lago_parent_id": null,
"taxes": [
{
"lago_id": "3c703c70-3c70-3c70-3c70-3c703c703c70",
"name": "VAT",
"code": "vat_20",
"rate": 20,
"description": "Standard VAT rate",
"applied_to_organization": true,
"created_at": "2026-01-01T00:00:00Z"
}
]
},
{
"lago_id": "4d604d60-4d60-4d60-4d60-4d604d604d60",
"lago_add_on_id": "5e505e50-5e50-5e50-5e50-5e505e505e50",
"code": "support_tier",
"invoice_display_name": "Support Tier",
"add_on_code": "premium_support",
"created_at": "2026-01-15T10:30:00Z",
"charge_model": "graduated",
"pay_in_advance": false,
"prorated": true,
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10,
"per_unit_amount": "5",
"flat_amount": "200"
},
{
"from_value": 11,
"to_value": null,
"per_unit_amount": "1",
"flat_amount": "300"
}
]
},
"units": 1,
"lago_parent_id": null,
"taxes": []
},
{
"lago_id": "6f406f40-6f40-6f40-6f40-6f406f406f40",
"lago_add_on_id": "7a307a30-7a30-7a30-7a30-7a307a307a30",
"code": "storage",
"invoice_display_name": "Storage Allocation",
"add_on_code": "cloud_storage",
"created_at": "2026-01-15T10:30:00Z",
"charge_model": "volume",
"pay_in_advance": false,
"prorated": false,
"properties": {
"volume_ranges": [
{
"from_value": 0,
"to_value": 100,
"per_unit_amount": "2",
"flat_amount": "1"
},
{
"from_value": 101,
"to_value": null,
"per_unit_amount": "1",
"flat_amount": "0"
}
]
},
"units": 50,
"lago_parent_id": null,
"taxes": []
}
],
"taxes": [
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"name": "TVA",
"code": "french_standard_vat",
"description": "French standard VAT",
"rate": 20,
"created_at": "2023-07-06T14:35:58Z"
}
],
"usage_thresholds": [
{
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"threshold_display_name": "Threshold 1",
"amount_cents": 10000,
"recurring": true,
"created_at": "2023-06-27T19:43:42Z",
"updated_at": "2023-06-27T19:43:42Z"
}
],
"entitlements": [
{
"entitlement": {
"code": "seats",
"name": "Number of seats",
"description": "Number of users of the account",
"privileges": [
{
"code": "max",
"name": "Maximum",
"value_type": "integer",
"config": {},
"value": 10
},
{
"code": "max_admins",
"name": "Max Admins",
"value_type": "integer",
"config": {},
"value": 5
},
{
"code": "root",
"name": "Allow root user",
"value_type": "boolean",
"config": {},
"value": true
},
{
"code": "provider",
"name": "SSO Provider",
"value_type": "select",
"value": "google",
"config": {
"select_options": ["google", "okta"]
}
}
]
}
}
],
"metadata": {
"external_id": "ext-123",
"synced_at": "2024-01-15",
"source": null
}
}
}'
```
## Editing Plans[](#editing-plans "Direct link to heading")
A plan can be fully edited as long as it is not linked to any active subscription.
Once a plan is assigned to a customer, some changes are still allowed. You can still update prices, add or remove charges, and adjust charge settings.
However, core properties become locked, such as: billing interval, advance vs arrears configuration, proration rules.
Some updates may trigger invoice issuance and will impact all subscriptions using the plan.
If a plan is linked to overridden subscriptions, you can choose whether changes should apply to them.
When updating a plan via the API, use `cascade_updates: true` to propagate updates to overridden subscriptions.
To update plans already linked to customers, you must either:
* Remove all active subscriptions, or
* Create a new plan and migrate subscriptions
To update a specific charge, it must be removed and re-added with the new configuration.
## Deleting Plans[](#deleting-plans "Direct link to heading")
Plans can be deleted even if they are linked to active subscriptions.
In that case, deleting the plan will automatically terminate the associated subscriptions and generate the corresponding invoices.
# Plan model
Source: https://getlago.com/docs/guide/plans/plan-model
The plan model defines when and how much a customer is charged.
## Plan interval[](#plan-interval "Direct link to heading")
The plan interval corresponds to the billing period and defines when invoices
are generated. In most cases, the [charges](/guide/plans/charges) are also calculated
according to the plan interval.
There are several plan intervals:
1. **Weekly**: subscription fees and charges are billed on a weekly basis
(Monday to Sunday);
2. **Monthly**: subscription fees and charges are billed on a monthly basis;
3. **Quarterly**: subscription fees and charges are billed on a quarterly basis (every 3 months);
4. **Semiannual**: subscription fees and charges are billed on a semiannual basis (every 6 months); and
5. **Yearly**: subscription fees are billed on a yearly basis and charges can be
billed monthly or annually.
## The base charge amount and its currency[](#the-base-charge-amount-and-its-currency "Direct link to heading")
You need to define a **base amount** for each plan (i.e. the subscription fee).
This amount is what the customer will pay by subscribing to the plan regardless
of their consumption.
This base charge `amount` is recurring, and billed at the end of each billing
interval.
## Pay in advance or in arrears[](#pay-in-advance-or-in-arrears "Direct link to heading")
With Lago, you can define if the base charge of the Plan is paid **in advance**
or **in arrears**.
* If the toggle is `off` (boolean set to FALSE), the Plan is paid for the past
period (in arrears).
* If the toggle is `on` (boolean set to TRUE), the Plan is paid upfront (in
advance) for the period.
Note that this toggle only affects the base amount of the Plan. Additional
charges for per-usage Billable metrics **are always paid in arrears because
they are linked to a past consumption of your customers.**
## The trial period (optional)[](#the-trial-period-optional "Direct link to heading")
You can decide to apply a `Trial period` for a Plan. This means your customers
can test the Plan without being charged for a certain number of days. This is
optional and if the value is null, the Plan holds 0 day of trial.
Note that the trial period **can only be specified in days**. A pro-rata is
applied to the Plan regarding the number of days offered.
A trial period can only be applied to the first subscribed Plan. In case of an
upgrade or downgrade, the trial period of the new Plan **is not applied**.
The trial period is only applied to the subscription fee.
Any events received during the trial period will be taken into account at the end
of the billing cycle. Pay-in-advance charges will be invoiced and collected immediately
after an event is received.
If you want maximum flexibility, you can define two different Plans: one for the
free trial and one regular plan. A new customer starts on the free plan, and you
can configure the regular plan to start after the trial period. The free plan
subscription will automatically be terminated when the regular plan starts.
## Taxes applied on plans or charges
You have the option to store taxes either at a Plan level or for specific charges.
This choice entails that whenever you apply this plan to a customer without taxes,
invoice fees will inherit the taxes defined in the corresponding plan.
It's important to acknowledge that taxes applied to a plan will influence the charges,
unless the taxes are explicitly defined for the individual charge.
## Pro-ratas based on subscription date[](#pro-ratas-based-on-subscription-date "Direct link to heading")
Obviously, we know that your customers don't necessarily sign up for a Plan at
the very beginning of each month (or each year). This is why Lago automatically
applies a pro-rata for the first and the last subscription period of a Plan.
Here is an example: A `Customer X` signs up for the Plan `Start` (base amount of
10€, with no trial period) on April 15, 2022.
* If the Plan is defined to be `paid in arrears`, this Customer will be charged
5€ for the first month at the end of the period (May 1, 2022).
* If the Plan is defined to be `paid in advance`, this Customer is charged 5€
straight away for the first month (April 15, 2022).
Note that pro-ratas can also be applied in case of **upgrades or downgrades**.
# Progressive billing
Source: https://getlago.com/docs/guide/plans/progressive-billing
Progressive billing, also known as threshold billing, automatically triggers an invoice when a customer's cumulative usage reaches predefined thresholds. This method ensures that customers cannot exceed certain usage limits without ensuring payment is received, reducing the risk of unpaid services or fraud.
**PREMIUM ADD-ON** ✨
This progressive billing feature is available upon request only. Please [**contact us**](mailto:hello@getlago.com) to get access to this premium feature.
## Lifetime usage
In the context of progressive billing, thresholds and invoicing behavior are **determined by the lifetime usage of a subscription**.
This approach means that Lago continuously tracks and aggregates **the total usage across all billing periods**.
By considering this cumulative usage, Lago can accurately assess whether a customer has reached predefined thresholds.
When the lifetime usage reaches a specific threshold, Lago automatically triggers the invoicing process, ensuring that usage is invoiced promptly before it exceeds the specified limits. This mechanism helps prevent overuse of services without a corresponding invoice and payment, offering a safeguard against potential revenue leakage. It's important to note that lifetime usage is persistent across periods, meaning that even if a customer's usage fluctuates, Lago will account for the entire history to determine if and when an invoice should be issued.
The lifetime usage is calculated based on the usage amount before taxes.
## Setting up thresholds
For the progressive billing feature, you can configure two types of thresholds: Step-Based Thresholds and Recurring Thresholds.
### Step-based thresholds
For Step-Based Thresholds, invoices are generated when the lifetime usage of a subscription reaches a defined threshold.
You can set an unlimited number of thresholds, each with a specific amount and a unique name.
To add progressive billing Step-Based Thresholds from the UI:
1. Navigate to the desired plan;
2. Access the Advanced Settings;
3. Locate the Progressive Billing section; and
4. Add your thresholds.
```json Add progressive billing thresholds {14,15,16,17,18,19,20,21,22,23,24,25,26,27} theme={"dark"}
{
"plan": {
"name": "Premium",
"invoice_display_name": null,
"created_at": "2024-08-26T14:23:53Z",
"code": "premium",
"interval": "monthly",
"description": "",
"amount_cents": 10000,
"amount_currency": "USD",
"trial_period": 0.0,
"pay_in_advance": true,
"charges": [...],
"usage_thresholds": [
{
"amount_cents": 500,
"threshold_display_name": "Step 1 "
},
{
"amount_cents": 5000,
"threshold_display_name": "Step 2"
},
{
"amount_cents": 10000,
"threshold_display_name": "Step 3"
}
]
}
}
```
In the above example, Lago will issue an invoice when the specified threshold is met:
* `Invoice #1`: When the lifetime usage reaches \$5;
* `Invoice #2`: When the lifetime usage reaches \$20;
* `Invoice #3`: When the lifetime usage reaches \$50;
* `Invoice #4`: When the lifetime usage reaches \$100;
* `Invoice #5`: When the lifetime usage reaches \$1,000;
* Then, resume to 'end of the month' billing.
### Recurring threshold
In addition to Step-Based Thresholds, you can also set up a Recurring Threshold. This threshold determines what happens after the final step-based threshold is reached.
If a recurring threshold is defined, Lago will continue to issue invoices each time the lifetime usage increases by the specified amount.
For example, as shown in the image below, after the last threshold, Lago will automatically bill \$100 each time the lifetime usage increments by that amount.
To add a recurring threshold from the UI:
1. Navigate to the desired plan;
2. Access the Advanced Settings;
3. Locate the Progressive Billing section;
4. Toggle the 'Recurring' switch; and
5. Enter a name and define the recurring threshold amount.
```json Add a recurring billing threshold theme={"dark"}
{
"plan": {
"name": "Premium",
"invoice_display_name": null,
"created_at": "2024-08-26T14:23:53Z",
"code": "premium",
"interval": "monthly",
"description": "",
"amount_cents": 10000,
"amount_currency": "USD",
"trial_period": 0.0,
"pay_in_advance": true,
"charges": [...],
"usage_thresholds": [
{
"amount_cents": 500,
"threshold_display_name": "Step 1 "
},
{
"amount_cents": 5000,
"threshold_display_name": "Step 2"
},
{
"amount_cents": 10000,
"threshold_display_name": "Step 3"
},
{
"amount_cents": 5000,
"threshold_display_name": "Bill every 50 dollars",
"recurring": true
}
]
}
}
```
## Invoicing behaviors
For our progressive billing feature, invoices are generated whenever a threshold is crossed, regardless of when it occurs within a billing period.
However, there are a few specific behaviors and edge cases related to this feature that are important to consider.
### Invoicing during job execution
It's important to note that **threshold billing occurs when our progressive billing job runs** (every 5 minutes by default, though this interval can be adjusted on a case-by-case basis).
This means that Lago does not trigger the invoice immediately when the threshold is crossed but rather at a predefined interval.
As a result, Lago will invoice the total usage at the time the job runs, **which may slightly exceed the threshold**.
For instance, if your billing threshold is \$10 but the job runs when the customer's current usage is \$12, Lago will invoice for the full \$12.
### Charges included in the calculation
**Only charges billed in arrears (recurring or metered) are included in the lifetime usage calculation for progressive billing invoices**.
This means any charges paid in advance are excluded from this progressive billing feature.
### Excluding already billed usage
When a customer crosses a threshold for a specific subscription, Lago will invoice the total usage for the current period,
ensuring that any 'previously billed usage' is excluded.
This approach provides customers with a clear view of their current consumption while preventing them from being charged again
for usage already invoiced under previous thresholds.
It's important to note that the invoice template (as shown below) includes the following details:
* The total usage for the current period;
* An adjustment that excludes previously billed usage; and
* A footer that provides context, explaining the reason for the invoice, including lifetime usage and the threshold that was crossed.
### Grace period edge cases
It's important to note that **progressive billing invoices are not subject to a grace period** and, therefore, cannot be in a `draft` status.
The reason for this is that draft invoices are not `finalized`, and progressive billing calculations are based solely on `finalized` invoices. Including draft invoices in these calculations would significantly alter the accuracy of the progressive billing process.
### Applying discounts
Progressive billing invoices will automatically apply any available discounts, including coupons, prepaid credits, or credit notes.
### Overriding subscription thresholds
To provide maximum flexibility with the progressive billing feature, you can **override the default plan's thresholds for a specific subscription**.
This allows a particular subscription to have its own customized thresholds. You can add or remove thresholds as needed, or even disable the progressive billing feature entirely for a specific subscription.
### Modifying thresholds
You can edit, add, or remove progressive billing thresholds—or even disable this feature—at any time for a plan or subscription.
This flexibility allows you to adjust thresholds to meet your customer's needs without needing to rebuild everything from scratch.
### Being notified
Since progressive billing invoices can be triggered at any time during a billing period, it's crucial to stay informed when a customer crosses a threshold.
Lago sends a [webhook notification](/api-reference/webhooks/messages#subscription-usage-threshold-reached), `subscription.usage_threshold_reached`, providing details about the subscription and the specific threshold that was exceeded.
# Revenue share
Source: https://getlago.com/docs/guide/revenue-share
Model your revenue-sharing structure within Lago.
**PREMIUM ADD-ON** ✨
This revenue-share feature is available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium feature.
If you’re selling your product or service through a partner, model this revenue-share in Lago.
Mark your customer as a partner, and Lago will generate all invoices as self-billed invoices.
Self-billing is a billing arrangement where the customer creates and issues the invoice on behalf of the supplier for goods or services received.
That said, **please ensure** an agreement is in place with your partner to allow Lago to issue these invoices on their behalf.
## Create a partner
To generate self-billed invoices, create your first partner by following these steps:
1. Go to the **Customers** navigation tab.
2. Click on **Create a Customer**.
3. Enable the **Partner** option by toggling it on.
4. Fill in the customer’s billing information—this will be used to generate invoices.
```bash Create a customer theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
…
"account_type: "partner",
…
}
}'
```
## Generate invoices
To simplify your payment process, Lago will generate invoices on behalf of partners.
All invoices generated for a partner will be marked as **self-billed**. As a result, they won’t appear in revenue analytics in Lago.
The PDF invoice will explicitly mention **Self-billing Invoice** and will not be affected by the custom footer.
A specific notice will be displayed to indicate that the invoice was generated on behalf of the partner with their consent.
These invoices follow a specific numbering system tied to the customer.
Regardless of whether your organization’s invoice numbering is scoped per **organization** or **customer**, all partner invoices will adhere to the **partner invoice numbering**.
# API Keys
Source: https://getlago.com/docs/guide/security/api-keys
## Reveal and copy API key
To copy your API key, go to the **Developers > API keys** section and click the Reveal button.
This will display the selected API key, allowing you to copy it to your clipboard.
## Create an API key
**PREMIUM FEATURE** ✨
This feature is only available to users with a premium license. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
To create a new API key, navigate to the **Developers > API keys** section and click the Add a key button.
You will be prompted to provide an optional Name. While naming the key is not mandatory, it is highly recommended to make it easier to identify later. Once created, the API key will be ready for immediate use.
Whenever a new API key is created, all organization admins are notified via email. The key becomes active and usable instantly.
## Rotate an API key
### Rotate API key instantly
To rotate an API key, navigate to the **Developers > API keys** section and click the Rotate API key button. A new API key will be generated instantly, and the previous key will immediately become inactive and unusable.
Whenever an API key is rotated, all organization admins receive an email notification. The newly generated key becomes active and ready for use immediately.
### Schedule an API key rotation
**PREMIUM FEATURE** ✨
This feature is only available to users with a premium license. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
With this feature, you can schedule an API key rotation for a future time. Options include rotating the key `now`, in `1 hour`, `24 hours`, `48 hours`, or `7 days`. By hovering over the current API key, you can view the scheduled rotation time.
Whenever an API key is rotated, all organization admins receive an email notification. The newly generated key becomes active and ready for use immediately, while the previous key remains available until the scheduled rotation time is reached.
## Set API key permissions
**PREMIUM FEATURE** ✨
This feature is only available to users with an enterprise add-on. Please
**[contact us](mailto:hello@getlago.com)** to get access to this feature.
When creating or editing an API key, you can configure permissions for all objects exposed in the Lago API.
Permissions can be set individually for each object, allowing `read`, `write`, or `read and write` access.
If an API key lacks the necessary permissions to access a specific endpoint, the API will deny the request and return an appropriate error response.
## Delete an API key
To delete an API key, navigate to the **Developers > API keys** section and click the delete button. The API key will be permanently deleted and immediately rendered unusable.
Please note that you can only delete an API key if your organization has more than one API key defined.
## API key "Last used" field
For security purposes, a Last used field displays the last time this API key was accessed. This serves as a helpful indicator to determine if the key is still actively in use.
For scalability reasons and to avoid adding complexity to a high-traffic endpoint, we have decided that the events endpoint will not update the `Last used` field.
# Audit logs
Source: https://getlago.com/docs/guide/security/audit-logs
The audit logs enable organization admins to efficiently track member activity, providing detailed records of who performed each action, what was done, and when it occurred.
## Activity logs
Activity logs provide a record of actions initiated within your organization, including actions performed through the UI, via the API, or triggered automatically by the system (e.g., automated billing operations).
### Activity logs retention
Access to the activity log is limited to paid tiers:
1. Free users do not have access to activity logs;
2. Premium users can view activity logs for up to 30 days; and
3. Enterprise customers with the appropriate paid add-on can access the full activity log history without time limits.
### How to access activity logs
Only organization admins can access Activity Logs through the Developers Console.
To view the logs:
1. Click the **Developers** icon in the navigation sidebar;
2. Select the **Activity Logs** tab; and
3. View paginated activity logs directly in this section.
```bash Activity logs theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/activity_logs" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
```
### Activity log details
Each activity log includes a set of properties that provide context about the recorded action:
* **Type**: The name of the activity (e.g., `plan.updated`, `customer.created`, `invoice.drafted`);
* **Description**: A brief explanation of the activity;
* **Activity ID**: A unique identifier for the activity log entry;
* **Resource Type**: The type of object affected (e.g., `Wallet`, `Invoice`, `Customer`);
* **Resource ID**: The identifier of the impacted resource (e.g., `invoice_id`, `customer_id`);
* **Customer External ID**: Identifies the customer related to the activity;
* **Subscription External ID**: Identifies the subscription related to the activity;
* **Log Date**: The timestamp of the activity;
* **User**: The organization member who triggered the activity; and
* **Source**: Indicates the origin of the action.
* `front` – triggered from the UI
* `api` – triggered from the API
* `system` – triggered automatically by the system (e.g., billing)
In addition to the above, the **Activity Payload** section provides contextual data:
* **Changes**: Details of modified data (available for update actions only); and
* **New Object**: The full payload of the newly created object.
### Filtering activity logs
All of the fields listed above can be used to filter activity logs, either through the UI or via the API.
### Activity logs per object
In the UI, you can view activity logs for a specific object by clicking on the desired object (e.g., a specific customer, plan, invoice, etc.), and access the **Activity Logs** tab.
## API logs
API logs offer a comprehensive record of all API requests and calls made within your organization. They serve as an essential tool for monitoring activity, troubleshooting issues, and auditing system usage.
### API logs limitations
1. **Operation scope:** Only `POST`, `PUT`, and `DELETE` requests are currently recorded in the API logs. All `GET` requests are excluded at this time.
2. **Excluded endpoints:** API calls related to metering and high-throughput ingestion, such as `POST /api/v1/events` or `POST /api/v1/batch_events`, are intentionally omitted from logging to ensure performance and scalability.
### API logs retention
Access to the API requests logs is limited to paid tiers:
1. Free users do not have access to API logs;
2. Premium users can view API logs for up to 30 days; and
3. Enterprise customers with the appropriate paid add-on can access the full API log history without time limits.
### How to access API logs
Only organization admins can access API Logs through the Developers Console.
To view the logs:
1. Click the **Developers** icon in the navigation sidebar;
2. Select the **API Logs** tab; and
3. View paginated activity logs directly in this section.
```bash API Requests Logs theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request GET "$LAGO_URL/api/v1/api_logs" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
```
### API log details
Each API log includes a set of properties that provide context about the recorded action:
* **Endpoint**: The API endpoint that was called;
* **Request ID**: A unique identifier for the request;
* **Request Method**: The HTTP method used for the request (e.g., `POST`, `PUT`, `DELETE`);
* **API key**: The API key used for the request;
* **API version**: The API version used for the request;
* **Origin**: The origin URL of the request;
* **Client**: The SDK or Client used for the request (e.g., `RubySDK`, `PythonSDK` or `PostmanRuntime/7.44.1`); and
* **HTTP status code**: The HTTP status code of the response (e.g., `200`, `400`, `404`).
In addition to the above, the **Event Payload** section provides contextual data:
* **Request Body**: The payload of the request; and
* **Response Body**: The payload of the response.
### Filtering API logs
All the fields described above can be used to filter API logs, either through the UI or programmatically via the API. Here are some key filtering behaviors to note:
**Exact Path Matching**: Supplying a full, exact path (e.g., `/api/v1/customers`) will return only requests made to that specific endpoint. It will **not** include requests to extended paths like `/api/v1/customers/123`.
**Wildcard Path Matching**: You can use wildcard patterns (e.g., `/api/v1/customers/*`) to match all sub-paths related to a resource. This is useful for retrieving all activity tied to specific objects or nested routes.
# RBAC - Role-Based Access Control
Source: https://getlago.com/docs/guide/security/rbac
Define user roles & permissions in Lago.
**PREMIUM ADD-ON** ✨
RBAC is only available to licensed users. Please [**contact us**](mailto:hello@getlago.com) to get access to this premium add-on.
## System roles in Lago
System roles are predefined by Lago and define the access scope and permissions granted to users within the Lago platform. Lago provides three primary system roles:
### Admin role
Admins wield full control over Lago, managing billable metrics, plans, customers, subscriptions, settings or financial analysis.
Typically, developers with admin roles handle all critical billing operations. By default, the account creator is assigned the Admin role.
### Account manager role
The Account manager role suits Sales or Customer Success Managers, enabling them to carry out billing tasks for customers.
Account Managers can assign subscriptions, coupons, add-ons, and override prices but are not permitted to modify metrics or plans.
Here is the [full list of permissions](https://github.com/getlago/lago-api/blob/main/config/permissions.yml) for this pre-built role.
### Finance & analyst role
The Finance & analyst role is view-only, restricted from creating or editing metrics and plans, or assigning core billing actions such as coupons,
subscriptions. It's ideal for analyzing financial data, reviewing invoices, and issuing credit notes as necessary.
Here is the [full list of permissions](https://github.com/getlago/lago-api/blob/main/config/permissions.yml) for this pre-built role.
## Custom roles and permissions
**PREMIUM ADD-ON** ✨
This add-on is available on demand only. Please [**contact us**](mailto:hello@getlago.com) to get access to this premium add-on.
Custom roles enable you to **define tailored permission sets that align with your organization's specific requirements**. There is no limit to the number of custom roles you can create. This feature is designed around the following principles:
* Updating the permissions of a role automatically updates the permissions for all users assigned to that role; and
* At least one role with administrative permissions must always exist.
[This document](https://github.com/getlago/lago-api/blob/main/config/permissions.yml) outlines all the potential permissions by object that can be assigned to a custom role.
To create a custom role:
1. Navigate to the **Settings** view in Lago;
2. Access the **Roles & Permissions** section;
3. Click on **Create Role**;
4. Define the role `name`, `code` and `description`;
5. Select the desired permissions from the list;
6. Save the new custom role; and
7. Assign users to the newly created custom role.
# SOC 2 Type 2
Source: https://getlago.com/docs/guide/security/soc
Keeping your data secure.
Lago has achieved SOC 2 Type 2 compliance for its fully hosted version, which certifies the effectiveness of our operating and security controls.
Please contact [hello@getlago.com](mailto:hello@getlago.com) to request the full report. Please note that the self-hosted version is compliant by default, as you own the data and the infrastructure.
## Data Security
Lago encrypts data at rest and in transit for all of our customers. We use Amazon Web Service’s Key Management System (KMS) to manage encryption keys for maximum security, in line with industry best practices.
## Application Security
Lago also uses Dependabot, a high-quality analysis tooling provided by GitHub Advanced Security, to secure our product at every step of the development process.
## Infrastructure Security
Lago uses Amazon Web Services to host our application. We make use of the security products embedded within the AWS ecosystem, including KMS and GuardDuty.
In addition, we deploy our application using Kubernetes containers run on AWS managed services, meaning we typically do not manage servers or EC2 instances in production.
If you have further questions about security, please refer to [this page](https://www.getlago.com/company/security)
# Single Sign-On (SSO)
Source: https://getlago.com/docs/guide/security/sso
## Google SSO
Lago integrates with Google Single Sign-On (Google SSO), enabling your team to access Lago using their existing Google credentials.
This seamless integration allows team members to log in with their corporate Gmail accounts, eliminating the need for additional usernames and passwords.
This streamlines the login process and enhances security by leveraging Google's authentication infrastructure.
## Okta SSO
**PREMIUM ADD-ON** ✨
This add-on is available on demand only. Please [**contact us**](mailto:hello@getlago.com) to get access to this premium add-on.
Lago integrates with Okta Single Sign-On (Okta SSO), enabling your team to access Lago using their existing Okta credentials.
### Mandatory Okta settings
### Configure an Authorization Server
1. Log in to your Okta Admin Console.
2. Navigate to **Security** → **API** → **Authorization Servers**.
3. Create a new server by clicking **Add Authorization Server**.
4. Name: Choose a name for the auth server (e.g., `Lago`)
5. Audience: Enter the audience value which is usually your app’s base URL (e.g., `https://app.getlago.com` or `https://eu.getlago.com`)
6. Description: Optional field to describe the auth server
### Create scopes
Scopes define the level of access the app is requesting
1. In the Authorization Server details, click on Scopes tab.
2. Add a new scope that your app requires:
3. Name: `user_info`
4. Display name: Access user info
5. Description: This allows you to use user info to sign-in/sign-up to the app
6. User consent: Implicit
7. Default scope: False
### Create an application and settings
1. Go to your Okta Admin Console.
2. Navigate to **Applications** → **Applications**
3. Create a new application by clicking **Create App Integration**
4. **Sign-in method**: Define the method as `OIDC - OpenID Connect` & `Web Application`
5. **Grant type**: Check the `Refresh token` option
6. **Sign-in redirect URLs**: Enter the sign-in redirect value which is usually your app’s base URL with these values (e.g., `https://app.getlago.com/auth/okta/callback` or `https://eu.getlago.com/auth/okta/callback`)
7. **Assignments**: Define the assignment option based on your policy
Once created, please ensure the `Refresh tokens behaviour` is set to `Use persistent token`
### Connect Lago to Okta
To connect Lago to Okta, please follow these steps:
1. Go to your Lago Settings view.
2. Access the Authentication section.
3. Domain name: usually your app base URL (e.g., `acme.com`)
4. Application client ID: Public identifier for the client that is required for all OAuth flows.
5. Application client secret: Secret generated by Okta for this application
6. Okta organization name: Name of your organization (e.g., for a trial account `trial-5875810`)
Once all these setups are complete, don’t forget to add users to your Okta account and verify their accounts.
### Log in to Lago or join an existing organization
Once this integration is switched on, it allows team members to log in or join an existing organization with their corporate Okta accounts, eliminating the need for additional usernames and passwords. This streamlines the login process and enhances security by leveraging Okta’s authentication infrastructure.
### Edit or delete Okta's connection
Once this integration is switched on, you can edit the connection information or delete it. Please note that once deleted, you won't be able to access Lago via Okta SSO. Use the Forgot password feature to regain access to your account.
## Login Method Enforcement
As an organization admin, you can control which authentication methods are allowed for your team. This feature helps maintain security compliance by enforcing specific login methods across your organization.
### Managing Authentication Methods
Admins can configure allowed login methods from the **Organization Settings / Authentication** tab:
1. Navigate to your organization settings
2. Click on the **Authentication** section
3. Enable or disable login methods such as:
* Password login
* Google OAuth
* Okta SSO (if connected)
Only enabled methods will be available to users for login.
# Assign a plan to a customer
Source: https://getlago.com/docs/guide/subscriptions/assign-plan
A subscription is created when a plan is assigned to a customer. You can assign a plan to a customer at any time (i.e. when the customer record is created or later on).
To assign a plan to a customer through the user interface:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. In the **"Overview"** tab, click **"Add a plan"** on the right;
4. Select a plan (that you can overwrite if needed - [see below](#overwriting-a-plan));
5. Give a name to the subscription (name that will be displayed on the invoice - optional);
6. Give an id to the subscription (define your own subscription identifier - optional);
7. Set a subscription start date (start date of the subscription - [see below](#subscription-start-date));
8. Set a subscription end date (end date of the subscription - [see below](#subscription-end-date) - optional);
9. Choose whether the subscription should be renewed at the beginning of the period or on its anniversary date (see [below](#billing-cycles)); and
10. Click **"Add plan"** to confirm;
```bash Assign a plan to a customer theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"plan_code": "premium",
"external_id": "my_sub_12345789",
"name": "Repository 1",
"subscription_at": "2022-08-08T00:00:00Z",
"billing_time": "anniversary"
}
}'
```
When a subscription is active, Lago will automatically generate invoices for the customer according to the [plan model](/guide/plans/plan-model). It will also start monitoring the customer's consumption, which means that you can start pushing [events](/guide/events/ingesting-usage) related to this subscription.
The subscription date displayed in the app is based on the organization's timezone.
## Billing cycles
Optimize billing for your customers by assigning subscriptions based on either calendar dates or anniversary dates (the day they signed up).
By default, subscriptions are based on **calendar periods**. Therefore, if you assign a monthly plan to a customer on July 14th:
* The first invoice will be generated for the period July 14th to July 31st;
* The next invoice will be generated for the period August 1st to August 31st; and
* All future invoices will be generated for full calendar months.
When a subscription starts during the month, the subscription fee will be calculated on a **pro rata basis** according to the number of days.
Consider the following example:
> Your customer signs up for the Premium plan, \$50 monthly, on August 10th. There are 22 days left until the end of the month, including August 10th. Therefore, the subscription fee for August is:
> **22 days x \$50 / 31 days = \$35.48**
Another option is to use the **anniversary date** of the subscription to define a custom billing period.
For example:
> Your customer signs up for the Premium plan on August 10th.
> If you choose to align the billing cycle with the anniversary date of the subscription, the customer will be billed every 10th of the month.
> The first billing period will run from August 10th to September 9th.
## Subscription start date
By default, the subscription starts the day it is created. However, you can set a subscription date in the past or in the future.
The subscription date displayed in the app is based on the organization's timezone.
However, you can decide to start a subscription **in the past** or **in the future**.
If the start date of the subscription is in the past, the subscription is considered active.
Lago will not generate any invoices for past periods already completed.
The invoicing process varies depending on the [plan model](/guide/plans/plan-model) and [billing cycle](#billing-cycles):
* If the plan includes a subscription fee to be paid in advance, it will be considered as **already paid for the current period**. The next invoice will include the usage-based charges for the current period and the subscription fee for the next period (see example 1 below); and
* If the plan includes a subscription fee to be paid in arrears, it will be **included in the next invoice**, together with the usage-based charges for the current period (see example 2 below).
**Example 1:** Start date in the past and subscription fee to be paid in advance
**Example 2:** Start date in the past and subscription fee to be paid in arrears
If the start date of the subscription is in the future, the subscription is considered pending.
The invoicing process varies depending on the [plan model](/guide/plans/plan-model) and [billing cycle](#billing-cycles):
* If the plan includes a subscription fee to be paid in advance, when the subscription becomes active, Lago will automatically generate an **invoice for the subscription fee**. Usage-based charges will be included in the next invoice, generated at the end of the billing period (see example 3 below); and
* If the plan includes a subscription fee to be paid in arrears, when the subscription becomes active, **there will be no invoice**. The subscription fee and usage-based charges will be included in the invoice generated at the end of the billing period (see example 4 below).
**Example 3:** Start date in the future and subscription fee to be paid in advance
**Example 4:** Start date in the future and subscription fee to be paid in arrears
## Subscription end date
By default, if no subscription end date is specified, **the subscription will automatically renew at the end of the period**.
However, if you define an end date, the subscription will terminate on that date without renewal. This is valuable for contracts with specific termination dates.
Keep in mind, 45 days and 15 days before the subscription ends, a webhook alert, called `subscription.termination_alert`, will remind you. You then have two choices:
1. Allow the subscription to continue until the end date and finalize it; or
2. Adjust the subscription end date if the contract has been renegotiated.
Ensure that the subscription end date is set to a date later than the subscription start date.
Here is how you can define a subscription end date from the UI:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. In the **"Overview"** tab, click **"Add a plan"** on the right;
4. Set a subscription start date;
5. Set a subscription end date;
6. Choose between calendar or anniversary billing;
7. Click **"Add plan"** to confirm.
Use the `ending_at` field on the subscriptions endpoint.
```bash Define a subscription end date theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"plan_code": "premium",
"external_id": "my_sub_12345789",
"name": "Repository 1",
"subscription_at": "2022-08-08T00:00:00Z",
"ending_at": "2023-08-08T00:00:00Z",
"billing_time": "anniversary"
}
}'
```
## Multiple plans
You may create several subscriptions for a customer by assigning them multiple plans. This can be particularly useful if your application allows customers to create different projects or workspaces (e.g. Free plan for Workspace 1, Free plan for Workspace 2, Premium plan for Workspace 3, etc.).
There are some rules to keep in mind when assigning multiple plans to a customer:
1. All plans must be denominated in the same currency; and
2. You must specify the `external_subscription_id` for each event or create [batch events](/api-reference/events/batch).
It is possible to subscribe a customer to multiple plans using different billing cycles (e.g. a subscription based on calendar dates and another based on the anniversary date).
We recommend that you give each subscription a name when assigning multiple plans to a customer. The subscription names will make it easier to differentiate each plan and will also be displayed on the invoices.
When multiple subscriptions are linked to a customer, Lago will automatically consolidate invoices when possible.
| | Month 1 | Month 2 | Month 3 | Month 4 | (...) | Month 13 |
| ---------------- | ------- | ------- | ------- | ------- | ----- | -------- |
| Plan A (monthly) | \$40 | \$40 | \$40 | \$40 | (...) | \$40 |
| Plan B (monthly) | \$60 | \$60 | \$60 | \$60 | (...) | \$60 |
| Plan C (yearly) | \$500 | - | - | - | (...) | \$500 |
| Total invoice | \$600 | \$100 | \$100 | \$100 | (...) | \$600 |
## Overriding a plan
**PREMIUM FEATURE** ✨
This feature is only available to users with a premium license. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
By assigning a subscription to a customer, you gain the flexibility to customize certain aspects of the initially selected plan.
This enables you to maintain a consistent plan structure for all customers while tailoring individualized discounts through price adjustments per customer.
To perform plan overrides, assign a plan to a customer and you’ll be able to make modifications to the following elements:
1. Subscription invoice display name
2. Subscription fee
3. Plan currency
4. Plan trial period
5. Plan taxes
6. Charges properties (please note that the charge model cannot be modified)
7. Charge group definitions & properties (if applicable)
8. Charge minimum spending
9. Charge taxes
10. Charge invoice display name
11. [Progressive billing](/guide/plans/progressive-billing) thresholds
```bash Override a plan theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"plan_code": "premium",
"external_id": "my_new_sub_123456789",
"name": "",
"subscription_at": "2022-08-08T00:00:00Z",
"ending_at": "2023-08-08T00:00:00Z",
"billing_time": "anniversary",
"plan_overrides": {
"name": "new_plan",
"invoice_display_name": "Subscription fee",
"description": "Overriden plan for customer X",
"amount_cents": 10000,
"amount_currency": "USD",
"trial_period": "0",
"tax_codes": [
"vat_10"
],
"charges": [
{
"id": "cac4cff7-e2d9-41e2-83e5-7947d91f0eb5",
"invoice_display_name": "Cards - custom price",
"billable_metric_code": "cards",
"min_amount_cents": 0,
"properties": {
"amount": "10"
},
"group_properties": [],
"taxes": []
}
]
}
}
}'
```
It's crucial to note that all overridden plans will remain associated with the initial plan but won't be visible in the plans list.
To access an overridden plan, simply click on the specific subscription item in the customer details view.
Moreover, all invoices generated from this subscription will be based on the overridden plan, not the initial plan.
Additionally, any coupons restricted to a plan code will apply to both the initial and overridden plans.
Importantly, any changes made to the initial plans will not impact the subscriptions linked to overridden plans.
## Deleting a plan
You could [delete a plan](/api-reference/plans/destroy) linked to existing subscriptions.
If you do so, the subscriptions associated with this plan will be immediately terminated. This action may trigger the generation of invoices and/or credit notes.
After deleting a plan, you can create a new one using the same code.
# Edit a subscription
Source: https://getlago.com/docs/guide/subscriptions/edit-subscription
You can edit a subscription at any time, whether it's active or pending.
Once a plan has been assigned to a customer, whether it's in a pending or active state, you can make edits to the subscription by following these steps:
1. Click on the three dots menu icon and select "Edit subscription."
2. Subscription Start and End Date\
You have the ability to modify the subscription start date if the subscription is pending, and if the chosen date is later than today. It's important to refer to the [guidelines for subscription start date](https://docs.getlago.com/guide/subscriptions/assign-plan#subscription-start-date) for further information.
3. Subscription End Date\
You can also make changes to the subscription end date, but it's important to refer to the [guidelines for subscription end date](https://docs.getlago.com/guide/subscriptions/assign-plan#subscription-end-date) for further information.
4. You can edit any prices listed for a subscription, including charges, commitments, tiers and spending minimums.
```bash Override a plan theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request PUT "$LAGO_URL/api/v1/subscriptions/{external_id}" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"name": "",
"subscription_at": "2022-08-08T00:00:00Z",
"ending_at": "2023-08-08T00:00:00Z",
"plan_overrides": {
"name": "new_plan",
"invoice_display_name": "Subscription fee",
"description": "Overriden plan for customer X",
"charges": [
{
"id": "cac4cff7-e2d9-41e2-83e5-7947d91f0eb5",
"invoice_display_name": "Cards - custom price",
"properties": {
"amount": "10"
},
"group_properties": [],
}
]
}
}
}'
```
# Terminate a subscription
Source: https://getlago.com/docs/guide/subscriptions/terminate-subscription
You can terminate a subscription at any time, whether it's active or pending.
## Terminate an active subscription
To terminate an active subscription through the user interface:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. In the **"Overview"** tab, select an active subscription; and
4. Click **"Terminate subscription"**.
```bash Terminate an active subscription theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_ID="__YOUR_SUBSCRIPTION_ID__"
curl --location --request DELETE "$LAGO_URL/api/v1/subscriptions/$EXTERNAL_ID" \
--header "Authorization: Bearer $API_KEY"
```
### Generate a closing invoice at subscription termination
By default, Lago automatically generates a closing invoice for any **outstanding usage-based charges** or **pay-in-arrears subscription fees** that haven’t yet been invoiced.
If you don’t want to generate an invoice at termination:
In the Termination dialog, simply switch off the **Generate final invoice** option.
```bash Terminate a subscription without closing invoice theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_ID="__YOUR_SUBSCRIPTION_ID__"
curl --location --request DELETE "$LAGO_URL/api/v1/subscriptions/$EXTERNAL_ID?on_termination_invoice=skip" \
--header "Authorization: Bearer $API_KEY"
```
### Generate a closing credit note at subscription termination
If the subscription fee has been **paid in advance**, Lago automatically issues a credit note for the **unused days**.
At termination, you can :
In the Termination dialog, you can choose how to handle unused amounts:
* **Skip** – Don’t generate a credit note.
* **Offset** — The unused due amount is offset against the invoice, reducing the remaining amount due.
* **Refund** – If the invoice is paid or partially paid, the unused paid amount is refunded; any unpaid unused amount is credited back to the customer.
* **Credit** (default) – The unused amount is credited back to the customer.
```bash Terminate a subscription without closing credit note theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_ID="__YOUR_SUBSCRIPTION_ID__"
curl --location --request DELETE "$LAGO_URL/api/v1/subscriptions/$EXTERNAL_ID?on_termination_credit_note=skip" \
--header "Authorization: Bearer $API_KEY"
```
## Terminate a pending subscription
To terminate a pending subscription through the user interface:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. In the **"Overview"** tab, select a pending subscription (subscription set in the future or pending downgrade); and
4. Click **"Terminate subscription"** to cancel a pending subscription.
```bash Terminate a pending subscription theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
EXTERNAL_ID="__YOUR_SUBSCRIPTION_ID__"
curl --location --request DELETE "$LAGO_URL/api/v1/subscriptions/$EXTERNAL_ID?status=pending" \
--header "Authorization: Bearer $API_KEY"
```
To ensure the termination of a pending subscription, it is crucial to include the `?status=pending` filter in your endpoint.
Neglecting to do so will render any termination attempts ineffective.
# Upgrades and downgrades
Source: https://getlago.com/docs/guide/subscriptions/upgrades-downgrades
Customers have the flexibility to easily upgrade or downgrade their plan at any given moment.
To perform an upgrade or a downgrade through the user interface:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. In the **"Overview"** tab. By clicking the ellipsis icon, you can **"Upgrade/downgrade plan"**;
4. Give a name to the new subscription (name that will be displayed on the invoice - optional);
5. Provide a new subscription end date if needed (optional);
6. Click **"Upgrade/downgrade plan"** to confirm.
```bash Upgrade or downgrade a subscription theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/subscriptions \
--header 'Authorization: Bearer ' \
--data '{
"subscription": {
"external_customer_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"plan_code": "new_plan",
"external_id": "existing_sub_id"
}
}'
```
## Upgrades behavior
An upgrade occurs when the subscription fee of the new plan, calculated on a daily basis, equals or exceeds the subscription fee of the previous plan,
regardless of the pricing for usage-based charges.
When a subscription is upgraded, Lago immediately applies the new plan to the customer.
### Subscription paid in advance
Lago issues a [credit note](/guide/invoicing/credit-notes/overview) for the unused days remaining on the former plan.
### Subscription paid in arrears
When a plan is upgraded mid-cycle, Lago immediately generates an invoice covering the prorated portion of the old plan (i.e., the days used before the upgrade).
At the end of the billing period, a second invoice is issued for the prorated portion of the new plan (i.e., the days used after the upgrade).
**Example:** A customer subscribes to Plan A (€100/month, paid in arrears, calendar billing) on January 1st, then upgrades to Plan B (€200/month) on January 15th.
* **January 15th** — Invoice for Plan A: 14 days prorated = **€45.16** (14/31 × €100)
* **January 31st** — Invoice for Plan B: 17 days prorated = **€109.68** (17/31 × €200)
## Downgrades behavior
A downgrade occurs when the subscription fee of the new plan, calculated on a daily basis is lower than the subscription fee of the previous plan,
regardless of the pricing for usage-based charges.
When a subscription is downgraded:
* The new plan is applied at the end of the current billing period to ensure that your customer fully benefits from the plan they have already paid for. The newly applied plan will be in a pending state.
## Webhook messages for upgrades and downgrades
When a subscription is upgraded or downgraded:
* A `subscription.terminated` webhook message is triggered for the initial plan, with a `next_plan_code` defined in the payload;
* A `subscription.started` webhook message is triggered for the new plan, with a `previous_plan_code` defined in the payload;
* The `subscription.external_id` is persisted between the two to ensure the continuity of the subscription.
# Overview
Source: https://getlago.com/docs/guide/wallet-and-prepaid-credits/overview
Since usage-based charges can be calculated at the end of the billing period, you often need to wait to collect payments. With prepaid credits, you can now unlock recurring revenue opportunities for pay-as-you-go pricing models.
Prepaid credits increase predictability as they allow you to collect payments in advance and then monitor the evolution of the balance of your customer’s wallets.
## Create wallets[](#create-wallets "Direct link to heading")
You can create up to 5 active wallets per customer, each with its own settings. A wallet can be scoped to specific fees or billable metrics, include usage limitations, and define its own recurring top-up rules.
When a subscription or progressive billing invoice is generated, Lago automatically applies available wallet credits to reduce the invoice total.
You control the order in which wallets are applied using wallet priority, from 1 to 50 — where 1 is applied first and 50 last. This ensures credits are consumed exactly as intended.
To create a wallet for one of your customers through the user interface:
1. Access the **"Customers"** section via the side menu;
2. Select a customer from the list;
3. Open the **"Wallets"** and click **"Add a wallet & credits"** on the right;
4. Choose a name for the wallet (optional);
5. Set the credit value (e.g. 1 credit = \$5);
6. Define the wallet priority;
7. Enter the number of credits to be purchased and/or granted for free;
8. Define transaction metadata (optional & available only via API);
9. Determine whether the wallet transaction generates an invoice after a top-up or only following a successful payment;
10. Set the [expiration date](#expiration-date-and-termination) (optional); and
11. Click **"Add wallet & credits"** to confirm.
If the currency of the customer is already defined, the currency of the wallet
must be the same.
```bash Create a credit wallet theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": {
"external_customer_id": "hooli_1234",
"name": "Prepaid credits",
"rate_amount": "1.0",
"paid_credits": "100.0",
"granted_credits": "50.0",
"currency": "USD",
"expiration_at": "2022-07-07",
"invoice_requires_successful_payment": false,
"transaction_metadata": [
{
"key": "top-up-type",
"value": "manual"
}
]
}
}'
```
Free credits are added to the customer's wallet instantly, while purchased
credits are added to the wallet when payment is confirmed (see below).
Each customer can only have one active wallet.
## Real time wallet balance[](#real-time-wallet-balance "Direct link to heading")
**PREMIUM FEATURE** ✨
This feature is only available to users with a premium license. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
Keep track of your wallet's real-time balance. Lago provides two types of balances for your wallet:
1. **Balance:** invoiced balance, which reflects the remaining prepaid credits in your wallet. It updates each time an invoice is finalized for the customer.
2. **Ongoing Balance:** balance accounted for current usage, including taxes and draft invoices offering a real-time estimate of your balance's consumption. It refreshes every 5 minutes or upon the finalization of an invoice for the customer.
## Application scope[](#application-scope "Direct link to heading")
Prepaid credits settled in a wallet are applied to upcoming **subscription invoices**. They are deducted from the post-tax subtotal, after any credit notes have been applied.
```
## EXAMPLE OF INVOICE
All subscriptions fee $50.00
All usage-based fees $20.00
Coupons -$10.00
-------------------------------
Subtotal (excl. tax) $60.00
Tax (10%) $ 6.00
-------------------------------
Subtotal (incl. tax) $66.00
Credit notes $20.00
Prepaid credits $30.00
-------------------------------
Total $16.00
```
Prepaid credits do not apply to one-off invoices.
By default, prepaid credits apply to all fee types—subscriptions, charges, and commitments. You can refine this behavior by configuring limitation rules directly in the wallet.
To limit the scope of prepaid credits through the user interface:
1. Create or edit an existing wallet;
2. In the “Limit wallet credits to specific object” section, add one or more object limitations;
3. You can also limit wallet prepaid credits to specific billable metrics; and
4. Keep in mind: selecting all items has the same effect as selecting none. For this reason, we recommend leaving all options unselected unless a specific restriction is needed.
```bash Scope wallet to specific fee theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header "Authorization: Bearer $API_KEY" \
--header "Content-Type: application/json" \
--data-raw '{
"wallet": {
"external_customer_id": "hooli_1234",
"name": "Prepaid credits",
"rate_amount": 1.0,
"paid_credits": 100.0,
"granted_credits": 50.0,
"currency": "USD",
"applies_to": {
"fee_type": ["charge", "commitment", "subscription"]
}
}
}'
```
## Invoicing after successful payment option
When enabled, this option delays issuing an invoice for a wallet top-up until a successful payment is made. If disabled, the invoice is issued immediately upon the wallet top-up, regardless of the payment status. This setting applies to all transactions for the wallet, but can be overridden for individual transactions or recurring rules.
## Wallet transaction limits
For each wallet, you can set minimum and maximum limits per paid transaction.
When these limits are defined, any top-up attempt must fall within the specified range—transactions below the minimum or above the maximum will be rejected.
```bash Add wallet min and max limits theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header "Authorization: Bearer $API_KEY" \
--header "Content-Type: application/json" \
--data-raw '{
"wallet": {
"external_customer_id": "hooli_1234",
"name": "Prepaid credits",
"rate_amount": 1.0,
"paid_top_up_min_amount_cents": 1000,
"paid_top_up_max_amount_cents": 100000
}
}'
```
For a single transaction, you can ignore wallet limits at any time by adding the `ignore_paid_top_up_limits` flag to the payload, or by enabling the **Skip top-up limits for this transaction** option in the UI.
This applies to both single transactions and automatic top-ups (recurring wallet transactions).
## Expiration date and termination[](#expiration-date-and-termination "Direct link to heading")
By default, if you don't set an expiration date, prepaid credits are carried
over to the next billing period until the wallet balance is zero.
If you define an expiration date, when the date is reached, all remaining
credits are **automatically voided**.
To modify the expiration date of the prepaid credits through the user interface:
1. Open the **"Wallets"** tab and click **"Edit wallet"** on the right;
2. Select **"Edit information"**;
3. Modify the expiration date; and
4. Click **"Edit information"** to confirm.
The expiration date displayed in the app is based on the organization's timezone.
You also have the ability to terminate a wallet manually, before its expiration
date:
1. Open the **"Wallets"** tab and click **"Edit wallet"** on the right;
2. Select **"Terminate wallet"**; and
3. Click again to confirm.
Terminating a wallet will instantly void all remaining credits. This action
**cannot be undone**.
# Top-up and void credits
Source: https://getlago.com/docs/guide/wallet-and-prepaid-credits/wallet-top-up-and-void
Add and void credits, to the customer's wallet.
## Credit purchases and top-ups[](#credit-purchases-and-top-ups "Direct link to heading")
Lago automatically generates an invoice for each purchase. Taxes do not apply to
credit purchases, which are considered as advance payments.
Payment must be made in order for credits to be added to the customer's wallet
(i.e. the status of the invoice must be `succeeded`).
If a paid top-up is made, Lago will automatically round the top-up credits to the nearest cent to comply with decimal rounding rules for amounts.
However, this logic does not affect free credits.
To top up a wallet through the user interface:
1. Open the **"Wallets"** tab and click **"Edit wallet"** on the right;
2. Select **"Top up credit"**;
3. Enter the number of credits to be purchased and/or granted for free;
4. Define transaction metadata (optional & available only via API);
5. Determine whether the wallet transaction generates an invoice after a top-up or only following a successful payment; and
6. Click **"Top up credit"** to confirm.
Coupons **do not apply** to credit purchases and top-ups.
```bash Top up a credit wallet theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallet_transactions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet_transaction": {
"wallet_id": "wallet_1234567890",
"paid_credits": "20.0",
"granted_credits": "10.0",
"invoice_requires_successful_payment": false,
"metadata": [
{
"key": "top-up-type",
"value": "manual"
}
]
}
}'
```
## Invoicing top-up after successful payment option
When enabled, this option delays issuing an invoice for a wallet top-up until a successful payment is made. If disabled, the invoice is issued immediately upon the wallet top-up, regardless of the payment status.
This setting can be applied to individual transactions.
## Void credits[](#void-credits "Direct link to heading")
You can deduct an exact number of credits from the wallet's balance. Note that this action is instantaneous and cannot be undone.
To void credits through the user interface:
1. Open the **"Wallets"** tab and click **"Edit wallet"** on the right;
2. Select **"Void credits"**;
3. Enter the number of credits to void;
4. Define transaction metadata (optional & available only via API); and
5. Click **"Void credits"** to confirm.
```bash Top up a credit wallet theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallet_transactions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet_transaction": {
"wallet_id": "wallet_1234567890",
"voided_credits": "20.0",
"metadata": [
{
"key": "top-up-type",
"value" "manual-void"
}
]
}
}'
```
## Setup recurring top-ups
When creating or editing a wallet, you have the option to enable recurring top-ups. Two methods for recurring top-ups are available: `fixed` and `target`. These can be triggered either based on an `interval` or a `threshold`.
Be advised that when setting a start date for a recurring top-up, it will be ignored if it is the same as the date the wallet was created. For example, if you create a wallet on Jan 1st, 2026, and set a monthly recurring top-up to start on Jan 1st, 2026, the top-up will not trigger until Feb 1st, 2026.
### Fixed recurring top-up
A fixed recurring top-up allows you to add a predetermined number of credits to your wallet, either for purchasing or gifting.
### Target recurring top-up
A target recurring top-up allows you to add a variable amount of credits to your wallet to reach a specific target balance. The top-up amount is determined by the ongoing balance at the trigger moment and the desired target balance.
### Interval trigger
For an `interval` trigger, specify the frequency of the automatic top-up: `weekly`, `monthly`, `quarterly`, `semiannual` or `yearly`.
Once the interval is defined, the system will automatically perform a top-up:
* Weekly, on the same day each week (e.g., every Monday).
* Monthly, on the same date each month (e.g., every 2nd of the month).
* Quarterly, on the same date every three months (e.g., every 2nd of the quarter).
* Semiannual, on the same date every six months (e.g., every 2nd of the semester).
* Yearly, on the same date every year (e.g., every 2nd of January).
To set up an `interval` recurring top-up through the user interface:
1. Create or edit a wallet;
2. Trigger on the option `Activate recurring top-up`;
3. Select `interval` as recurring type;
4. Define your interval;
5. Define when the rule should start; and
6. Define transaction metadata for the top-ups (optional & available only via API);
```bash Setup an interval recurring top-up theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": {
"external_customer_id": "hooli_1234",
"name": "Prepaid credits",
"rate_amount": "1.0",
"paid_credits": "0.0",
"granted_credits": "0.0",
"currency": "USD",
"expiration_at": "2022-07-07",
"recurring_transaction_rules": [
{
"method": "fixed"
"trigger": "interval",
"interval": "weekly",
"started_at": null,
"paid_credits": "100.0",
"granted_credits": "0.0",
"invoice_requires_successful_payment": false,
"transaction_metadata": [
{
"key": "top-up-type",
"value": "automatic"
}
]
}
]
}
}'
```
### Threshold trigger
With a `threshold` trigger, set a specific number of `credits` that will trigger an automatic top-up. Lago monitors the `ongoing balance`, and if it falls below the defined credit threshold, an automatic top-up is initiated.
To set up an `interval` recurring top-up through the user interface:
1. Create or edit a wallet;
2. Trigger on the option `Activate recurring top-up`;
3. Select `threshold` as recurring type;
4. Define the credits threshold; and
5. Define transaction metadata for the top-ups (optional & available only via API);
```bash Set a recurring top-up on creation theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": {
"external_customer_id": "hooli_1234",
"name": "Prepaid credits",
"rate_amount": "1.0",
"paid_credits": "100.0",
"granted_credits": "50.0",
"currency": "USD",
"expiration_at": "2022-07-07",
"recurring_transaction_rules": [
{
"method": "fixed"
"trigger": "threshold",
"threshold_credits": "100.0"
"paid_credits": "100.0",
"granted_credits": "0.0",
"invoice_requires_successful_payment": true,
"transaction_metadata": [
{
"key": "top-up-type",
"value": "automatic"
}
]
}
]
}
}'
```
### Expiration date
Define an expiration date for your recurring transaction rule. Once reached, the rule will be terminated and will no longer generate any top-ups.
# Webhooks
Source: https://getlago.com/docs/guide/webhooks
When using Lago, the app generates [several events](/api-reference/webhooks/messages) that you can listen to in order to trigger workflows. Each time an event is generated, you can view it in the Lago application using the webhook logs. This allows you to take a closer look at the generated events, detect possible errors, and retry them.
## Adding a webhook URL
To add a webhook endpoint via the Lago app, follow these steps:
1. Go to the **Developers** section via the sidebar;
2. Open the **Webhooks** tab;
3. Click **Add a webhook**;
4. Enter the webhook name and URL;
5. Choose the webhook signature between HMAC and JWT;
6. Define the events you want to listen to by selecting the relevant checkboxes; and
7. Click **Add webhook** to confirm.
Note that you can add up to 10 webhook endpoints.
## The webhook signature
By creating a webhook endpoint, you have two signature options.
* The first is `JWT`, with a possibly lengthy payload header and potential size limits;
* The second is `HMAC`, which features a shorter payload header and no size restrictions.
```bash Choosing the webhook signature theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/webhook_endpoints" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"webhook_endpoint": {
"webhook_url": "https://foo.bar",
"signature_algo": "hmac"
}
}'
```
## Locate your HMAC signature token
To find your HMAC signature token, navigate to **Developers > Webhooks** and locate the **HMAC Signature Token**. Then, reveal and copy the key.
## Accessing the webhook logs
Once a webhook is registered in the app, you can access the webhook logs:
1. Go to the **Developers** section via the sidebar;
2. Open the **Webhooks** tab;
3. Click on the webhook endpoint to see the list of events;
4. Filter events by dates, types, HTTP status and status; and
5. Click the reload icon to see new events (optional).
## Accessing a specific event
You can see the details of a specific event by clicking on it. Depending on the event status, you will have access to two or three main blocks:
1. **A list of properties, including:**
1. **Timestamp:** the timestamp of the event;
2. **Webhook URL:** the URL used to listen to events;
3. **Unique key:** idempotency key associated with the event;
4. **Webhook type:** the webhook type used to understand the action triggered;
5. **Response:** the response code (i.e. acknowledgement of receipt);
6. **Number of retries:** if the event failed, the number of retries attempted;
2. **A JSON snippet with the arguments sent by Lago; and**
3. **If the event failed, an error response will be included.**
## Errors and retries
Your webhook server should respond with a 2xx (`200`, `201`, `202`, `204`) status code to acknowledge the receipt of the event. If the response is not supported as a success, Lago will consider it as failed.
Some events generated by Lago may not be received on the user side, which is why Lago displays an error status in the user interface.
# NetSuite
Source: https://getlago.com/docs/integrations/accounting/netsuite
Lago seamlessly integrates with NetSuite, enabling real-time synchronization of billing data with your preferred accounting tool.
**PREMIUM ADD-ON** ✨
This integration is available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium integration.
## RESTlet script configuration
Lago's native integration with NetSuite utilizes a [custom RESTlet script](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_4618456517.html) to provide maximum flexibility in fetching or pushing billing data. To set up the Lago RESTlet script in your NetSuite instance, follow these steps:
### Upload Lago Scripts
1. In NetSuite, go to **Documents > Files > File Cabinet**;
2. Under `SuiteScripts`, create a new folder named `Lago`;
3. **Upload `ramda.min.js`**: This library is essential for using Lago and can be downloaded from [here](https://github.com/ramda/ramda/blob/master/dist/ramda.min.js); and
4. Upload another file into the `Lago` folder and **paste the script provided by your Lago Account Manager**.
### Deploy Lago Scripts
1. Navigate to **Customization > Scripting > Scripts > Create a New Script**;
2. Deploy the Lago script for **All roles** and **All employees** (you can create custom roles if needed); and
3. Make sure to change the script status to `released`.
By deploying this script, you'll generate a **custom endpoint url** that is crucial for the authentication process and enables seamless data synchronization between Lago and NetSuite.
## Mandatory NetSuite settings
To ensure the sync doesn't fail, verify that the following settings are correctly configured. This will enable Lago to sync data to NetSuite properly.
### Remove Locations on invoices and credit memos
Lago doesn't recognize the location field on invoices, which is mandatory by default. To resolve this, remove the location requirement from your invoice form:
1. Navigate to **Customization > Forms > Transaction Forms**;
2. Locate the form related to your invoices;
3. Go to the **Screen Fields** tab; and
4. Find the Location field and **uncheck both the Show and Mandatory checkboxes**.
You can repeat the same operation for Credit Memos
### Create Lago Tax Nexus, Type and Code
To have Lago override the tax details for your invoice line items, follow these steps. If not, Lago will send the amount excluding taxes to NetSuite.
1. Go to **Setup** > **Tax** > **Nexuses** > **New**;
2. Choose a brand new **Nexus** (⚠️ ensure it's unused by other existing tax nexuses. It can be a new state for an existing country, or a new country.);
3. Enter `Lago Tax Nexus` in the **Description** field;
4. Create a new **Tax Agency** by clicking the **+** button. Name it `Lago Tax Agency` and assign it to the relevant parent subsidiary;
5. Save your new Nexus;
6. Add this newly created Nexus to the targeted NetSuite Subsidiaries by navigating to **Setup > Company > Subsidiaries**. Select the parent subsidiary, and add this new nexus in the **Tax Registrations** tab; and
7. Ensure that the tax engine for this registration is set to `SuiteTax Engine`.
1. Navigate to **Setup** > **Tax** > **Tax Types** > **New**;
2. Select the same **Country** as the one used in the Lago Tax Nexus;
3. Name it `Lago Tax Type`;
4. **Link the Lago Tax Nexus** in the Nexus section;
5. Add a **Payables Account** and a **Receivables Account** to this new Tax Type; and
6. Save it.
1. Go to **Setup** > **Tax** > **Tax Code** > **New**;
2. Enter a **Name**, like `Lago Tax`;
3. Select and tie the previously created Lago Tax Type; and
4. Save your settings.
### Define Taxable items
To enable tax amount overrides for your Lago invoices synced to NetSuite, ensure all items are marked as taxable. If any item is non-taxable, the invoice sync will fail. To update an item:
1. Go to **Lists > Accounting > Items**;
2. Edit the item associated with a Lago object;
3. Navigate to the **Accounting** tab;
4. Locate the **Tax / Tariff** section; and
5. Set the item to **Taxable**.
## Connecting Lago to NetSuite
To fully integrate Lago with NetSuite, start by connecting your Lago instance to a new NetSuite connection.
You can have an unlimited number of NetSuite connections. First, link your NetSuite account to Lago.
Once connected, activate the specific syncs and actions required for your use case.
This ensures that your Lago instance is properly configured to communicate with NetSuite, enabling seamless data synchronization and management.
### Create a new integration in NetSuite
After logging into your NetSuite account, navigate to **Setup > Integration > Manage Integrations > New**.
Enter the required integration details and follow these steps:
* Make sure the [oAuth feature is enabled](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_157771482304.html#To-enable-OAuth-2.0-feature%3A) for your NetSuite instance;
* Make sure the *SOAP WEB SERVICES* and *REST WEB SERVICES* features are enabled in **NetSuite > Company > Enable Features > SuiteCloud**;
* Under Authentication, select **TOKEN-BASED AUTHENTICATION**;
* Disable *TBA: AUTHORIZATION FLOW* and *AUTHORIZATION CODE GRANT*; and
* Save your new integration.
The Client Credentials will be displayed. **Copy the `Consumer Key/Client ID` and `Consumer Secret/Client Secret`** and save them in a secure document for future reference, as this information will not be accessible once you leave the screen.
### Create a new access token in NetSuite
* Log into your NetSuite account and navigate to the homepage by **clicking the home icon**;
* In the **Settings** section at the bottom left corner, locate and click the **Manage Access Tokens** button;
* Select the **Application Name** created for this integration;
* Enter a **token Name**; and
* Save your new access token.
The Token Credentials will be displayed. **Copy the `Token ID` and `Token Secret`** and save them in a secure document for future reference, as this information will not be accessible once you leave the screen.
### Authentication flow
The authentication process connects Lago and NetSuite through OAuth2.
To establish this connection, you need to provide the following mandatory fields:
* **Connection Name:** an internal name for the connection within Lago;
* **Unique Connection Code:** an internal code for the connection within Lago;
* **NetSuite Account ID:** your NetSuite [account identifier](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/section_1498754928.html#:~:text=You%20can%20find%20your%20NetSuite,an%20underscore%2C%20for%20example%20123456_RP.);
* **NetSuite Client ID:** the [client ID](/integrations/accounting/netsuite#create-a-new-integration-in-netsuite) from your NetSuite account;
* **NetSuite Client Secret:** the [client secret](/integrations/accounting/netsuite#create-a-new-integration-in-netsuite) from your NetSuite account;
* **NetSuite Token Id:** the [token ID](/integrations/accounting/netsuite#create-a-new-access-token-in-netsuite) from your NetSuite account;
* **NetSuite Token Secret:** the [token secret](/integrations/accounting/netsuite#create-a-new-access-token-in-netsuite) from your NetSuite account;
* **Custom RESTlet Endpoint:** The endpoint created from the [custom RESTlet script](/integrations/accounting/netsuite#restlet-script-configuration).
### Enable actions and syncs
Here is a list of syncs and actions that Lago uses with NetSuite. Some are mandatory, while others are optional:
* `Customers`: Syncs or fetch customer data from NetSuite Customers *(mandatory)*;
* `Invoices`: Syncs invoice data to NetSuite Invoices *(optional)*;
* `Credit Notes`: Syncs credit note data to NetSuite Credit Memos *(optional)*; and
* `Payments`: Syncs payment data to NetSuite Customer Payments *(optional)*.
## Mapping items between Lago and NetSuite
**Mapping between Lago and NetSuite is done by Lago Entity → NetSuite Subsidiary**. You can define a
default mapping that applies across all subsidiaries, but a single item (including tax items)
can be mapped differently for each subsidiary. When a mapping is defined for a specific Lago
entity, that entity-specific mapping overrides the default mapping for the corresponding
NetSuite subsidiary. If all your entities share the same mapping, you only need to configure
the default mapping.
Follow these steps to map items or tax items between Lago and NetSuite:
1. Navigate to the **NetSuite Integration** page in Lago;
2. Select the **Item Mapping** tab;
3. Click on the item you want to map;
4. Fill all the required fields; and
5. Save your mapping.
The item mapping must be completed before syncing invoices, credit notes, or payments to NetSuite. Anytime a new item is created in Lago, it must be mapped to a NetSuite item to ensure successful synchronization.
### Mapping a fallback item
The fallback item is a dummy item used as a backup in case the mapping of other objects fails.
To ensure continuous data synchronization between Lago and NetSuite, this fallback item will be used whenever there is a mapping issue.
This mapping follows a one-to-many structure, meaning that a single fallback item can be used to handle multiple mapping issues.
### Mapping a tax item
To override the tax amount for an invoice, sales order, or credit note, you need to map a single tax item from NetSuite.
This mapped item will be used to assign the correct tax amount.
**To ensure taxes are sent from Lago to NetSuite, complete the tax mapping** for the following [tax fields you created here](#create-lago-tax-nexus-type-and-code):
1. Tax Nexus;
2. Tax Type; and
3. Tax Code.
Use the `id` for each item, found either in the UI or in the URL of the specific item. You can define a specific tax mapping for each Lago entity or NetSuite Subsidiary.
This mapping follows a one-to-many structure, meaning that a single tax item can be mapped to override all tax amounts issued by Lago.
### Mapping default objects
Coupons, credit notes, subscription fees, minimum commitments, and prepaid credits require a one-to-many mapping.
Each of these objects must be mapped to a single default item from your NetSuite instance. Lago will use this mapped item
whenever any of these objects appear on the final invoice sent to NetSuite. You can override the default mapping for each Lago entity or NetSuite Subsidiary if needed.
This mapping follows a one-to-many structure, meaning a single item can handle multiple mappings for coupons, credit notes, subscription fees, minimum commitments, and prepaid credits.
### Mapping custom objects
Billable metrics and add-ons require a one-to-one mapping. Each billable metric, used for usage-based billing, must represent a specific SKU in your NetSuite instance.
You need to map each of these individually. Lago will use the mapped items whenever any of these metrics or add-ons appear on the final invoice sent to NetSuite.
You can override the default mapping for each Lago entity or NetSuite Subsidiary if needed.
This mapping follows a one-to-one structure, meaning each billable metric or add-on must be mapped to a specific NetSuite item.
## Mapping currencies between Lago and NetSuite
As NetSuite supports multiple currencies for a single customer, it's essential to map the currencies used in Lago to those in NetSuite.
This ensures that all financial data is accurately represented and synchronized between the two systems. To map currencies, follow these steps:
1. Navigate to the **NetSuite Integration** page in Lago;
2. Select the **Currency Mapping** tab;
3. Click the **Add Currency mapping** button; and
4. Map the Lago currency code with the currency ID used in NetSuite.
## Customers synchronization
When creating or updating a Lago customer, you can choose to link it to a NetSuite customer.
The first option is to **automatically create a new customer from Lago to NetSuite**. Follow these steps:
1. Create or update a new Lago customer;
2. Select the targeted NetSuite connection;
3. Check the box labeled 'Create this customer automatically in NetSuite';
4. Choose a NetSuite subsidiary from the list (Lago will fetch the list of subsidiaries from your NetSuite instance); and
5. Save and create this new customer.
If the customer is successfully created in NetSuite, a new field will be displayed in the Lago customer view, providing a direct link to the corresponding NetSuite customer.
Customer creation from Lago to NetSuite happens in real-time with only a few seconds of delay.
The second option is to **import an existing NetSuite customer to a Lago customer**. Follow these steps:
1. Create or update a Lago customer;
2. Select the targeted NetSuite connection;
3. Ensure the box labeled 'Create this customer automatically in NetSuite' is unchecked;
4. Paste the NetSuite customer ID in the appropriate field; and
5. Save and create this new customer.
## Invoices synchronization
If a Lago customer is linked to a NetSuite customer, Lago syncs invoices to NetSuite Invoices in real-time.
It's important to note the following:
* Each fee issued by Lago is synced as a line item on a NetSuite invoice;
* The Lago fee `units` are synced to NetSuite as `quantity`;
* The Lago fee `precise_unit_amount` is synced to NetSuite as `rate`;
* Lago overrides the total tax amount of a NetSuite invoice using the tax item, as NetSuite does not support tax details at the line item level; and
* Any discounts on an invoice (coupon, credit note, or prepaid credits) are synced as negative line items on the NetSuite invoice.
If the invoice is successfully created in NetSuite, a new field will be displayed in the Lago invoice view, providing a direct link to the corresponding NetSuite invoice.
Invoice creation from Lago to NetSuite happens in real-time with only a few seconds of delay.
## Credit Notes synchronization
If a Lago customer is linked to a NetSuite customer, Lago syncs credit notes to NetSuite Credit Memos in real-time.
It's important to note the following:
* Each fee refunded by Lago is synced as a line item on a NetSuite Credit Memo;
* Lago overrides the total tax amount of a NetSuite credit memo using the tax item, as NetSuite does not support tax details at the line item level; and
* Any discounts on an credit note (like coupon, for instance) are synced as line items on the NetSuite Credit Memo.
If the credit note is successfully created in NetSuite, a new field will be displayed in the Lago credit note view, providing a direct link to the corresponding NetSuite Credit Memo.
Credit note creation from Lago to NetSuite happens in real-time with only a few seconds of delay.
## Payments synchronization
If a Lago invoice is tied to a NetSuite invoice, Lago automatically syncs payments occurring in Lago to NetSuite, updating in-real time the payment status of the invoice in NetSuite.
You can also retrieve payments for invoices paid directly in NetSuite.
## Integration logs
Whenever an issue occurs in NetSuite, Lago will notify you through a [webhook message](/api-reference/webhooks/messages#accounting-provider-error) called `customer.accounting_provider_error`.
You can also **view integration logs inside NetSuite** for troubleshooting and auditing purposes.
# QuickBooks
Source: https://getlago.com/docs/integrations/accounting/quickbooks
Sync Lago billing data to QuickBooks Online via n8n.
**Community maintained**: This integration is built and maintained by the Lago community. It is not an official Lago integration.
## Overview
Sync your Lago billing data to QuickBooks Online automatically using this community-maintained integration.
It uses n8n as middleware to transform Lago webhooks into QuickBooks API calls — so your accounting records stay in sync with your billing, without lifting a finger.
## How it works
The integration uses **[n8n](https://n8n.io/)** (a workflow automation platform) as middleware between Lago and [QuickBooks Online](https://quickbooks.intuit.com/).
**Bring your own n8n** — This integration requires your own [n8n](https://n8n.io/) account (self-hosted or [Cloud](https://n8n.io/cloud/)).
n8n is a third-party service with its own pricing. You are responsible for managing and paying for your instance.
```mermaid theme={"dark"}
graph LR
A[Lago Billing] -->|Webhooks HMAC Signed| B[n8n Middleware]
B -->|OAuth2 API REST Calls| C[QuickBooks Online]
```
### What gets synced
| Lago Event | QuickBooks Action | Description |
| -------------------------------- | ----------------------------- | -------------------------------------------- |
| `customer.created` | Create/Update Customer | Creates customer record with billing details |
| `customer.updated` | Update Customer | Updates existing customer information |
| `invoice.created` | Create Invoice | Creates invoice with line items and taxes |
| `invoice.one_off_created` | Create Invoice | Creates one-off invoice |
| `credit_note.created` | Create Credit Memo | Creates credit memo for refunds/adjustments |
| `invoice.payment_status_updated` | Create Payment (if succeeded) | Records successful payments |
| `invoice.voided` | Void Invoice | Voids invoice in QuickBooks |
### Key features
Creates QuickBooks customers on-the-fly when processing invoices.
Uses Lago's tax calculations instead of QuickBooks tax rates.
Checks for existing records before creating new ones.
Map Lago item codes to QuickBooks products/services.
Handle high-volume invoice creation with concurrency control.
Automatic retries with exponential backoff for transient failures.
## Prerequisites
1. **Lago account** with API and webhook endpoints access
2. **QuickBooks Online account** (Essentials, Plus, or Advanced)
3. **n8n instance** — [n8n Cloud](https://n8n.io/cloud/) or [self-hosted](https://docs.n8n.io/hosting/)
1. Create a [QuickBooks Developer account](https://developer.intuit.com/)
2. Create a new app in the Developer Portal
3. Note your **Client ID** and **Client Secret**
4. Set the OAuth2 redirect URI to `https://your-n8n-instance.com/rest/oauth2-credential/callback`
* n8n version **0.235.0** or higher
* HTTPS endpoint for webhook receiver (required for production)
* QuickBooks Online API access (included with QB Online subscriptions)
## Installation
1. Download `lago-quickbooks-main.json` from the [GitHub repository](https://github.com/getlago/lago-quickbooks-integration)
2. In n8n, go to **Workflows** → **Add workflow**
3. Click the **⋮** menu → **Import from file**
4. Select the downloaded file and click **Import**
1. In n8n, go to **Workflows** → **Add workflow**
2. Click **Import from URL**
3. Enter: `https://raw.githubusercontent.com/getlago/lago-quickbooks-integration/main/lago-quickbooks-main.json`
4. Click **Import**
The workflow will be created with 47 nodes pre-configured.
1. In n8n, click **+** → **Credentials** → **Add credential**
2. Search for **QuickBooks OAuth2 API**
3. Fill in the details:
| Field | Value |
| ------------------- | ---------------------------------------------------------------- |
| **Credential name** | `QuickBooks OAuth2` |
| **Client ID** | From QuickBooks Developer Portal → Your App → Keys & credentials |
| **Client Secret** | From QuickBooks Developer Portal → Your App → Keys & credentials |
| **Environment** | `sandbox` for testing, `production` for live data |
| **Scope** | `com.intuit.quickbooks.accounting` |
4. Click **Connect my account**, authorize in QuickBooks, then **Save**
The workflow expects the credential to be named **exactly** `QuickBooks OAuth2`. All 14 QuickBooks nodes reference it by name — use a different name and you'll need to update each one manually.
The workflow has two configuration nodes.
#### HMAC Signature node
Open the **Verify HMAC Signature** node and edit the `CONFIG` object:
```javascript theme={"dark"}
const CONFIG = {
LAGO_WEBHOOK_SECRET: 'your_lago_webhook_secret_here', // REQUIRED
BYPASS_SIGNATURE: true, // Set to false in production
QB_ENVIRONMENT: 'sandbox', // REQUIRED: 'sandbox' or 'production'
QB_REALM_ID: 'your_quickbooks_company_id', // REQUIRED
QB_DEFAULT_ITEM_ID: '1', // REQUIRED: Fallback QB Item ID
QB_DISCOUNT_ACCOUNT_ID: '1' // QB Account ID for discounts
};
```
| Field | Required | Description |
| ------------------------ | -------- | -------------------------------------------------------------- |
| `LAGO_WEBHOOK_SECRET` | Yes | From Lago → Settings → Webhooks → Secret |
| `QB_ENVIRONMENT` | Yes | `sandbox` for testing, `production` for live |
| `QB_REALM_ID` | Yes | Your QuickBooks company ID (see below) |
| `QB_DEFAULT_ITEM_ID` | Yes | Default QuickBooks Item ID — see [Item mapping](#item-mapping) |
| `QB_DISCOUNT_ACCOUNT_ID` | No | Account ID for discounts/credits |
| `BYPASS_SIGNATURE` | No | Skip signature verification (dev only) |
Log into QuickBooks Online and look at the URL:
`https://app.qbo.intuit.com/app/homepage?realmId=123456789`
The number after `realmId=` is your Realm ID. Alternatively, use the [API Explorer](https://developer.intuit.com/app/developer/qbo/docs/api/accounting/most-commonly-used/companyinfo) and look for `CompanyInfo.Id`.
Go to QuickBooks → **Settings** → **Products and Services**, click an item, and grab the ID from the URL:
`https://qbo.intuit.com/app/item?id=1` — here, the Item ID is `1`.
#### Item Mappings Config node
Open the **Item Mappings Config** node and edit the `MAPPINGS` object:
```javascript theme={"dark"}
const MAPPINGS = {
ITEM_MAPPINGS: {
// 'startup_plan': '5',
// 'premium_plan': '12',
},
ITEM_FALLBACK_ID: '1', // REQUIRED: Same as QB_DEFAULT_ITEM_ID
QB_TAX_CODE_ID: '', // REQUIRED if you charge tax
DISCOUNT_MAPPINGS: {},
DISCOUNT_FALLBACK_ACCOUNT_ID: '1'
};
```
See [Item mapping](#item-mapping) and [Tax mapping](#tax-mapping) below for details.
1. In n8n, open the workflow and click the **Lago Webhook Receiver** node
2. Copy the **Production URL** (e.g., `https://your-n8n.com/webhook/lago-webhook`)
For production, you need an HTTPS webhook URL. n8n Cloud provides this automatically. For self-hosted n8n, ensure your instance is accessible via HTTPS.
1. In Lago, go to **Settings** → **Webhooks** → **Add a webhook endpoint**
2. Paste the n8n webhook URL from the previous step
3. Enable **HMAC signature** (strongly recommended)
4. Copy the **Signature secret** and paste it into the `LAGO_WEBHOOK_SECRET` field in n8n
5. Set `BYPASS_SIGNATURE: false` for production
In n8n, toggle the workflow to **Active** (top right). Done — the workflow is now listening for Lago webhooks.
## Item mapping
Item mapping connects Lago billing items to QuickBooks products/services, so you can track revenue by product line.
When Lago sends an invoice, each fee includes an `item.code` (e.g., `"premium_plan"`). The workflow looks it up in `ITEM_MAPPINGS` and uses the matched QuickBooks Item ID — or falls back to `ITEM_FALLBACK_ID` if there's no match.
Go to QuickBooks → **Settings** → **Products and Services**, click an item, and note the ID from the URL.
In Lago, check **Billable metrics** and **Plans** for the `code` field on each item.
Edit the **Item Mappings Config** node in n8n:
```javascript theme={"dark"}
ITEM_MAPPINGS: {
'startup_monthly': '10', // QB: "Subscription Revenue"
'premium_monthly': '10', // QB: "Subscription Revenue"
'api_calls': '20', // QB: "Usage Revenue"
'storage_gb': '20', // QB: "Usage Revenue"
'onboarding_fee': '30', // QB: "Professional Services"
},
ITEM_FALLBACK_ID: '1', // QB: "Services" (for unmapped items)
```
**Keep it simple** — You can map everything to a single QB item, group items by category, or go one-to-one. Pick the granularity that matches your accounting needs.
## Tax mapping
The integration uses QuickBooks' **tax override** feature — Lago's exact tax amounts show up in QuickBooks, regardless of QB's own tax rates. No recalculation, no rounding surprises.
Under the hood:
* Line items are marked `TAX` or `NON` based on Lago data
* The exact tax total from Lago is set via `TxnTaxDetail.TotalTax`
* The API uses `minorversion=70` to enable the override
Use the [API Explorer](https://developer.intuit.com/app/developer/qbo/docs/api/accounting/all-entities/taxcode) to query:
```sql theme={"dark"}
SELECT Id, Name FROM TaxCode WHERE Active = true
```
Use the ID of the **taxable** code (e.g., `"TAX"` → `Id: "2"`), **not** `"NON"`.
In the **Item Mappings Config** node:
```javascript theme={"dark"}
QB_TAX_CODE_ID: '2', // Your taxable code ID. Leave empty if no tax.
```
Create a test invoice with tax in Lago and verify the exact amounts match in QuickBooks.
**Tax amount doesn't match** — Verify `QB_TAX_CODE_ID` is set and points to a taxable code (not "NON").
**QuickBooks recalculates tax** — Ensure `minorversion=70` is in the API URL. The workflow includes this by default — check the node settings if you've modified things.
## Understanding the flow
### Workflow architecture
```mermaid theme={"dark"}
graph TD
A[Webhook Receiver] --> B[Verify HMAC Signature]
B --> C[Item Mappings Config]
C --> D[Route by Webhook Type]
D --> E[Customer Created]
D --> F[Customer Updated]
D --> G[Invoice Created]
D --> H[Credit Note Created]
D --> I[...]
```
### Event flows
```mermaid theme={"dark"}
graph LR
A[Transform Customer Data] --> B[Lookup Customer in QB] --> C[Prepare Upsert] --> D[Create/Update Customer]
```
Deduplicates by `DisplayName` — updates if found, creates if not.
```mermaid theme={"dark"}
graph LR
A[Transform Invoice] --> B[Map Items] --> C[Lookup Customer]
C -->|Not found| D[Create Customer] --> E[Finalize Invoice]
C -->|Found| E
E --> F[Lookup Invoice]
F -->|Exists| G[Skip - duplicate]
F -->|Not found| H[Create Invoice in QB]
```
Auto-creates missing customers and prevents duplicates by checking `DocNumber`.
Same flow as Invoice Created, but creates a **Credit Memo** in QB.
```mermaid theme={"dark"}
graph LR
A[Extract Payment Info] --> B[Lookup Invoice in QB] --> C[Check Status]
C -->|Succeeded| D[Create Payment]
C -->|Other| E[Log status only]
```
Only `succeeded` creates a QB Payment. Other statuses are logged and skipped.
```mermaid theme={"dark"}
graph LR
A[Extract Invoice Info] --> B[Lookup Invoice in QB] --> C[Void Invoice in QB]
```
### Error handling
All QB API calls retry up to 5 times with exponential backoff.
1-second wait between API calls to stay within QB limits.
Lookups before creation prevent duplicate records.
Auto-created when processing invoices or credit notes.
**Monitoring** — In n8n, go to **Executions** to view all workflow runs. Click any execution to see detailed logs per node.
## Scaling
| Limit | Value |
| ------------------- | ----- |
| Requests per minute | 500 |
| Concurrent requests | 10 |
| Per-second limit | 10 |
For n8n self-hosted, set the concurrency limit:
```bash theme={"dark"}
N8N_CONCURRENCY_PRODUCTION_LIMIT=10
```
n8n Cloud manages concurrency automatically. Incoming webhooks are queued in memory (FIFO) and processed within the concurrency limit.
| Scenario | Throughput | Time for 10k invoices |
| ----------------------- | ---------- | --------------------- |
| Default (10 concurrent) | \~100/min | \~100 minutes |
| Optimized (parallel) | \~300/min | \~33 minutes |
For **10,000+ invoices per day**, consider separating workflows, using Redis-backed queues, or reaching out at [support@getlago.com](mailto:support@getlago.com).
## Testing
Always test in QuickBooks Sandbox (`QB_ENVIRONMENT: 'sandbox'`) before going to production.
### Checklist
* [ ] **Customer sync**: Create/update customer in Lago → verify in QB
* [ ] **Invoice creation**: Create invoice in Lago → verify items and tax in QB
* [ ] **Credit note**: Create credit note → verify credit memo in QB
* [ ] **Payment**: Mark invoice as paid → verify payment in QB
* [ ] **Duplicate prevention**: Send same invoice twice → only one in QB
* [ ] **Tax calculation**: Tax amount in QB matches Lago exactly
* [ ] **Item mapping**: Correct QB items are used
### Troubleshooting
* Check the webhook URL in Lago settings
* Verify the workflow is **Active** in n8n
* Check n8n firewall/network settings
* Verify `LAGO_WEBHOOK_SECRET` matches Lago exactly
* Check for extra spaces when copying the secret
* Re-authorize the OAuth2 credential in n8n
* Verify Client ID and Secret are correct
* Check `QB_TAX_CODE_ID` is set and points to a taxable code (not "NON")
* Verify `minorversion=70` is in the API URL (included by default)
## Production checklist
Before going live:
* [ ] `QB_ENVIRONMENT` set to `production`
* [ ] `BYPASS_SIGNATURE` set to `false`
* [ ] `QB_REALM_ID` matches your production company
* [ ] Item mappings configured and tested
* [ ] `QB_TAX_CODE_ID` configured (if using tax)
* [ ] QuickBooks OAuth2 credential authorized for production
* [ ] Lago webhook endpoint configured with HMAC enabled
* [ ] n8n workflow set to **Active**
* [ ] Error notifications configured (email/Slack)
## Support and resources
Source code, issues, and contributions.
Join the Slack community or email [success@getlago.com](mailto:success@getlago.com).
Official n8n docs for workflow and hosting setup.
QuickBooks Online API reference.
# Xero
Source: https://getlago.com/docs/integrations/accounting/xero
Lago seamlessly integrates with Xero, enabling real-time synchronization of billing data with your preferred accounting tool.
**PREMIUM ADD-ON** ✨
This integration is available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium integration.
## Connecting Lago to Xero
To fully integrate Lago with Xero, start by connecting your Lago instance to a new Xero connection.
You can have an unlimited number of Xero connections. First, link your Xero account to Lago.
Once connected, activate the specific syncs and actions required for your use case.
This ensures that your Lago instance is properly configured to communicate with Xero, enabling seamless data synchronization and management.
1. In Lago, navigate to **Integrations > Xero**;
2. Create a **new Xero connection**;
3. Assign a unique **name** and **code** to the connection; and
4. Use OAuth2 to **grant access** to your Xero instance.
There you go, Lago is fully connected to Xero!
## Enable actions and syncs
Here is a list of syncs and actions that Lago uses with Xero. Some are mandatory, while others are optional:
* `Accounts`: Fetch account data from Xero *(mandatory)*;
* `Customers`: Syncs or fetch customer data from Xero *(mandatory)*;
* `Items`: Fetch item data from Xero *(mandatory)*;
* `Invoices`: Syncs invoice data to Xero *(mandatory)*;
* `Credit Notes`: Syncs credit note data to Xero *(optional)*; and
* `Payments`: Syncs payment data to Xero *(optional)*.
## Mapping items between Lago and Xero
To sync invoices, credit notes and payments to Xero, Lago maps each Lago object to a corresponding Xero object (one-to-one). You can define mappings per Lago entity when different entities require distinct Xero items. If the same mapping applies across entities, configure a default mapping. It will be used for any entity that doesn't have a specific override.
Follow these steps to map an item:
* **Access a Xero Connection in Lago:** navigate to your connected Xero integration within the Lago platform;
* **Select the Item to map:** click on the specific item in Lago that you wish to map to a corresponding Xero item;
* **Fetch Items from Xero:** Lago will automatically retrieve the relevant items from your Xero instance;
* **Map the Item:** choose the appropriate Xero item from the list provided by Lago; and
* **Click 'Save'** to finalize the mapping.
### Mapping a fallback item (mandatory)
The fallback item is a dummy item used as a backup in case the mapping of other objects fails.
To ensure continuous data synchronization between Lago and Xero, this fallback item will be used whenever there is a mapping issue.
This mapping follows a one-to-many structure, meaning that a single fallback item can be used to handle multiple mapping issues.
### Mapping a payment account (mandatory)
To synchronize invoice payments between Lago and Xero, ensure that at least one payment account is mapped.
To set up a payment account in Xero, follow these steps:
1. Log in to your Xero instance;
2. Navigate to **Accounting > Chart of Accounts**;
3. Select an existing revenue account or create a new one; and
4. When editing or creating the account, ensure the **'Enable payments to this account'** checkbox is selected.
In Lago, you can now map it in the dedicated section '**Account linked to payments**'.
### Mapping custom objects
Billable metrics and add-ons require a one-to-one mapping. Each billable metric, used for usage-based billing, must represent a specific SKU in your Xero instance.
You need to map each of these individually. Lago will use the mapped items whenever any of these metrics or add-ons appear on the final invoice sent to Xero.
This mapping follows a one-to-one structure, meaning each billable metric or add-on must be mapped to a specific Xero item.
## Customers synchronization
When creating or updating a Lago customer, you can choose to link it to a Xero customer.
The first option is to **automatically create a new customer from Lago to Xero**. Follow these steps:
1. Create or update a new Lago customer;
2. Select the targeted Xero connection;
3. Check the box labeled 'Create this customer automatically in Xero'; and
4. Save and create this new customer.
If the customer is successfully created in Xero, a new field will be displayed in the Lago customer view, providing a direct link to the corresponding Xero customer.
Customer creation from Lago to Xero happens in real-time with only a few seconds of delay.
The second option is to **import an existing Xero customer to a Lago customer**. Follow these steps:
1. Create or update a Lago customer;
2. Select the targeted Xero connection;
3. Ensure the box labeled 'Create this customer automatically in Xero' is unchecked;
4. Paste the Xero customer ID in the appropriate field; and
5. Save and create this new customer.
**Here is the list of fields that is currently synced to Xero:**
| Lago | Xero |
| ------------------------------------ | ------------ |
| customer | type |
| customer.name | Name |
| customer.email | EmailAddress |
| customer.phone | Phones |
| customer.tax\_identification\_number | TaxNumber |
| customer.address\_line\_1 | AddressLine1 |
| customer.address\_line\_2 | AddressLine2 |
| customer.city | City |
| customer.zip | PostalCode |
| customer.country | Country |
| customer.state | Region |
## Invoices synchronization
If a Lago customer is linked to a Xero customer, Lago syncs invoices to Xero Invoices in real-time.
It's important to note the following:
* Each fee issued by Lago is synced as a line item on a Xero invoice;
* The Lago fee `units` are synced to Xero as `Quantity`;
* The Lago fee `precise_unit_amount` is synced to Xero as `UnitAmount`;
* Lago can send the total tax amount for a specific line item; and
* Lago can apply discount to a specific line item.
If the invoice is successfully created in Xero, a new field will be displayed in the Lago invoice view, providing a direct link to the corresponding Xero invoice.
Invoice creation from Lago to Xero happens in real-time with only a few seconds of delay.
**Here is the list of fields that is currently synced to Xero:**
| Lago | Xero |
| ------------------------------------------- | -------------- |
| invoice | type |
| invoice.number | InvoiceNumber |
| invoice.status | Status |
| invoice.currency | CurrencyCode |
| invoice.issuing\_date | Date |
| invoice.payment\_due\_date | DueDate |
| invoice.fee.units | Quantity |
| invoice.fee.precise\_unit\_amount | UnitAmount |
| invoice.fee.amount\_cents | LineAmount |
| invoice.fee.taxes\_amount\_cents | TaxAmount |
| invoice.fee.precise\_coupons\_amount\_cents | DiscountAmount |
## Credit Notes synchronization
If a Lago customer is linked to a Xero customer, Lago syncs credit notes to Xero Credit Notes in real-time.
It's important to note the following:
* Each fee refunded by Lago is synced as a line item on a Xero Credit Note; and
* Any discounts on an credit note (like coupon, for instance) are synced as line items on the Xero Credit Note.
If the credit note is successfully created in Xero, a new field will be displayed in the Lago credit note view, providing a direct link to the corresponding Xero Credit Note.
Credit note creation from Lago to Xero happens in real-time with only a few seconds of delay.
**Here is the list of fields that is currently synced to Xero:**
| Lago | Xero |
| --------------------------------------------- | ---------------- |
| credit\_note.number | CreditNoteNumber |
| credit\_note.reference | Reference |
| credit\_note.status | Status |
| credit\_note.currency | CurrencyCode |
| credit\_note.issuing\_date | Date |
| credit\_note.line\_item.units | Quantity |
| credit\_note.line\_item.precise\_unit\_amount | UnitAmount |
| credit\_note.line\_item.amount\_cents | LineAmount |
| credit\_note.line\_item.taxes\_amount\_cents | TaxAmount |
## Payments synchronization
If a Lago invoice is tied to a Xero invoice, Lago automatically syncs payments occurring in Lago to Xero, updating in-real time the payment status of the invoice in Xero.
| Lago | Xero |
| --------------------- | ------- |
| invoice.id | Invoice |
| invoice.amount\_cents | Amount |
## Integration logs
Whenever an issue occurs in Xero, Lago will notify you through a [webhook message](/api-reference/webhooks/messages#accounting-provider-error) called `customer.accounting_provider_error`.
# N8N
Source: https://getlago.com/docs/integrations/alerting/n8n
Here is a typical use case of using Lago and N8N to create powerful alerting automation.
## Overconsumption Alerting Example (with N8N)
When one of your customers is overconsuming during a period, you might need to warn her. This might happen for Cloud or API products. Automatic billing does not mean that your customers should have a bad surprise when opening their invoices.
Here is a full workflow to create an alerting system based on your customers' current usage, using [N8N](https://n8n.io/), a powerful automation tool for developers.
In this example, we are going to build an alert anytime a usage threshold is overcome. Here is a summary of this workflow:
1. Use a **Cron** expression to call the Lago API every X minutes/hours/days
2. Call the [**Current usage**](/api-reference/customer-usage/get-current) endpoint available in Lago to fetch your customers' current usage;
3. Create a **IF statement** to condition the trigger (in our case, messages are triggered above a specific overconsumption); and
4. **Send a message** whenever this threshold is reached. You could use an emailing tool, Slack or a CRM. In our case, we are using Slack.
## 1st Node - CRON expression to repeat tasks at a defined interval
The first node is repeatedly and automatically triggering the automation at a defined interval.
1. Add a new **Node**;
2. Select **CRON** as a new application node;
3. The **Mode** is set to `Every X`; and
4. The **Value** is defined to `10` and the the **Units** to `minutes`.
This will trigger the flow automatically every 10 minutes. You can obviously change the value and the units to your preferred interval.
## 2nd Node - Catch customers' current usage with a HTTP Request
This node is used to fetch current usage from Lago API, using a HTTP request.
1. Add a new **Node**;
2. Select **HTTP Request** as a new application node;
3. Fetch [customers' current usage](/api-reference/customer-usage/get-current) from Lago API;
4. Make sure to set the `API_KEY` and the `Content-Type` as headers of your request; and
5. Execute the node to fetch the payload from Lago's API.
## 3rd Node - IF conditional statement to trigger messages under conditions
This node is used to trigger the alert only when your customers overcome a threshold of usage. Those limits depend on your product and your paying features.
In our present use case, we want to trigger an alert **when the total consumption of usage-based features overcomes \$200**. You could also use the `number of units` consumed or another useful value from the payload.
1. Add a new **Node**;
2. Select **IF** as a new application node;
3. Create a condition for the **TRUE** branch (when conditions are met);
4. The **Value** is the parameter of your condition (in our case the `amount_cents` of the current usage);
5. The **Operation** is the math operation you want to apply (in our case, condition is met when the total `amount_cents` is larger or equal to \$200);
It is important to mention that:
* You can add as many conditions as you need;
* You could add an action when the condition is `FALSE`.
## 4th Node - Send an alert message to Slack
This last node is used to trigger the message. In the example, we use a Slack channel, but you could even decide to send an email directly to your customers when they pass the limits of usage.
1. Add a new **Node**;
2. Select **Slack** as a new application node;
3. Select the targeted **Slack Account** & **Slack Channel**;
4. Choose the option to **POST** a **Message**; and
5. **Define a message** and use the variables of your payload to give context to your customers about their current usage.
On top of connecting your Slack account, don't forget to authorize the application's bot to post messages to the targeted channel.
# Zapier
Source: https://getlago.com/docs/integrations/alerting/zapier
Here is a typical use case of using Lago with Zapier to create powerful alerting automation.
## Invoice Alerting Example (with Zapier)
In this example, we are going to **build an alert anytime a new invoice is emitted**. To create this workflow, we are using:
1. Lago's webhook when a new invoice is emitted;
2. Zapier as an automation tool, to catch, tranform and send the data; and
3. Slack as the "receiver" to alert your team anytime a new invoice is created.
## 1. Catch a webhook when a new invoice is emitted
Lago automatically creates an invoice when a billable period is over. The invoice's payload gives you a detailed view of what has been invoiced. The first action we need to perform is to catch this invoice with a webhook:
1. In Zapier, create a new Zap;
2. Use the **Webhooks by Zapier** as the trigger of this Zap;
3. Select the **Catch Raw Hook** event trigger;
4. Copy the Zapier Webhook URL and paste it in Lago (**Developers** > **Webhooks** > **Add a webhook**); and
5. Catch your first webhook when an invoice is emitted (whenever you assign an add-on or a subscription).
## 2. Run a script to transform the webhook
In Zapier, create a second action by clicking the `+` icon. This new event action is used to format the webhook with a breakdown of fields that can be used in a message.
1. Select **Code by Zapier** as a new *Event Action*;
2. Click on **Javascript** as the event code language to run;
3. Create a field called `payload`. The value of this field is the full **Raw body** of your invoice object received);
4. Run the script (code snippet below) in the **Code** section;
5. Test the action. If valid, it returns a breakdown of fields.
```javascript theme={"dark"}
var obj = JSON.parse(inputData.payload);
if(obj.object_type == "invoice"){
return obj
}
```
## 3. Send a message to a Slack Channel
Once you catch the breakdown of fields returned by the invoice payload, you can easily use them to create a Slack text message.
In Zapier, create a third action by clicking the `+` icon. This new event action is used to send a message to Slack by using the fields of the invoice payload.
1. Select **Slack** as a new app action;
2. Select the **Send Channel Message** action;
3. Choose the targeted **Slack Account**;
4. Choose the targeted **Slack Channel**; and
5. Create a message by using the fields returned by the payload.
By testing and validating the entire Zap, a Slack message is sent anytime a new invoice is emitted by Lago. You can use the same message example as detailed below:
# HubSpot
Source: https://getlago.com/docs/integrations/crm/hubspot
Lago syncs billing data to HubSpot in real-time.
**PREMIUM ADD-ON** ✨
This integration is only available to users with a specific paying add-on. Please
**[contact us](mailto:hello@getlago.com)** to get access to HubSpot CRM integration.
This integration is a one-way sync, where Lago continuously syncs billing data to HubSpot in real time.
Currently, it doesn’t support fetching information or taking actions from HubSpot back to Lago.
## Object mapping
As Lago needs to sync billing data to HubSpot custom objects, your HubSpot account needs to be on the **Sales Hub Enterprise** plan.
## Integration configuration
### oAuth connection
To fully integrate Lago with HubSpot, start by connecting your Lago instance to a new HubSpot connection. You can have an unlimited number of HubSpot connections. First, link your HubSpot account to Lago. Once connected, activate the specific syncs and actions required for your use case. This ensures that your Lago instance is properly configured to communicate with HubSpot, enabling seamless data synchronization and management.
1. In Lago, navigate to **Integrations** > **HubSpot**;
2. Create a **new HubSpot connection**;
3. Assign a unique **name** and **code** to the connection;
4. Select the **default targeted object** for Lago customers between HubSpot Contacts or Companies; and
5. Use OAuth2 to grant access to the desired HubSpot account.
There you go, Lago is fully connected to HubSpot!
### List of scopes
Here's a list of scopes you grant to Lago when connecting your HubSpot instance: `oauth`, `crm.objects.companies.read`, `crm.objects.companies.write`,
`crm.objects.custom.read`, `crm.objects.custom.write`, `crm.schemas.companies.read`, `crm.schemas.companies.write`, `crm.schemas.custom.read`,
`crm.objects.contacts.read`, `crm.objects.contacts.write`, `crm.schemas.contacts.read`, `crm.schemas.contacts.write` and `crm.schemas.custom.write`.
### Custom properties deployment
By connecting HubSpot to Lago, **custom properties are automatically added to both your HubSpot Companies and Contacts** (native objects).
These fields are used to sync customer data between HubSpot and Lago.
* `lago_customer_id`: internal id of a Lago customer (unique);
* `lago_customer_external_id`: your customer's external id in Lago;
* `lago_billing_email`: your customer's billing email in Lago;
* `lago_tax_identification_number`: your customer's tax identification number in Lago; and
* `lago_customer_link`: the URL path to the related Lago customer.
Note that custom properties are deployed in the background the first time the connection is created.
### Custom objects deployment
By connecting HubSpot to Lago, 2 custom objects are automatically deployed to your HubSpot instance: `LagoSubscriptions` and `LagoInvoices`.
Note that custom objects are deployed in the background the first time the connection is created. They are automatically tied to HubSpot Contacts or Companies.
#### LagoSubscriptions
Here is the list of properties deployed with the `LagoSubscriptions` custom object:
| HubSpot Property Name | Type | Field Type | Has Unique Value |
| -------------------------------- | ----------- | ---------- | ---------------- |
| Lago Subscription Id | string | text | true |
| Lago External Subscription Id | string | text | false |
| Lago Subscription Name | string | text | false |
| Lago Subscription Plan Code | string | text | false |
| Lago Subscription Status | string | text | false |
| Lago Subscription Created At | date | date | false |
| Lago Subscription Started At | date | date | false |
| Lago Subscription Ending At | date | date | false |
| Lago Subscription At | date | date | false |
| Lago Subscription Terminated At | date | date | false |
| Lago Subscription Trial Ended At | date | date | false |
| Lago Subscription Link | string | file | false |
| Lago Billing Time | enumeration | radio | false |
#### LagoInvoices
Here is the list of properties deployed with the `LagoInvoices` custom object:
| HubSpot Property Name | Type | Field Type | Has Unique Value |
| ------------------------------------- | ------ | --------------- | ---------------- |
| Lago Invoice Id | string | text | true |
| Lago Invoice Number | string | text | false |
| Lago Invoice Issuing Date | date | date | false |
| Lago Invoice Payment Due Date | date | date | false |
| Lago Invoice Payment Overdue | bool | booleancheckbox | false |
| Lago Invoice Type | string | text | false |
| Lago Invoice Status | string | text | false |
| Lago Invoice Payment Status | string | text | false |
| Lago Invoice Currency | string | text | false |
| Lago Invoice Total Amount | number | number | false |
| Lago Invoice Subtotal Excluding Taxes | number | number | false |
| Lago Invoice File URL | string | file | false |
| Lago Invoice Link | string | file | false |
## Sync data from Lago to HubSpot
### Sync customers to HubSpot
When you create or update a customer in Lago, the information is synced in real time to your HubSpot account. Please note the following:
* If `customer.customer_type` in Lago is `company`, the data is synced as a HubSpot Company record.
* If `customer.customer_type` in Lago is `individual`, the data is synced as a HubSpot Contact record.
* If `customer.customer_type` is undefined, the data is synced using the default Customer Object set at the connection level.
You can instruct Lago to automatically create a new Company or Contact in your HubSpot account, or link an existing one by pasting a HubSpot ID into the corresponding Lago customer record.
### Sync subscriptions to HubSpot
Whenever a Lago customer is linked to a HubSpot Contact or Company, **Lago Subscriptions are automatically synced in real-time with the `LagoSubscriptions` object in HubSpot**.
The subscription record is then automatically associated with the corresponding Contact or Company in HubSpot.
### Sync invoices to HubSpot
Whenever a Lago customer is linked to a HubSpot Contact or Company, **Lago Invoices are automatically synced in real-time with the `LagoInvoices` object in HubSpot**.
The invoice record is then automatically associated with the corresponding Contact or Company in HubSpot.
# Salesforce CPQ
Source: https://getlago.com/docs/integrations/crm/salesforce-cpq
Lago syncs billing data to Salesforce in real-time.
**PREMIUM ADD-ON** ✨
This integration is only available to users with a specific paying add-on. Please
**[contact us](mailto:hello@getlago.com)** to get access to Salesforce CPQ integration.
This is extension package of the base package: Lago for Salesforce CRM. Base package must be installed to install CPQ package.
## Object mapping
## Pre-requisite:
* Salesforce CPQ (> Summer '19)
* Install Lago For Salesforce CRM Package [Lago Base Package](/integrations/crm/salesforce-crm)
## I. Integration configuration
### Install Salesforce CRM Package and complete Integration configuration step
* [Integration configuration ](/integrations/crm/salesforce-crm#install-salesforce-crm-package)
* [Establish and finalize connection](/integrations/crm/salesforce-crm#establish-and-finalize-connection)
### Install Salesforce CPQ Package
To gain premium access to our Salesforce Package application, please don't hesitate to contact us.
You can initiate the installation process **by clicking on the provided link**, which will direct you to the installation
page where you can follow step-by-step instructions for a seamless integration. If you have any questions or need assistance
during the installation, our dedicated support team is here to help you every step of the way.
To ensure a successful installation, please follow these steps:
1. We recommend selecting the **"Install for all users"** option;
2. Click on the **"Install" button**;
3. Make sure to **check the box to grant access to these third-party websites**; and
4. Once completed, you'll have **successfully installed** the Lago Salesforce App.
Please note that the installation process may take a few minutes to complete.
However, rest assured that you will receive an email confirmation once the installation is finished.
*
## II. Configuration to sync data
### Assign Permission:
Assign `Lago CPQ Permission` to users who needs to access Lago for Salesforce CPQ.
### Include Lago Fields in 'Quote Line Items editor' layout
Update the "Edit Line" which is available in Quote Layout to enter the details related to lago fieds in QuoteLine by following below steps:
1. Go to Setup
2. Click on Object manager
3. Go to `Quote Line` object
4. Click on \`field sets.
5. Select edit 'Line Editor\` field set.
6 Make sure following fields are available in field set:
* Lago Name
* Lago External Id
* Lago Billing Time
* Lago Start Date
* Lago End Date
## III. Actions from Salesforce to Lago
Beyond just syncing data from Lago to Salesforce, you can also initiate actions in Lago directly from Salesforce.
You can leverage Salesforce `Flows` to execute actions in Lago. Lago provides customizable templates for creating subscription from Salesforce Accounts, directly assigning subscriptions to customers from Salesforce, creating one-off invoice from salesforce.
### Create customers [from Lago to Salesforce CRM](/integrations/crm/salesforce-crm#flow-lago-template-create-customer-in-lago-on-account-create)
### Create subscriptions (automation)
Assigning a plan to a customer, adjusting negotiated prices, and initiating the subscription upon accepting a quote represents a key action from Salesforce to Lago.
To assign a subscription and set prices in Lago directly from Salesforce, use the provided two flows via following Lago Flow templates.
#### Flow 1: `LagoCPQ Template - Quote Line After Insert`
This Flow is used to update Subscription External Id if it is null
1. Log into your Salesforce instance;
2. Access the Setup section via the settings gear icon in Salesforce;
3. Find and select `Flows` under Process Automation in the sidebar;
4. Locate and open the `LagoCPQ Template - Quote Line After Insert`;
5. Click 'Save As' to create and save your own version of the template; and
6. Do not forget to click the `Activate` button to activate your flow.
The default setting triggers plan assignment when Lago subscription external id is null You can customize this flow to suit your specific needs.
#### Flow 2: Pre-requisite from Lago to Salesforce CRM package: `Lago Template - Create Subscription in Lago on Subscription Creation/Update`
This Flow is used to create subscriptions in Lago from Salesforce
1. Log into your Salesforce instance;
2. Access the Setup section via the settings gear icon in Salesforce;
3. Find and select `Flows` under Process Automation in the sidebar;
4. Locate and open the `Lago Template - Create Subscription in Lago on Subscription Creation/Update`;
5. Click 'Save As' to create and save your own version of the template; and
6. Do not forget to click the `Activate` button to activate your flow.
The default setting triggers plan assignment when `SyncToLago` checkbox is checked. You can customize this flow to suit your specific needs.
#### Flow 3: `LagoCPQ Template - Create Lago SObject Records Using Quotes`
This Flow is used to create Lago subscriptions records in Salesforce when Quote status is changed to Approved
1. Log into your Salesforce instance;
2. Access the Setup section via the settings gear icon in Salesforce;
3. Find and select `Flows` under Process Automation in the sidebar;
4. Locate and open the `LagoCPQ Template - Create Lago SObject Records Using Quotes`;
5. Click 'Save As' to create and save your own version of the template; and
6. Do not forget to click the `Activate` button to activate your flow.
The default setting triggers plan assignment when Quote status is changed to Approved. You can customize this flow to suit your specific needs.
### Terminate Subscription
We can terminate the subscription from Salesforce to lago only if the subscription is already synced to lago(status is *active* or *pending*).
Go to Lago Subscription record in Salesforce, and check `Terminate Subscription` checkbox.
As soon as `Terminate Subscription` is checked it will terminate the subscription in Lago. It is handled from the backend via trigger.
## Debugging & logs
To ensure seamless data synchronization between Lago and Salesforce, every action and data transfer is meticulously logged.
These logs are accessible directly through the Lago package for comprehensive debugging and analysis:
1. Navigate to 'Lago Base Configuration': This is your starting point for accessing the debugging tools. and
2. Access Logs: Click on the 'Logs' tab to view a detailed record of all activities.
You can refresh logs to keep your data current or delete unnecessary logs to maintain clarity and efficiency in the debugging process.
This approach aids in promptly identifying and resolving integration issues.
# Salesforce CRM
Source: https://getlago.com/docs/integrations/crm/salesforce-crm
Lago syncs billing data to Salesforce in real-time.
**PREMIUM ADD-ON** ✨
This integration is only available to users with a specific paying add-on. Please
**[contact us](mailto:hello@getlago.com)** to get access to Salesforce CRM integration.
## Object mapping
## I. Integration configuration
### Create integration for Salesforce on Lago Side
To gain premium access to our Salesforce Package application, please don't hesitate to contact us. Login to Lago as admin user, navigate to Settings > Integrations > *Salesforce* (allowed only if team has enabled it for your account), and click "Create new". Enter the following details:
* Name
* Code
* Salesforce Instance (URL of your Salesforce instance)
Make note of the integration code as shown in the connection details - you'll need this later:
### Install Salesforce CRM Package
You can initiate the installation process **by clicking on the provided link**, which will direct you to the installation
page where you can follow step-by-step instructions for a seamless integration. If you have any questions or need assistance
during the installation, our dedicated support team is here to help you every step of the way.
To ensure a successful installation, please follow these steps:
1. We recommend selecting the **"Install for all users"** option;
2. Click on the **"Install" button**;
3. Make sure to **check the box to grant access to these third-party websites**; and
4. Once completed, you'll have **successfully installed** the Lago Salesforce App.
Please note that the installation process may take a few minutes to complete.
However, rest assured that you will receive an email confirmation once the installation is finished.
### Webhook config: sync real-time data
After installation in Salesforce CRM, set up a webhook URL in Salesforce to receive real-time data from Lago.
This involves **configuring a new "Site" in Salesforce's setup section**.
Note that the four main actions described below should be performed by a Salesforce Admin and is only required during the initial setup.
1. Click the gear icon in the upper right to access **Salesforce Setup**;
2. Search and navigate to the Sites section; and
3. Create a new Site (see picture below).
When creating a new site, follow these steps:
1. Set a unique **Site Label**;
2. Specify a unique **Site Name**;
3. Optionally, add a **Site Description**;
4. Ensure the **Site Contact** and **Default Record Owner** are filled;
5. Set the **Default Web Address** prefix to `getPushNotification`;
6. Choose `SiteLogin` as the **Active Site Home Page**; and
7. Don't forget to **save the new site**: and
8. **Activate the newly created site** by going to the Site Details and clicking the `Activate` button.
To edit Public Access Settings for your new Site:
1. Visit the site and click **Public Access Settings**;
2. In the **Enabled Apex Class Access** section, click "edit";
3. Add `LagoWebHookSubscriptionController` to **Enabled Apex Classes**; and
4. Save your changes.
To set up the webhook URL for real-time data syncing between Lago and Salesforce, follow these steps:
1. Return to your newly created site;
2. Locate the **Custom URLs** section;
3. Copy the **domain name** *(e.g., lago.my.salesforce-sites.com)*;
4. Add the `https://` prefix to this domain name (e.g., `https://lago.my.salesforce-sites.com`); and
5. Append `/services/apexrest/lago/api/Webhooks/incoming/pushDetails/` to the domain name (e.g., `https://lago.my.salesforce-sites.com/services/apexrest/lago/api/Webhooks/incoming/pushDetails/`).
Now, go to your Lago app and past this webhook into the webhook’s settings:
1. Within Lago, navigate to **Developers**;
2. Visit the **Webhooks** tab;
3. Choose `HMAC` as the **mandatory signature type**;
4. Paste your Salesforce webhook URL; and
5. Save this webhook endpoint.
Congratulations! You're ready to sync real-time data from Lago to Salesforce! 🎉
### Establish and finalize connection
**Option 1: Configure a standard API Base URL**
To establish a connection between your Lago instance and the Salesforce Package, follow these steps:
1. Access Salesforce and locate the **App Launcher**;
2. Find and open the Lago app you recently installed;
3. Within the Lago Base Configuration tab:
* Provide your **Lago API Key** (located in Lago's Developer Section)
* Enter your Lago **API base URL**. Do not insert the `api/v1` at the end of the URL. By default, the valid URL is `https://api.getlago.com/`.
If you want to change the API base URL to another one (e.g., `https://api.eu.getlago.com/` or a custom self-hosted one), please follow option 2.
* Enter lago app URL (**Front End Base URL**). By default, the valid URL is `https://app.getlago.com/` (it will be different for self-hosted).
* Enter Lago Integration code from Step 1 [`Salesforce integration on Lago`](/integrations/crm/salesforce-crm#create-integration-for-salesforce-on-lago-side)
4. **"Save and validate"** your connection; and
* If the **Lago API Key** is valid then only **Start Data Sync** button will be enabled.
5. Click the **"Start Data Sync"** to finalize the connection between Lago and Salesforce.
Please note that data synchronization is available only for Lago customers with an `external_salesforce_id` and an existing Salesforce Account.
**Option 2: Configure a custom API Base URL**
If you use your own Lago API base URL (self-hosting) or one for a different server instance,
you can customize it directly in Salesforce:
1. Navigate to Salesforce's Setup;
2. Search for and select Remote Site Settings;
3. Find and access the remote site for the Lago App;
4. Click the Edit button to modify the remote site's details;
5. Update the Remote Site URL with your preferred URL; and
6. Save the changes.
## II. Sync data from Lago to Salesforce
If your webhook endpoint is configured correctly, your *customer, subbscription, and billing data will flow seamlessly in real-time*\*.
Please note that from all the version above Salesforce for Lago v2.7 - Customer, Subscriptions, and Invoices will be created in Salesforce via webhooks seamlessly
### Sync customers to Salesforce (> v2.7)
For organizations with existing Lago customers that need to be synchronized with Salesforce, our support team provides specialized assistance with the migration process. Please contact our team to initiate this synchronization.
To establish a new customer connection between Lago and Salesforce, follow these steps:
1. Navigate to the customer creation screen in Lago
2. Complete the standard customer information fields
3. Expand the 'Connect to external apps' section at the bottom of the form
4. Select Salesforce and choose the integration established during the initial setup
5. Choose the appropriate synchronization method:
* For new Salesforce customers: Enable the Create automatically this customer option
* For existing Salesforce customers: Enter the corresponding 'Salesforce Account ID'
The system handles account creation in Salesforce based on your configuration:
For Salesforce instances with Person Accounts enabled:
When `Customer Type` is set to \`Individual1: Creates a Person Record type account.
When `Customer Type` is `Company` or unspecified: Creates a standard company account using the default record type for the running user
For Salesforce instances without Person Accounts:
Creates all accounts using the default record type associated with the running user
Important considerations for customer record management:
Synchronized customer records have specific update restrictions in Salesforce to maintain data integrity
When using the Lago Integration Code (available for >= v2.7):
The system sets `sync_with_provider` to `true`.
This setting allows future updates from lago in Salesforce.
Without the Lago Integration Code (for \< v2.7):
We don't keep the data in sync from lago to Salesforce. Only initial sync is avaialble from lago to Salesforce, check below section.
### Sync customers to Salesforce (\< v2.7)
To synchronize Lago Customer data with Salesforce Accounts (native object), ensure that your
Salesforce Account is created first, and that the Lago Customer's `external_salesforce_id` is explicitly populated.
1. Begin by creating a new Account in Salesforce or accessing an existing one;
2. Next, create a customer in Lago and populate the `external_salesforce_id` field for a Lago Customer with the Salesforce Account Id; and
3. Finally, your Salesforce Account and Lago Customer are synchronized!
Billing data will not sync unless these requirements are met.
Lago does not create Salesforce Accounts.
Before syncing billing data, you need to create or retrieve an existing Account in Salesforce
and populate the Lago customer field called `external_salesforce_id`.
### Sync subscriptions to Salesforce
Whenever a subscription is created for a Lago Customer, the subscription details will be automatically
synced in real-time with Salesforce using the `Lago Subscriptions` custom object.
Here is a list of Subscription fields that are automatically synced.
Note that this subcription is automatically linked to a Salesforce Account:
* Subscription Id;
* Subscription Name;
* Subscription Start Date;
* Subscription Status;
* Subscription Termination Date (synced when the subscription is terminated);
* Subscription Billing Time (either `calendar` or `anniversary`); and
* Plan Code.
### Sync invoices to Salesforce
Whenever an invoice is issued for a Lago Customer, the invoice details will be automatically
synced in real-time with Salesforce using the `Lago Invoices` custom object.
Here is a list of Subscription fields that are automatically synced:
* Invoices Number;
* Invoice Payment Status;
* Invoice Type (`subscription` or `one-off`);
* Invoice Issuing Date;
* Invoice Amount;
* Invoice File Url; and
* Invoice Currency.
### Sync credit notes to Salesforce
Whenever a credit note is issued for a Lago Invoice, the credit note details will be automatically
synced in real-time with Salesforce using the `Lago CreditNotes` custom object.
### Sync Plans, Add-Ons, Coupons to Salesforce
Plans and Add-ons are synced to Salesforce when we initially click on **Start Data Sync** from Lago Base Configuration page.
* Plans are synced to `Lago Plans` object and `Product2` standard object. We also create a *price book entry* for all the products in `Standard Price Book` price book
* Add-Ons are synced to `Lago Add-Ons` object and `Product2` standard object. We also create a *price book entry* for all the products in `Standard Price Book` price book.
### Sync coupons and applied coupons to Salesforce
Coupons and Applied coupons are synced to Salesforce when we click on **Start Data Sync** from Lago Base Configuration page.
* Coupons are synced to `Lago Coupons` custom object. All the existing coupons will be available in Salesforce. Please note: we cannot create coupons from Salesforce to Lago, we must create coupons in Lago.
* Applied coupons are synced to `Lago Applied Coupon` custom object.
### Schedule Sync from Lago To Salesforce
We also provide option to schedule the data sync from Lago to Salesforce.
* `LagoSyncScheduleable` -- a schedulable class which helps us schedule either all the data or any one of them.
* To schedule the sync of any *ONE* of the object:
* Create a new instance of class by passing any one of the following string: `CUSTOMER`, `SUBSCRIPTION`, `PLAN`, `ADDON`, `INVOICE`, `CREDITNOTE`
* Ex: To sync Plans from lago to Salesforce everyday at 1PM, execute below anonymous code in Anonymous window in Developer Console. ([click here to learn more about CRON expression](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm))
```
//Create a new instance. Pass 'PLAN' in brackets.
lago.LagoSyncScheduleable syncPlan = new lago.LagoSyncScheduleable('PLAN');
//CRON expression to schedule a job everyday at 1 PM
String schedule_cron = '0 0 13 * * ?';
//schedule(name, cron_expression, class_instance)
System.schedule('Sync Lago Plan', schedule_cron, syncPlan);
```
* To schedule the sync of *ALL* the objects:
* create a new instance of class by passing `true`
* Ex: To sync **all** objects from lago to Salesforce everyday at 1PM, execute below anonymous code in Anonymous window in Developer Console. ([click here to learn more about CRON expression](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm))
```
//Create a new instance. Pass true in brackets.
lago.LagoSyncScheduleable syncAll = new lago.LagoSyncScheduleable(true);
//CRON expression to schedule a job everyday at 1 PM
String schedule_cron = '0 0 13 * * ?';
//schedule(name, cron_expression, class_instance)
System.schedule('Sync Lago all', schedule_cron, syncAll);
```
## III. Actions from Salesforce to Lago
Beyond just syncing data from Lago to Salesforce, you can also initiate actions in Lago directly from Salesforce.
You can leverage Salesforce `Flows` to execute actions in Lago. Lago provides several customizable templates for creating customers from Salesforce Accounts, directly assigning subscriptions to customers from Salesforce, creating one-off invoice from salesforce.
### Create customers
#### Flow: `Lago Template - Create Customer in Lago on Account Create`
To create a customer in Lago upon the creation of a Salesforce Account, utilize the Flow template provided by Lago.
1. Log into your Salesforce instance;
2. Access the Setup section via the settings wheel icon in Salesforce;
3. Find and select `Flows` under Process Automation in the sidebar;
4. Locate and open the `Lago Template - Create Customer in Lago on Account Create`;
5. Click 'Save As' to create and save your own version of the template; and
6. Do not forget to click the `Activate` button to activate your flow.
You have the **flexibility to modify various aspects of this flow, including the trigger conditions and field mappings**.
By default, the action is initiated when a Lago ID is absent. Additionally, you can customize how fields are mapped from your Salesforce instance to Lago. You can also configure `customer type` to 'Individual' or 'Company' which creating customer from Salesforce to Lago.
### Create subscriptions (automation)
Assigning a plan to a customer, adjusting negotiated prices, and initiating the subscription upon winning an opportunity represents a key action from Salesforce to Lago.
This enables sales teams to remain within Salesforce, their primary tool, and activate billing processes directly, without the need to switch platforms.
To assign a subscription and set prices in Lago directly from Salesforce, use the provided two flows via following Lago Flow templates.
#### Flow 1: `Lago Template - Create Lago SObject Records`
This Flow is used to create intermediate records in Lago Objects - `Lago Subscription`
1. Log into your Salesforce instance;
2. Access the Setup section via the settings gear icon in Salesforce;
3. Find and select `Flows` under Process Automation in the sidebar;
4. Locate and open the `Lago Template - Create Lago SObject Records`;
5. Click 'Save As' to create and save your own version of the template; and
6. Do not forget to click the `Activate` button to activate your flow.
The default setting triggers plan assignment when a Salesforce Account links to a Lago customer and the **opportunity status changes to closed-won**.
You can customize this flow to suit your specific needs. Moreover, you have the option to adjust the subscription fields and subscription charges fields being synchronized from Salesforce to Lago.
1. Create an opportunity by assigning an expected closed date and a stage;
2. Add a Lago plan to this opportunity **as a product** (Salesforce will automatically retrieve all plans from Lago in `Standard Price Book`);
3. Specify `1` for the quantity of the plan;
4. Use the custom UI to either assign this plan directly or to override prices; and
5. Click on 'Lago Override Plan' to finalize the subscription assignment.
By default, the lago subscription record in salesforce is created when the opportunity is `closed-won`. You can assign multiple subscriptions for the same opportunity.
#### Flow 2: `Lago Template - Create Subscription in Lago on Subscription Creation/Update`
This Flow is used to create subscriptions in Lago from Salesforce
1. Log into your Salesforce instance;
2. Access the Setup section via the settings gear icon in Salesforce;
3. Find and select `Flows` under Process Automation in the sidebar;
4. Locate and open the `Lago Template - Create Subscription in Lago on Subscription Creation/Update`;
5. Click 'Save As' to create and save your own version of the template; and
6. Do not forget to click the `Activate` button to activate your flow.
The default setting triggers plan assignment when `SyncToLago` checkbox is checked. You can customize this flow to suit your specific needs.
### Create subscriptions (lago native UI)
We also have option to create subscriptions in Lago directly from Salesforce using Lago's create subscription screen.
1. Log into your Salesforce instance;
2. Access the setup section via the settings gear icon in Salesforce;
3. Go to Object manager and find and open account object;
4. Go to page layout (or Lightning record page) depending on what you are using, and open the page layout in which you'd like to add the button to create subscription.
5. Add the button `Lago Subscription`
6. Save the page layout or lightning record page.
Open any account which has `lago_id` populated. Click on `Lago Subscription` button; it will pop-up Lago Screen (make sure you've entered correct `Front End URL` in Lago Base Configuration page); enter correct username and password. Save. A new subscription will be directly created in Lago. And, if Webhooks are configured correctly, it will also create `Lago Subscription` record in Salesforce.
We can add a new button ***Lago Subscription*** on *Account* page or *Opportunity* page
A new Lago Subscription record will be created via webhooks (if configured).
And after 1 minute another callout will be made to sync Charges.
### Terminate Subscription
We can terminate the subscription from Salesforce to lago only if the subscription is already synced to lago(status is *active* or *pending*).
Go to Lago Subscription record in Salesforce, and check `Terminate Subscription` checkbox.
As soon as `Terminate Subscription` is checked it will terminate the subscription in Lago. It is handled from the backend via trigger.
### Create one-off invoice
This enables sales team to create one-off invoice in lago from Salesforce.
Right from the opportunity record we add products which are related to `Lago Add-ons`, specify the quantity, description and amount.
To create one-off invoice and set prices in Lago directly from Salesforce, use the provided two flows via following Lago Flow templates.
#### Flow 1: [`Lago Template - Create Lago SObject Records`](/integrations/crm/salesforce-crm#flow-1-lago-template-create-lago-sobject-records)
The same flow as we created above to create subscription - is also used to create intermediate records in Lago Objects - `Lago Invoice`
#### Flow 2: `Lago Template - Generate Invoice in Lago On Lago Invoice Field Update`
This Flow is used to create one-off invoice in Lago from Salesforce
1. Log into your Salesforce instance;
2. Access the Setup section via the settings gear icon in Salesforce;
3. Find and select `Flows` under Process Automation in the sidebar;
4. Locate and open the `Lago Template - Generate Invoice in Lago On Lago Invoice Field Update`;
5. Click 'Save As' to create and save your own version of the template; and
6. Do not forget to click the `Activate` button to activate your flow.
The default setting triggers create invoice when `SyncToLago` checkbox is checked. You can customize this flow to suit your specific needs.
### Create one-off invoice (lago native UI)
We also have option to create one off invoice in Lago directly from Salesforce using Lago's create invoice screen.
1. Log into your Salesforce instance;
2. Access the setup section via the settings gear icon in Salesforce;
3. Go to Object manager and find and open Account object or Opportunity;
4. Go to page layout (or Lightning record page) depending on what you are using, and open the page layout in which you'd like to add the button to create Invoice.
5. Add the button `Lago Invoice`
6. Save the page layout or lightning record page.
Open any account which has `lago_id` populated. Click on `Lago Invoice` button; it will pop-up Lago Screen (make sure you've entered correct `Front End URL` in Lago Base Configuration page); enter correct username and password. Save. A new Invoice will be directly created in Lago. And, if Webhooks are configured correctly, it will also create `Lago Invoice` record in Salesforce.
We can add a new button ***Lago Invoice*** on *Account* page or *Opportunity* page
A new Lago Invoice record will be created via webhooks (if configured).
After 1 minute another callout will be made to sync invoice line items (add ons).
### Get Invoice pdf
Now we can also get invoice pdf directly directly from Salesforce.
1. Go to Lago Invoice
2. Open any Invoice which is already synced.
3. Click `Get Invoice pdf` > it will open PDF in a new tab.
### Get Invoice Line Item Details
We can fetch Invoice line items manually for any invoices if required.
1. Go to Lago Invoice tab > Open any Invoice which is already synced.
2. Click on `Lago Sync Invoice Line Item` button. If button is not present on the layout, please add it on Page layout or Lightning record page.
3. All lago items will be synced and available in `Lago Line Items` child custom object.
### Managing Coupons in Salesforce
The Salesforce integration allows you to manage customer coupons directly from your Salesforce interface. This section explains how to apply new coupons to customer accounts and manage existing coupons effectively.
#### Applying Coupons to Accounts
Before you begin applying coupons, you'll need to ensure your Salesforce environment is properly configured. The "Apply Coupon" action button must be available in your account page layout or lightning record page. If you don't see this button, work with your Salesforce administrator to add it through the page layout editor or lightning app builder.
Once your environment is configured, follow these steps to apply a coupon to a customer account:
1. Navigate to the Account Details> Access the account details page for the customer who will receive the coupon.
2. Initiate Coupon Application > Click the "Apply Coupon" action button. This will open a popup dialog for coupon configuration.
3. Select and Configure the Coupon. The configuration options will vary depending on the type of coupon you're applying:
* For Fixed Amount Coupons: Enter the discount amount, select the appropriate currency, Choose the frequency for applied coupon
If the Lago customer currency is already set in the account, the currency field will be locked to maintain consistency.
* For recurring frequencies, specify the duration period
* For Percentage-Based Coupons: Verify or adjust the percentage rate, set the frequency of application
* For recurring frequencies, enter the duration period
4. Complete the Application
* Click the "Apply Coupon" button to finalize the process.
* This action will:
* Create an Applied Coupon record in Salesforce
* Synchronize the coupon with the customer's account in Lago
* Enable the discount for future qualifying transactions
#### Terminating Active Coupons
There may be times when you need to end a coupon's application before its natural expiration. Here's how to terminate an active coupon:
1. Access the Coupon Record. Navigate to the Applied Coupon details page for the coupon you wish to terminate.
2. Initiate Termination, locate the "Terminate Coupon" checkbox in the record.
3. Confirm Termination: Check the box to initiate the termination process. Upon saving:
* The coupon status will update from "Active" to "Terminated"
* The change will synchronize with Lago
* The customer will no longer receive the discount
Remember that coupon termination is permanent. Once a coupon is terminated, it cannot be reactivated. You would need to apply a new coupon if the discount needs to be reinstated.
This coupon management system ensures that your sales team can efficiently handle discounts and promotional offers while maintaining synchronization between Salesforce and Lago platforms.
## Debugging & logs
To ensure seamless data synchronization between Lago and Salesforce, every action and data transfer is meticulously logged.
These logs are accessible directly through the Lago package for comprehensive debugging and analysis:
1. Navigate to 'Lago Base Configuration': This is your starting point for accessing the debugging tools. and
2. Access Logs: Click on the 'Logs' tab to view a detailed record of all activities.
You can refresh logs to keep your data current or delete unnecessary logs to maintain clarity and efficiency in the debugging process.
This approach aids in promptly identifying and resolving integration issues.
# Airbyte (ETL)
Source: https://getlago.com/docs/integrations/data/airbyte
Airbyte is an open-source **data integration platform** used as an ETL. With this integration, you can connect Lago billing data to any warehouses.
## Destinations
You can push Lago billing data to destinations such as Snowflake, BigQuery, Redshift, S3 buckets or Azure, for instance.
The entire list of data destinations enabled by Airbyte is listed on their [destinations documentation](https://docs.airbyte.com/integrations/destinations/).
## Data available for extraction
With Airbyte's native integration of Lago, you can push the following billing data to warehouses:
* billable\_metrics
* plans
* coupons
* add\_ons
* invoices
* customers
* subscriptions
At present this connector **only supports full refresh syncs** meaning that each time you use the connector it will sync all available records from scratch. Please use cautiously if you expect your API to have a lot of records.
Find the full documentation of [Airbyte's native Lago integration](https://docs.airbyte.com/integrations/sources/getlago/).
## 1. Connect Lago to Airbyte
First of all, you simply need to bring your Lago private API key.
In airbyte:
* Go to **Sources**;
* Select getLago as a source of data; and
* Paste your Lago private API key.
## 2. Select a destination
You can select any of the data destinations available in Airbyte. It could be a warehouse (BigQuery, Redshift, Snowflake...) or a file storage tool (S3, for instance). Please find here the entire list of [data destinations available in Airbyte](https://docs.airbyte.com/integrations/destinations/).
## 3. Sync billing data
In the following example, we connected Lago billing data to Snowflake data warehouse. Obviously, you can select another destination if needed.
1. Create a **data sync** between Lago source and your destination;
2. Define a **sync frequency**; and
3. Activate the sync in Airbyte between Lago source and your destination.
This action will populate Lago billing data into a warehouse (Snowflake in our example).
## 4. Query Lago billing data
Once the data has been populated in your destination, a warehouse in our example, you can easily query your billing data. Here is a query calculating your monthly revenue with Lago:
# Lago Data Pipeline
Source: https://getlago.com/docs/integrations/data/lago-data-pipeline
Sync your Lago data with your data warehouse or cloud storage
**PREMIUM ADD-ON** ✨
This Lago Data Pipeline feature is available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium feature.
Lago Data Pipeline lets you automate the flow of your billing, subscription, and usage data into your analytics and storage systems.
Whether you're running complex queries on warehouses, or simply building data visualization dashboards for your finance team, you can keep all your data in sync with just a few clicks.
## Prerequisites
* **Data sync frequency:** 1 day by default, but we can go down to 15 minutes;
* **Data transfers:** Incremental or Backfill; and
* **Data security:** high-level of security and encryption.
## Data destinations
You can sync your Lago data to any of the following destinations:
| Vendor | Type | Status |
| ----------------- | -------------- | --------- |
| `Snowflake` | OLAP | Supported |
| `BigQuery` | OLAP | Supported |
| `Redshift` | OLAP | Supported |
| `Databricks` | OLAP | Supported |
| `Athena` | OLAP | Supported |
| `ClickHouse` | OLAP | Supported |
| `MotherDuck` | OLAP | Supported |
| `Postgres` | OLTP | Supported |
| `Aurora Postgres` | OLTP | Supported |
| `MySQL` | OLTP | Supported |
| `Aurora MySQL` | OLTP | Supported |
| `SQL Server` | OLTP | Supported |
| `SingleStore` | OLTP | Supported |
| `S3` | Object Storage | Supported |
| `S3-Compatible` | Object Storage | Supported |
| `GCS` | Object Storage | Supported |
| `ABS` | Object Storage | Supported |
| `Google Sheets` | Spreadsheet | Supported |
## Data sources
Here is the list of tables synced from Lago to your data destination:
| Name | Type |
| --------------------- | ----- |
| `applied_coupons` | Table |
| `billable_metrics` | Table |
| `charges` | Table |
| `coupons` | Table |
| `credit_notes_taxes` | Table |
| `credit_notes` | Table |
| `customers` | Table |
| `fees_taxes` | Table |
| `fees` | Table |
| `invoices_taxes` | Table |
| `invoices` | Table |
| `plans` | Table |
| `subscriptions` | Table |
| `taxes` | Table |
| `wallet_transactions` | Table |
| `wallets` | Table |
# Oso
Source: https://getlago.com/docs/integrations/entitlements/osohq
[Oso](https://www.osohq.com/) is an authorization-as-a-service provider partnering with Lago to offer entitlements. You can use either the open-source version (available on [Github](https://github.com/osohq/oso)) or the cloud-hosted version. To create entitlements with Lago, you must open an account on Oso.
Oso offers a suitable solution for Entitlements. For more information, please refer to [Oso's documentation](https://www.osohq.com/docs/guides/model/entitlements).
## Define available features and plan's quota
First, define the available features for each plan. For instance, the Basic plan has a limited set of features, while the Premium plan offers the full range.
In addition to this, you can use Lago to bill metering and overage. This information can then be passed directly to Oso's `plan_quota` and `quota_used` to limit usage for a specific feature.
## Example
[Oso's documentation](https://www.osohq.com/docs/guides/model/entitlements) explains the following example of entitlements properly.
```ruby theme={"dark"}
actor User { }
resource Organization {
roles = ["admin", "member"];
permissions = ["create_repository"];
"member" if "admin";
}
resource Plan {
roles = ["subscriber"];
relations = { subscribed_organization: Organization };
"subscriber" if role on "subscribed_organization";
}
resource Feature {
relations = { plan: Plan };
}
declare plan_quota(Plan, Feature, Integer);
declare quota_used(Organization, Feature, Integer);
plan_quota(Plan{"pro"}, Feature{"repository"}, 10);
plan_quota(Plan{"basic"}, Feature{"repository"}, 0);
has_quota_remaining(org: Organization, feature: Feature) if
has_quota(org, feature, quota) and
quota_used(org, feature, used) and
used < quota;
has_quota(org: Organization, feature: Feature, quota: Integer) if
plan matches Plan and
has_relation(plan, "subscribed", org) and
plan_quota(plan, feature, quota);
has_permission(user: User, "create_repository", org: Organization) if
has_role(user, "member", org) and
has_quota_remaining(org, Feature{"repository"});
test "members can create repositorys if they have quota" {
setup {
quota_used(Organization{"apple"}, Feature{"repository"}, 5);
quota_used(Organization{"netflix"}, Feature{"repository"}, 10);
quota_used(Organization{"amazon"}, Feature{"repository"}, 0);
has_relation(Plan{"pro"}, "subscribed", Organization{"apple"});
has_relation(Plan{"pro"}, "subscribed", Organization{"netflix"});
has_relation(Plan{"basic"}, "subscribed", Organization{"amazon"});
has_role(User{"alice"}, "member", Organization{"apple"});
has_role(User{"bob"}, "member", Organization{"netflix"});
has_role(User{"charlie"}, "member", Organization{"amazon"});
}
assert has_quota_remaining(Organization{"apple"}, Feature{"repository"});
# Apple has quota remaining, so all good
assert allow(User{"alice"}, "create_repository", Organization{"apple"});
# Netflix has used all quota
assert_not allow(User{"bob"}, "create_repository", Organization{"netflix"});
# Amazon doesn't have any quota left
assert_not allow(User{"charlie"}, "create_repository", Organization{"amazon"});
}
```
# Introduction
Source: https://getlago.com/docs/integrations/introduction
Find all Lago integrations with third-party tools—whether for payment providers, alerting systems, or data integrations. Note that some integrations are native and actively maintained by Lago, while others are community-developed and come with limited support.
## Payments integrations
}
href="/integrations/payments/gocardless-integration"
>
GoCardless is the global leader of direct debits bank payments.
Official
}
href="/integrations/payments/stripe-integration"
>
Stripe is a suite of APIs powering online payment processing, especially
card payments.
Official
}
href="/integrations/payments/adyen-integration"
>
Adyen is an omnichannel payment processing company providing multiple ways
to accept payments.
Official
}
href="/integrations/payments/cashfree-integration"
>
Cashfree Payments is India's leading payments and API banking company.
Community
}
href="/integrations/payments/moneyhash-integration"
>
Moneyhash is the leading payment infrastructure software in Africa and the Middle East.
Community?
}
href="/integrations/payments/custom-payment-integration"
>
This guide helps you integrate Lago with a custom payment provider. Build your own integration by following these steps.
Community
## Accounting integrations
}
href="/integrations/accounting/netsuite"
>
NetSuite is the leading integrated cloud business software for business
accounting.
Official
}
href="/integrations/accounting/xero"
>
Xero is a cloud-based accounting software for small businesses.
Official
}
href="/integrations/accounting/quickbooks"
>
QuickBooks is an accounting software package for small and medium-sized businesses.
Community
## Taxes integrations
}
href="/integrations/taxes/anrok"
>
Anrok is the global sales tax platform for software companies.
Official
}
href="/integrations/taxes/avalara"
>
AvaTax is a cloud-based tax calculation and compliance platform that helps businesses manage their sales tax obligations.
Official
}
href="/integrations/taxes/lago-eu-taxes"
>
Lago now features an automatic European tax detection integration for your
customers.
Official
## CRM integrations
}
href="/integrations/crm/salesforce-crm"
>
Salesforce CRM integration is used to sync data from Lago to Salesforce.
Official
}
href="/integrations/crm/salesforce-cpq"
>
Salesforce CPQ extension for Lago's native Salesforce package.
Official
}
href="/integrations/crm/hubspot"
>
HubSpot CRM integration is used to sync data from Lago to HubSpot.
Official
## Marketplaces & hyperscalers integrations
Lago integrates with marketplaces and hyperscalers through our partner
[Suger.io](https://suger.io).
}
href="/integrations/marketplaces/aws-marketplace"
>
Quickly list, transact, and co-sell on AWS Marketplace with Lago, via
Suger.io integration.
Official
}
href="/integrations/marketplaces/azure-marketplace"
>
Quickly list, transact, and co-sell on Azure Marketplace with Lago, via
Suger.io integration.
Official
}
href="/integrations/marketplaces/gcp-marketplace"
>
Quickly list, transact, and co-sell on GCP Marketplace with Lago, via
Suger.io integration.
Official
## Usage tracking integrations
}
href="/integrations/usage/segment"
>
Segment is used to track and ingest events that can be sent to Lago as
usage.
Official
}
href="/integrations/usage/hightouch"
>
Reverse-ETL helping you sync data from any sources (database, warehouses,
spreadsheet...) to Lago.
Official
## Alerting integrations
}
href="/integrations/alerting/zapier"
>
Use Zapier and Lago to trigger billing automations, such as an invoice
alerting system.
Official
}
href="/integrations/alerting/n8n"
>
Use n8n and Lago to trigger billing automations, such as an overconsumption
alerting system.
Official
## Data integrations
}
href="/integrations/data/lago-data-pipeline"
>
Sync your Lago data to any data destinations by using our native data pipeline.
Official
}
href="/integrations/data/airbyte"
>
Send billing data to any warehouses by using our integration with Airbyte
ETL services.
Community
## Entitlements integrations
}
href="/integrations/entitlements/osohq"
>
Oso is an Authorization as service used for entitlements
Community
# AWS Marketplace
Source: https://getlago.com/docs/integrations/marketplaces/aws-marketplace
Lago integrates with AWS marketplace through our partner Suger.io
If you're using Lago for metering and billing and looking to expand into AWS marketplace, [Suger](https://suger.io) is the ideal partner. Suger offers the fastest and easiest way to list, transact, and co-sell on AWS marketplace.
Their no-code, fully automated integration with Lago allows you to seamlessly track usage within your existing setup and allocate it across various cloud marketplaces.
This approach eliminates the need for migration or complex engineering, ensuring a smooth and hassle-free transition.
}
href="https://doc.suger.io/integrations/lago"
>
Quickly list, transact, and co-sell on AWS Marketplace with Lago, via Suger.io integration.
# Azure Marketplace
Source: https://getlago.com/docs/integrations/marketplaces/azure-marketplace
Lago integrates with Azure marketplace through our partner Suger.io
If you're using Lago for metering and billing and looking to expand into Azure marketplace, [Suger](https://suger.io) is the ideal partner. Suger offers the fastest and easiest way to list, transact, and co-sell on Azure marketplace.
Their no-code, fully automated integration with Lago allows you to seamlessly track usage within your existing setup and allocate it across various cloud marketplaces.
This approach eliminates the need for migration or complex engineering, ensuring a smooth and hassle-free transition.
}
href="https://doc.suger.io/integrations/lago"
>
Quickly list, transact, and co-sell on Azure Marketplace with Lago, via
Suger.io integration.
# GCP Marketplace
Source: https://getlago.com/docs/integrations/marketplaces/gcp-marketplace
Lago integrates with GCP marketplace through our partner Suger.io
If you're using Lago for metering and billing and looking to expand into GCP marketplace, [Suger](https://suger.io) is the ideal partner. Suger offers the fastest and easiest way to list, transact, and co-sell on GCP marketplace.
Their no-code, fully automated integration with Lago allows you to seamlessly track usage within your existing setup and allocate it across various cloud marketplaces.
This approach eliminates the need for migration or complex engineering, ensuring a smooth and hassle-free transition.
}
href="https://doc.suger.io/integrations/lago"
>
Quickly list, transact, and co-sell on GCP Marketplace with Lago, via
Suger.io integration.
# Adyen
Source: https://getlago.com/docs/integrations/payments/adyen-integration
Lago's native integration with Adyen allows you to collect payments automatically when new invoices are generated.
Lago's seamless integration with Adyen offers a wide range of payment options, enabling you to conveniently collect payments from your customers. Supported payment methods include:
* Card payments (Visa, MasterCard, CB)
* Apple Pay
* Paypal
* American Express
* Amazon Pay
* Google Pay
And many more! With Lago's native Adyen integration, you can offer your customers a variety of payment options, enhancing their convenience and flexibility during transactions.
Please ensure that you have added payment methods to your Adyen account before setting up the integration ([see Adyen documentation](https://docs.adyen.com/payment-methods/add-payment-methods/)).
## Connecting Lago to Adyen
To set up the Adyen integration in Lago from our user interface, follow these steps:
1. In the side menu of your Lago app, navigate to **Settings**;
2. Select the **Integrations** tab;
3. Click **"Adyen"** to create a connection;
4. Give a name to this connection;
5. Assign a code for easy identification;
6. Enter the required connection fields (described in the next section); and
7. Click **Connect to Adyen** to confirm the integration.
## Adyen Connection Fields
When connecting Lago to Adyen, you need to provide information for the following fields.
The API Key is a mandatory field and can be found in your Adyen account. Follow these steps to retrieve the API Key:
* Go to your Adyen account and navigate to **Developers** > **API Credentials**;
* On the API Credentials page, create new credentials with a type of **Web service user**;
* Click on the **Create credentials** button to generate the API Key; and
* Copy the API Key and paste it in the corresponding field in Lago. Remember to save the changes.
The Merchant Account is required to ensure that Lago targets the correct Adyen account. To find the Merchant Account:
* Go to **Settings** > **Merchant accounts** in your Adyen account; and
* Copy the **Account code** of the targeted account you want to use with Lago.
The Live Prefix represents the prefix url of your live Adyen account. This field is optional. If left empty, you can connect a test account. However, for live accounts, you must provide a Live Prefix. Follow these steps to obtain the Live Prefix:
* Go to **Developers** > **API URLs** > **Prefix** in your Adyen account.
Adyen's HMAC signatures are used to protect webhook endpoints and messages created by Adyen. Lago requires this signature to properly decrypt outgoing webhooks from Adyen. To find the HMAC Signature:
* Create or edit a webhook in Adyen by accessing **Developers** > **Webhooks**;
* Choose a webhook, e.g. Standard webhook; and
* Under "Security" settings, you can find the HMAC Key.
The Live Prefix and HMAC Signature fields are optional and may not be required depending on your use case.
## Setting up Adyen's payments auto-capture
To enable automatic payment capture in your Adyen account, ensure that you have configured the account settings accordingly. Automatic payment capture allows for immediate processing without manual intervention. Refer to Adyen's documentation for instructions on [setting up auto capture](https://docs.adyen.com/online-payments/capture#automatic-capture).
## Turn on Adyen's recurring details
In Adyen, to enable recurring payments for a stored payment method, follow these steps:
1. Go to Developers > Additional Data;
2. Check the box for Recurring Details; and
3. Click Save.
## Setting up Adyen Webhook for listening to important events
**This step is crucial and mandatory** for Lago to receive and process messages from Adyen, enabling functionalities such as customer creation/update, payment processing, and refunds. To configure Adyen webhook and establish communication with Lago, follow the steps below:
1. Access your Adyen application and navigate to the **Developers** section;
2. Select **Webhooks** and create a new webhook of type **Standard**;
3. In the **Server configuration** section, locate the **General** settings; and
4. Copy and paste the following URL: **`https://api.getlago.com/webhooks/adyen/{{your_organization_id}}?code={{connection_code}}`**.
You can find your Organization ID in Lago under the Developers section in Lago, specifically in **API keys & ID** > **Organization ID**.
To find your **connection code**, navigate to the Integrations section in Lago and select the appropriate connection code for your Adyen integration.
**Please ensure that you complete this setup correctly, as your Adyen integration will not function without this vital step.**
## Setting Adyen as a Payment Provider for a customer
In order to facilitate automated payment collection, it is essential for the customer to exist in both the Lago and Adyen databases. Please note that in Adyen, customers are referred to as **Shoppers**.
### Adding a new customer in Adyen
If the customer does not already exist in Adyen, you can create them in Lago using either the user interface or the **[API](/api-reference/customers/create)**. When providing customer information, please ensure the following:
1. Set Adyen as the customer's **default payment provider**;
2. Select the Adyen connected account;
3. Keep the field associated with the **Adyen Payment Provider Customer ID** empty; and
4. **Enable** the option to automatically create the customer in Adyen.
Once the customer is added in Lago, they will be automatically synchronized with Adyen. Adyen will generate a unique Shopper ID, which will be stored in Lago. Typically, Adyen utilizes the Lago customer's **`external_id`** as the Shopper ID for seamless integration between the two platforms.
Upon successful customer creation, you will receive two **[webhook messages](/api-reference/webhooks/messages)** to keep you informed:
1. **`customer.checkout_url_generated`**: This message includes the checkout URL that provides access to the default payment method. It allows you to perform a pre-authorization payment and store the payment method securely; and
2. **`customer.payment_provider_created`**: This message confirms the successful creation of the customer in Adyen, indicating that the customer's details have been added to the Adyen database.
You may need to enable Developers -> Additional Data -> Payment -> Recurring details for the customer to be automatically created.
Please note that the customer will be created in Adyen only if the payment method has been stored through the checkout URL and pre-authorization payment.
### Using an existing customer from Adyen
If the customer and direct debit mandate already exist in Adyen, you can create the customer record in Lago using either the user interface or **[the API](/api-reference/customers/create)**. Follow these steps when adding customer information:
1. Set Adyen as the **default payment provider** for the customer in Lago;
2. Select the Adyen connected account;
3. Provide the **Adyen [Shopper Reference](https://docs.adyen.com/point-of-sale/card-acquisition/identifiers#:~:text=Shopper%20reference%3A%20a,contract%20payments.)** as the Lago **Payment provider customer ID**.
4. **Disable** the option to automatically create the customer in Adyen.
By following these steps, you can integrate an existing customer from Adyen into Lago, ensuring synchronization and consistency between the two platforms.
## Redirect url after checkout[](#checkout-redirect-url "Direct link to heading")
After establishing the connection with Adyen, set a success URL where your end customer will be directed after completing the checkout.
Please note that if it's not defined, your end customer will be redirected to Adyen's website.
Please note that you can edit or delete the redirect URL, and this will only affect new checkout URLs created.
URL defined should always begin with `http://` or `https://`.
## Adyen Checkout: storing customer's payment method information
When Lago automatically creates a customer in Adyen, you will receive a checkout link from Lago to facilitate the storage of your customer's payment method information.
The payload sent by Lago will have the following structure, with the checkout link stored under **`checkout_url`**:
```json theme={"dark"}
{
"webhook_type": "customer.checkout_url_generated",
"object_type": "payment_provider_customer_checkout_url",
"payment_provider_customer_checkout_url": {
"lago_customer_id": "88d23508-47fd-46bb-a87e-50c50f3cb371",
"external_customer_id": "hooli_1234",
"payment_provider": "adyen",
"payment_provider_code": "adyen_test",
"checkout_url": "https://test.adyen.link/PLEEA656869B11DF6B"
}
}
```
Note: The checkout link automatically expires after 69 days.
By utilizing this provided checkout link, your customers can perform a pre-authorization payment. It's important to note that the pre-authorization payment will not collect any funds from the customer. Once the pre-authorization is confirmed, Lago will send the payment method details and securely store them into Adyen for future transactions.
## Regenerate checkout link on demand
In cases where your end customer has not had the opportunity to complete the checkout process to inform their payment method
or wishes to modify the saved payment information, you can generate a new checkout link using the designated [endpoint](/api-reference/customers/psp-checkout-url).
```json theme={"dark"}
POST /api/v1/customers/:customer_external_id/checkout_url
```
Upon successful generation, the new checkout link will be available in the endpoint response, and it will not be delivered through a webhook message.
It is important to note that the new link will inherit the same expiration setting as the original one.
It is crucial to be aware that if a customer is not associated with any payment provider, the response will contain an error message.
## Creating payments from Lago Invoices
When a customer has Adyen defined as their payment provider, Lago seamlessly automates the process of triggering payments in Adyen whenever a new invoice is generated.
This integration ensures that payments are initiated in Adyen without any manual intervention. Lago's automatic payment creation saves time and effort, providing a streamlined experience for both you and your customers.
## Creating refunds from Lago Credit Notes
In cases where a customer has Adyen defined as their payment provider, Lago simplifies the refund process by automatically triggering refunds in Adyen whenever a new refund is initiated through credit notes.
This integration eliminates the need for manual refund processing and ensures that refunds are efficiently handled in Adyen. Lago's automated refund functionality helps you maintain accurate and timely refund transactions, enhancing customer satisfaction and operational efficiency.
## Payment disputes
In the event of a **lost** chargeback (dispute) within Adyen, Lago initiates an automatic response by marking the relevant invoice as disputed lost. This action involves populating the `dispute_lost_at` field with the timestamp when the dispute was lost. Following this update:
* The invoice becomes non-voidable;
* Generating a credit note is possible; however, refunding the payment back to the original payment method is not permitted; and
* The invoice cannot be resent for collection.
## Watch the demo video
# Cashfree Payments
Source: https://getlago.com/docs/integrations/payments/cashfree-integration
Make your users pay Lago invoices with Cashfree Payments, India's leading payments and API banking company.
This integration is community-maintained, and therefore Lago provides only limited support.
## Payments in India
Cashfree is a leading payment platform in India, offering an end-to-end suite of payment and payout products tailored to the country's needs.
Its extensive coverage of payment methods—including credit/debit cards, net banking, UPI, and popular wallets like Paytm, PhonePe, and Amazon Pay—enables businesses to seamlessly collect payments from Indian customers with minimal friction.
This integration streamlines the collection of Lago invoices in India by leveraging multiple local payment methods.
## Connect Cashfree to Lago
To connect Cashfree to Lago, navigate to your Lago UI, then go to **Integrations** > **Built by community**, and add a new **Cashfree Payments** connection:
1. Click **Add a connection**.
2. Type a connection **name**.
3. Type a unique connection **code**.
4. Paste your Cashfree **Client ID**.
5. Paste your Cashfree **Client Secret**.
6. Provide the **redirect URL** to redirect your users when a payment is processed.
## Create a webhook endpoint
To complete this process, you will need:
* Your Lago **organization ID**, available in the **"API keys & ID"** tab of the
**"Developers"** section;
* The **connection code** you created during the Cashfree setup process.
If you want Lago to automatically retrieve the status of the payments processed
via Cashfree Payments, you must create a webhook endpoint in Cashfree. To do so:
1. Log in to your Cashfree Payments account;
2. Add the following Webhook URL in the **Webhooks** > **Payment Link** section of the Cashfree Payments dashboard;
3. Enter the following URL: `https://api.getlago.com/webhooks/cashfree/{{__YOUR_ORG_ID__}}?code={{__YOUR_CONNECTION_CODE}}` (you must replace `organization_id` with your Lago organization ID, and the `connection_code` by the targeted Lago connection); and
4. Save the creation of this webhook endpoint.
## Collect payments via Cashfree
### Connect a Lago Customer to Cashfree
To begin collecting payments for your Lago invoices via Cashfree, you need to link a Lago customer to a Cashfree connection.
When creating or editing a customer in Lago, simply select the relevant Cashfree connection under **external apps** to enable invoice payments.
### Generate a checkout link
Note that payments through Cashfree does not automatically proceed when Lago generates an invoice. You need to programmatically generate a checkout link by calling the [following endpoint](/api-reference/invoices/payment-url):
```bash Request theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/invoices/{lago_id}/payment_url \
--header 'Authorization: Bearer '
```
By generating this checkout link, you can forward it to your customer to complete payment using their preferred method from India. Once the payment is processed, Lago automatically retrieves the invoice status from Cashfree.
```json Response theme={"dark"}
{
"invoice_payment_details": {
"lago_customer_id": "13b901a90-1a90-1a90-1a90-1a901a901a90",
"lago_invoice_id": "1e501a90-938s-1a90-1a90-1a901a901a80",
"external_customer_id": "53dj371e-4ea2-bcf9-57d3a41bc6ba",
"payment_provider": "cashfree",
"payment_url": "https://cashfree.payment_link"
}
}
```
### Cashfree payment errors
If an error occurs during the Cashfree payment process for a Lago invoice, Lago sends a [`payment_request.payment_failure`](https://docs.getlago.com/api-reference/webhooks/messages#param-payment-request-payment-failure) webhook containing the error details.
# GoCardless
Source: https://getlago.com/docs/integrations/payments/gocardless-integration
Lago's native integration with GoCardless allows you to collect payments via direct debit.
## Integration setup[](#integration-setup "Direct link to heading")
### Connect your GoCardless account[](#connect-your-gocardless-account "Direct link to heading")
To connect to GoCardless through the user interface:
1. In the side menu, select **"Settings"**;
2. Open the **"Integrations"** tab;
3. Click **"GoCardless"** to create a connection;
4. Give a name to this connection;
5. Assign a code for easy identification;
6. Click on **"Connect to GoCardless"** to be redirected to the GoCardless application;
7. Create a GoCardless account or log in to your existing account; and
8. Connect your account to be redirected to the Lago application.
When the OAuth connection is active, you will see the screen below, with your
secret key.
### Create webhook endpoints[](#create-webhook-endpoints "Direct link to heading")
To complete this process, you will need:
* Your Lago **organization ID**, available in the **"API keys & ID"** tab of the
**"Developers"** section; and
* Your **secret key**, available in the **"Integrations"** tab of the
**"Settings"** section ([learn more](#connect-your-gocardless-account)).
If you want Lago to automatically retrieve the status of the payments processed
via GoCardless, you must create a webhook endpoint in GoCardless. To do so:
1. Log in to your [GoCardless account](https://manage.gocardless.com/sign-in);
2. Go to the **"Developers"** section;
3. In the upper right corner, click **"Create"** and then select **"Webhook
endpoint"**;
4. Choose a name for this webhook (e.g. Lago);
5. Enter the following URL: `https://api.getlago.com/webhooks/gocardless/{{organization_id}}?code={{connection_code}}` (you must replace `organization_id` with your Lago organization ID, and the `connection_code` by the targeted Lago connection);
6. Enter your secret key; and
7. Click **"Create webhook endpoint"**.
In addition to this, you must create a webhook endpoint in Lago to retrieve the
checkout URL associated with each customer account
([learn more](#direct-debit)). To do so:
1. Go to the **"Developers"** section of the Lago application;
2. In the **"Webhooks"** tab, click **"Add a webhook"** on the right;
3. Enter your webhook URL; and
4. Click **"Add webhook"** to confirm.
For more information about our webhooks, please refer to the
[API documentation](/api-reference/webhooks/format---signature).
## Redirect url after checkout[](#checkout-redirect-url "Direct link to heading")
After establishing the connection with GoCardless, set a success URL where your end customer will be directed after completing the checkout.
Please note that if it's not defined, your end customer will be redirected to GoCardless’s website.
Please note that you can edit or delete the redirect URL, and this will only affect new checkout URLs created.
URL defined should always begin with `http://` or `https://`.
## Customer information[](#customer-information "Direct link to heading")
To collect payments automatically, the customer must exist in both the Lago and
GoCardless databases.
### New customer[](#new-customer "Direct link to heading")
If the customer does not already exist in GoCardless, you can first create them
in Lago, either via the user interface or
[the API](/api-reference/customers/create). When adding customer information, you
must:
1. Provide the customer's email address;
2. Define GoCardless as the **default payment provider**;
3. Select the GoCardless connected account;
4. Leave the field associated with the **GoCardless customer ID** blank; and
5. **Enable** the option to automatically create the customer in GoCardless.
The customer will automatically be added to GoCardless. GoCardless will then
return the customer ID, which will be stored in Lago.
When the customer is successfully created, you will receive two
[webhook messages](/api-reference/webhooks/messages):
* `customer.payment_provider_created` that confirms the creation of the customer
in GoCardless; and
* `customer.checkout_url_generated` that includes the checkout URL to set up the
direct debit ([learn more](#direct-debit)).
### Existing customer[](#existing-customer "Direct link to heading")
If the customer and direct debit mandate already exist in GoCardless, then you
should create the customer record in Lago, either via the user interface or
[the API](/api-reference/customers/create). When adding customer information, you
must:
1. Provide the customer's email address;
2. Define GoCardless as the **default payment provider**;
3. Select the GoCardless connected account;
4. Provide the **GoCardless customer ID**; and
5. **Disable** the option to automatically create the customer in GoCardless.
## Direct debit[](#direct-debit "Direct link to heading")
To collect payments via direct debit, a mandate must be created. To do so:
1. Retrieve the checkout URL included in the `customer.checkout_url_generated`
webhook; and
2. Redirect your customer to the checkout page, so that they can complete the
online form and approve the mandate.
The mandate must be validated by GoCardless before the first payment can be
processed. It can take up to six business days to validate a new mandate. For
more information about payment timings, please consult the
[GoCardless FAQ](https://gocardless.com/faq/merchants/direct-debit/).
To collect payments via direct debit, the currency of the mandate must match
the currency of the plan associated with the customer's subscription.
Each time a new invoice with an **amount greater than zero** is generated by
Lago, a payment will automatically be created. GoCardless will record the
invoice ID and process the payment. Payments via direct debit are usually
processed within five business days. If the payment is successful, the status of
the payment will switch from `pending` to `succeeded`.
If the payment fails, the status of the payment will switch from `pending` to
`failed` and Lago will generate an `invoice.payment_failure`
[webhook](/api-reference/webhooks/messages).
If you have signed up for [GoCardless
Success+](https://gocardless.com/solutions/success-plus/), failed payments may
be automatically resubmitted, in which case Lago will automatically update the
invoice payment status.
## Regenerate checkout link on demand
In cases where your end customer has not had the opportunity to complete the checkout process to inform their payment method
or wishes to modify the saved payment information, you can generate a new checkout link using the designated [endpoint](/api-reference/customers/psp-checkout-url).
```json theme={"dark"}
POST /api/v1/customers/:customer_external_id/checkout_url
```
Upon successful generation, the new checkout link will be available in the endpoint response, and it will not be delivered through a webhook message.
It is important to note that the new link will inherit the same expiration setting as the original one.
It is crucial to be aware that if a customer is not associated with any payment provider, the response will contain an error message.
# Moneyhash
Source: https://getlago.com/docs/integrations/payments/moneyhash-integration
Moneyhash is a leading payment infrastructure software in Africa and the Middle East.
This integration is community-maintained, and therefore Lago provides only limited support.
## About Moneyhash
Moneyhash is a leading payment infrastructure software in Africa and the Middle East.
They help businesses across Emerging Markets to optimize payment performance, scale operations, cut costs, and grow revenue through their all-in-one orchestration platform.
## Connect Moneyhash to Lago
To connect Moneyhash to Lago, navigate to your Lago UI, then go to **Integrations** > **Built by community**, and add a new **Moneyhash Payments** connection:
1. Click **Add a connection**;
2. Type a connection **name**;
3. Type a unique connection **code**;
4. Paste your Moneyhash **API key**; and
5. Paste your Moneyhash **Flow Id**.
## Create a webhook endpoint
To complete this process, you will need:
* Your Lago **organization ID**, available in the **"API keys & ID"** tab of the
**"Developers"** section;
* The **connection code** you created during the Moneyhash setup process.
If you want Lago to automatically retrieve the status of the payments processed
via Moneyhash, you must create a webhook endpoint in Moneyhash. To do so:
1. Log in to your Moneyhash account;
2. Add the following Webhook URL in the **Webhooks** section of the Moneyhash dashboard;
3. Enter the following URL: `https://api.getlago.com/webhooks/moneyhash/{{__YOUR_ORG_ID__}}?code={{__YOUR_CONNECTION_CODE}}` (you must replace `organization_id` with your Lago organization ID, and the `connection_code` by the targeted Lago connection); and
4. Save the creation of this webhook endpoint.
## Collect payments via Moneyhash
### Connect a Lago Customer to Moneyhash
To begin collecting payments for your Lago invoices via Moneyhash, you need to link a Lago customer to a Moneyhash connection.
When creating or editing a customer in Lago, simply select the relevant Moneyhash connection under **external apps** to enable invoice payments.
### Generate a checkout link
Note that payments through Moneyhash does not automatically proceed when Lago generates an invoice. You need to programmatically generate a checkout link by calling the [following endpoint](/api-reference/invoices/payment-url):
```bash Request theme={"dark"}
curl --request POST \
--url https://api.getlago.com/api/v1/invoices/{lago_id}/payment_url \
--header 'Authorization: Bearer '
```
By generating this checkout link, you can forward it to your customer to complete payment using their preferred method from India. Once the payment is processed, Lago automatically retrieves the invoice status from Moneyhash.
```json Response theme={"dark"}
{
"invoice_payment_details": {
"lago_customer_id": "13b901a90-1a90-1a90-1a90-1a901a901a90",
"lago_invoice_id": "1e501a90-938s-1a90-1a90-1a901a901a80",
"external_customer_id": "53dj371e-4ea2-bcf9-57d3a41bc6ba",
"payment_provider": "moneyhash",
"payment_url": "https://moneyhash.payment_link"
}
}
```
### Moneyhash payment errors
If an error occurs during the Moneyhash payment process for a Lago invoice, Lago sends a [`payment_request.payment_failure`](https://docs.getlago.com/api-reference/webhooks/messages#param-payment-request-payment-failure) webhook containing the error details.
# Stripe
Source: https://getlago.com/docs/integrations/payments/stripe-integration
Lago's native integration with Stripe allows you to collect payments automatically when new invoices are generated.
## Watch the demo video
## Integration setup[](#integration-setup "Direct link to heading")
To set up the integration with Stripe through the user interface:
1. In the side menu, select **"Settings"**;
2. Select the **"Integrations"** tab;
3. Click **"Stripe"** and add a new connection;
4. Give this new connection a name and a code;
5. Enter your Stripe API key ([locate your API key](https://support.stripe.com/questions/locate-api-keys-in-the-dashboard)); and
6. Click **"Connect to Stripe"** to confirm.
By default, customers created in Lago are not automatically created in Stripe.
If you want your Lago customers to be added to Stripe, you need to activate
this option ([learn more](#new-customer)).
## Redirect url after checkout[](#checkout-redirect-url "Direct link to heading")
After establishing the connection with Stripe, set a success URL where your end customer will be directed after completing the checkout.
Please note that if it's not defined, your end customer will be redirected to Stripe's website.
Please note that you can edit or delete the redirect URL, and this will only affect new checkout URLs created.
URL defined should always begin with `http://` or `https://`.
## Customer information[](#customer-information "Direct link to heading")
To collect payments automatically, the customer must exist in both the Lago and
Stripe databases.
### New customer[](#new-customer "Direct link to heading")
If the customer does not already exist in Stripe, you can first create them in
Lago, either via the user interface or [the API](/api-reference/customers/create).
When adding customer information, you must:
1. Define Stripe as the **default payment provider**;
2. Leave the field associated with the **Stripe customer ID** blank;
3. **Enable** the option to automatically create the customer in Stripe; and
4. Define payment method options for this customer. Possible values are `card`, `link`, `sepa_debit`, `us_bank_account`, `bacs_debit`, `boleto`, `crypto` or `customer_balance`.
The customer will automatically be added to Stripe. Stripe will then return the
customer ID, which will be stored in Lago.
### Existing customer[](#existing-customer "Direct link to heading")
If the customer already exists in Stripe but not in Lago, you should create the
customer record, either via the user interface or
[the API](/api-reference/customers/create). When adding customer
information, you must:
1. Define Stripe as the **default payment provider**;
2. Provide the **Stripe customer ID**;
3. **Disable** the option to automatically create the customer in Stripe; and
4. Define payment method options for this customer. Possible values are `card`, `link`, `sepa_debit`, `us_bank_account`, `bacs_debit`, `boleto`, `crypto` or `customer_balance`.
## Supported payment methods
Lago's Stripe integration accommodates a variety of payment methods, both generic and region-specific.
The checkout URL provided by Lago is designed to handle multiple payment options seamlessly.
### General payment methods
Lago's Stripe integration includes a universal card payment method that supports various currencies, ideal for global transactions.
This method is set as the default to facilitate recurring payments, ensuring Lago can process charges for your customers efficiently.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["card"]
}
}
}'
```
For card transactions, you can enable the [Link](https://stripe.com/payments/link) feature to offer one-click payments.
Link automatically fills in your customers' payment information, ensuring a seamless and secure checkout experience.
If you are using the `link` feature, it must be used in conjunction with `card`.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["card", "link"]
}
}
}'
```
Lago now accepts invoice payments via Stripe bank transfers (customer balance). Supported methods include:
* JPY: Japan
* GBP: United Kingdom
* EUR: Specific SEPA countries (see Stripe documentation)
* MXN: Mexico
* USD: United States, United Kingdom, and select SEPA countries
If you are using the `customer_balance` payment method in Lago, no other payment method can be selected.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["customer_balance"]
}
}
}'
```
### Localized payment methods
For European customers, Lago supports Stripe SEPA Debit (Single Euro Payments Area).
Accepting a mandate through this method authorizes you to debit your customers' accounts for recurring payments via Lago.
The designated payment method for SEPA transactions within Lago is identified as `sepa_debit`.
It's important to note that **this payment option is exclusive to invoices in `EUR` currency**.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["sepa_debit"]
}
}
}'
```
For US-based transactions, Lago integrates Stripe ACH Debit, leveraging the Automated Clearing House for electronic bank-to-bank payments.
Upon accepting a mandate, you gain authorization to execute recurring debits from your customers' accounts through Lago.
The designated payment method for ACH transactions within Lago is identified as `us_bank_account`.
It's important to note that **this payment option is exclusive to invoices in `USD` currency**.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["us_bank_account"]
}
}
}'
```
For UK transactions, Lago integrates Stripe BACS Debit, utilizing the UK's BACS system for direct bank-to-bank payments.
By accepting a mandate with this method, you're authorized to initiate recurring debits from your customers' accounts through Lago.
The specific payment method for BACS transactions within Lago is designated as `bacs_debit`.
It's important to note that **this payment method is exclusively for invoices in `GBP` currency.**
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["bacs_debit"]
}
}
}'
```
For transactions in Brazil, you can process payments using Boleto vouchers.
In Lago, this payment method is identified as `boleto`.
Note that Boleto is only valid for invoices denominated in Brazilian Real (BRL). Additionally, Boleto payments cannot be refunded and are unlikely to be successfully disputed.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["boleto"]
}
}
}'
```
Lago invoices can be paid via Stripe Crypto for USD-denominated invoices only. Please note that payments must be made using stablecoins, such as USDC or USDP.
```bash theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba",
"address_line1": "5230 Penfield Ave",
"billing_configuration": {
"invoice_grace_period": 3,
"payment_provider": "stripe",
"provider_customer_id": "cus_12345",
"sync": true,
"sync_with_provider": true,
"provider_payment_methods": ["crypto"]
}
}
}'
```
## Stripe Checkout: storing customer's payment method information
Checkout page shows only selected payment methods for customers.
When Lago automatically creates a customer in Stripe, you will receive a checkout link from Lago to facilitate the storage of your customer's payment method information.
The payload sent by Lago will have the following structure, with the checkout link stored under `checkout_url`:
```json theme={"dark"}
{
"webhook_type": "customer.checkout_url_generated",
"object_type": "payment_provider_customer_checkout_url",
"payment_provider_customer_checkout_url": {
"lago_customer_id": "88d23508-47fd-46bb-a87e-50c50f3cb371",
"external_customer_id": "hooli_1234",
"payment_provider": "stripe",
"checkout_url": "https://checkout.stripe.com/c/pay/prod_c15sTbBMLep5FKOA9b9pZBiRBBYYSU1IJ5T89I5TTtpKgzE380JSmxnVYz#fidkdWxOYHw"
}
}
```
Note: The checkout link automatically expires after 24 hours!
By utilizing this provided checkout link, your customers can perform a pre-authorization payment. It's important to note that the pre-authorization payment will not collect any funds from the customer. Once the pre-authorization is confirmed, Lago will send the payment method details and securely store them into Stripe for future transactions.
## Regenerate checkout link on demand
In cases where your end customer has not had the opportunity to complete the checkout process to inform their payment method
or wishes to modify the saved payment information, you can generate a new checkout link using the designated [endpoint](/api-reference/customers/psp-checkout-url).
```bash theme={"dark"}
POST /api/v1/customers/:customer_external_id/checkout_url
```
Upon successful generation, the new checkout link will be available in the endpoint response, and it will not be delivered through a webhook message.
It is important to note that the new link will inherit the same expiration setting as the original one.
It is crucial to be aware that if a customer is not associated with any payment provider, the response will contain an error message.
## Default payment method
When you add a new payment method in Stripe, **Lago automatically sets it as the default**.
This guarantees that Lago uses the latest payment method for a customer. However, if you manually designate one of
multiple payment methods as the default, Lago will use it for payments instead the most recent one.
## Payment intents[](#payment-intents "Direct link to heading")
Once Stripe is connected and the customer exists in both databases, you can
start collecting payments.
### Succeeded payments
Each time a new invoice with an **amount greater than zero** is generated by
Lago, a payment intent will automatically be created. Stripe will record the
invoice ID and process the payment. If the payment is successful, the status of
the payment will switch from `pending` to `succeeded`.
### Failed payments
If the payment fails, the status of the payment will switch from `pending` to
`failed` and Lago will generate an `invoice.payment_failure`
[webhook](/api-reference/webhooks/messages).
### Payments requiring validation
When a payment requires multi-step authentication, such as 3D Secure (3DS), Lago triggers a `payment.requires_action` [webhook](/api-reference/webhooks/messages#payment-requires-action).
This webhook provides the details for completing the 3DS process. Depending on your integration, you'll get a Stripe Checkout URL or details
to use in your integration (like with Stripe Link).
The invoice will be marked `pending` and the payment as `processing` until the 3DS process is completed.
It's important to note that payments in Europe can request 3DS due to [SCA regulations](https://stripe.com/en-fr/guides/strong-customer-authentication)
and most payments in India require 3DS authentication due to [RBI regulations](https://www.rbi.org.in/Scripts/NotificationUser.aspx?Id=12051\&Mode=0).
### Minimum payment amount
If the new invoice amount falls below the [minimum amount supported by Stripe](https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts), the payment status will remain as `pending`.
A valid payment method for the customer must be defined in Stripe for the
payment intent to succeed ([learn how to save payment
details](https://stripe.com/docs/payments/save-and-reuse)).
## Payment disputes
In the event of a **lost** payment dispute within Stripe, Lago initiates an automatic response by marking the relevant invoice as disputed lost. This action involves populating the `dispute_lost_at` field with the timestamp when the dispute was lost. Following this update:
* The invoice becomes non-voidable;
* Generating a credit note is possible; however, refunding the payment back to the original payment method is not permitted; and
* The invoice cannot be resent for collection.
## Restricted Stripe API key
In case you're using Lago Cloud, and want to limit the scope granted to the Stripe API key which is shared with Lago, you can create a [restricted Stripe API key](https://docs.stripe.com/keys-best-practices#limit-access). At minimum, you'll need to grant it the following resource permissions, otherwise Stripe integration will not work properly:
* Core
* Charges - `Write` (to create refunds when creating credit notes)
* Customers - `Write`
* Events - `Read` (to receive webhooks with event details)
* Funding Instructions - `Write` (to create and read bank details)
* Payment Intents - `Write` (to create payments)
* Payment Methods - `Write` (to update customer's payment methods)
* Checkout
* Checkout Sessions - `Write` (to generate checkout URLs)
* Webhook
* Webhook Endpoints - `Write` (to create and update webhooks)
# Anrok
Source: https://getlago.com/docs/integrations/taxes/anrok
Lago's native integration with Anrok allows you to automatically update your invoices with tax amounts sourced directly from Anrok. This integration ensures compliance with international tax regulations by calculating taxes for US & non-US obligations, like VAT.
**PREMIUM FEATURE** ✨
This feature is only available to users with a premium license. Please
**[contact us](mailto:hello@getlago.com)** to get access to Lago Cloud and Lago
Self-Hosted Premium.
## Overview
Lago’s integration with [Anrok](https://www.anrok.com/request-demo?utm_source=lago\&utm_medium=partner_website\&utm_campaign=evergreen) simplifies tax calculation and reporting by syncing invoice amounts with Anrok for filing.
When an invoice is in draft status, Lago generates an ephemeral transaction in Anrok to calculate the preliminary taxes. Once the invoice is finalized, Lago creates a permanent transaction in Anrok to calculate the final taxes, marking it for reporting to the appropriate tax authority via Anrok.
To calculate the appropriate tax for each line item, Lago sends the customer’s address, tax identifier (if applicable), and the relevant product ID to Anrok. Anrok then calculates the tax for the invoice and returns the data to Lago, which is used to update the invoice with accurate tax information. Additionally, Lago synchronizes updates for voided and disputed invoices, as well as any credit notes created, ensuring that your records remain up to date.
## Prerequisites
1. **Premium feature**: To access Anrok via Lago, you’ll need to be under the Premium license.
2. **Getting Started**: We recommend reviewing the [Anrok Getting Started Guide](https://help-center.anrok.com/hc/en-us/categories/4410165176339-Getting-Started-Guide) before initiating the setup process.
3. **Anrok Account**: Ensure you have an Anrok account. Ideally, test the connection via an Anrok sandbox account to your Lago test account. Contact the Anrok team to request a free sandbox account.
4. **Physical Nexus**: Make sure you are correctly recording physical nexus in Anrok. Add or manage your physical nexus through the "Jurisdictions" tab by clicking the “Manage Physical Nexus” button.
5. **Products in Anrok**: Create products in Anrok, assigning a tax configuration to each product you sell in Lago. You will need the IDs of these products when setting up the Anrok integration in Lago (see the mapping below).
6. **Customer Exemptions in Anrok**: If necessary, upload valid exemption certificates for your customers in Anrok. Ensure that when you create a customer profile in Lago, you use the same customer ID as in Anrok. This consistency allows Lago to correctly identify the customer and apply the exemption certificates when calculating taxes.
## Connect Anrok to Lago
Lago allows you to connect your different Anrok instances. For example, you could connect both a sandbox and a production Anrok account. To do so:
1. In Lago, please go to Settings > Integration
2. Click on Anrok
3. Define a name and code for this connection; and
4. Enter your Anrok API key
### Mapping items between Lago and Anrok (mandatory)
To synchronize invoices and retrieve tax data, Lago needs to establish a one-to-one relationship between its objects and Anrok products.
**You can define tax mappings per Lago entity when different entities require distinct Anrok Product IDs**. If the same mapping applies across entities, configure a default mapping. It will be used for any entity that doesn't have a specific override.
Follow these steps to map an item:
1. In Anrok, navigate to the **Products IDs** section.
2. Click on a product and **copy its Product ID.**
3. In Lago, navigate to **Integration** > **Anrok** > **Mapping**.
4. Choose the item you want to associate with the Product ID selected in step 2.
5. **Paste the Product ID to map the item** — repeat this action for all items in Lago that require mapping.
The invoice will be marked as `failed` if any item requiring tax calculation from Anrok is not properly mapped and no fallback item is provided.
### Mapping a fallback item (mandatory)
The fallback item serves as a backup and is used if the mapping of other items is not defined. This dummy item ensures continuous data synchronization between Lago and Anrok in the event of mapping issues.
## Customer configuration for tax calculation
### Customer synchronization
When creating or updating a Lago customer, you can choose to link it to an existing Anrok customer.
The first option is to **automatically create a new customer from Lago to Anrok**. Follow these steps:
1. Create or update a new Lago customer;
2. Select the targeted Anrok connection;
3. Check the box labeled ‘Create this customer automatically in Anrok’; and
4. Save and create this new customer.
If the customer is successfully created in Anrok, a new field will be displayed in the Lago customer view, providing a direct link to the corresponding Anrok customer.
The second option is to **import an existing Anrok customer to a Lago customer**. Follow these steps:
1. Create or update a Lago customer;
2. Select the targeted Anrok connection;
3. Ensure the box labeled ‘Create this customer automatically in Anrok’ is unchecked;
4. Paste the Anrok customer ID in the appropriate field; and
5. Save and create this new customer.
If the customer is successfully synced in Anrok, a new field will be displayed in the Lago customer view, providing a direct link to the corresponding Anrok customer.
Please note that in both cases, the customer will be created in Anrok after the first invoice is synchronized.
### Address requirements
Anrok requires that each customer in Lago has a valid shipping address. If a shipping address is not available, Lago will default to using the billing address for tax calculation purposes. If both addresses are invalid or missing, Lago will be unable to generate the invoice, and the invoice status will be marked as failed. In such cases, you will be notified of the failure in the dashboard and via webhook.
### Tax identifier
If a customer has a `tax_identification_number` configured in Lago, this ID will be sent to Anrok for tax calculation and reporting. This ID is essential for determining whether the transaction is subject to a reverse charge in eligible VAT countries.
### Tax exempt customers
For customers who qualify for tax exemptions, you need to create a Certificate in your Anrok dashboard. Ensure that the customer profile in Lago uses the same customer ID as in Anrok in the Anrok customer ID. This consistency allows Lago to correctly identify the customer and apply the exemption certificates when calculating taxes.
## Current usage
Lago queries Anrok for the current usage and wallet ongoing balance. To ensure the best experience, Lago caches the results of current usage taxes for 24 hours.
## Error management
### Refresh draft invoice with tax errors
When an invoice is in `draft` and encounters a tax synchronization error, you have the option to refresh the invoice to recalculate the tax. The invoice remains editable during this process, and the error will not prevent the invoice from being `finalized`. However, if the error persists after attempting to finalize the invoice, the invoice will be marked as `failed`.
### Retry synchronization for failed invoice
When an invoice fails due to a tax synchronization error, you have the option to manually re-sync each invoice individually from the invoice details page or via this [endpoint](/api-reference/invoices/retry_finalization). Alternatively, you can go to the integration settings and trigger a bulk invoice synchronization.
### Retry synchronization for voided / disputed invoices
When an invoice is voided or disputed, Lago will sync this updated record with Anrok to ensure your reports are accurate. If the sync fails, you will be notified via webhook. In that case, please manually resync the voided or disputed invoice through the dashboard.
### Retry synchronization for credit notes
When a credit note is created, Lago will sync this record with Anrok to ensure your reports are accurate. If the sync fails, you will be notified via webhook. In that case, please manually resync the credit note through the dashboard.
### Pay in advance non invoiceable charge
Lago will notify you via webhook if a tax error occurs when a non-invoiceable fee paid in advance is generated. The fee will not be created. Please note that you will need to fix the issue and resend the event to generate the fee. For any assistance, please contact the Lago team.
### Tax error scenario
If Lago is unable to generate an invoice or sync it to Anrok, you will be alerted via the dashboard and webhook.
Tax synchronization and invoice generation can fail due to the following reasons:
1. Incorrect connection settings (API key).
2. Items used in objects or fallback items not mapped.
3. Missing customer shipping or billing address.
4. Timeout or internal service error.
Tax synchronization can fail during the following processes:
1. Calculating taxes in one-off-invoice form
2. Refreshing a draft invoice
3. Finalizing an invoice
4. Generating a fee paid in advance non-invoiceable
5. Fetching current usage
6. Voiding an invoice
7. Disputing an invoice
8. Creating a credit note
If an issue arises, please check the mapping, verify the customer address and launch a synchronization; or contact the Lago team for assistance.
# Avalara
Source: https://getlago.com/docs/integrations/taxes/avalara
Lago's native integration with Avalara allows you to automatically update your invoices with tax amounts sourced directly from Avalara. This integration ensures compliance with international tax regulations by calculating taxes for US & non-US obligations, like VAT.
**PREMIUM ADD-ON** ✨
This integration is available upon request only. Please **[contact us](mailto:hello@getlago.com)** to get access to this premium feature.
## Overview
Lago’s native integration with **AvaTax** (by Avalara) enables seamless tax calculation, application, and reporting throughout the invoicing process.
When an invoice is in `draft` status, Lago creates a `SalesOrder` in AvaTax to estimate the applicable taxes.
This preliminary calculation allows teams to preview tax amounts before finalizing the invoice.
Once the invoice is `finalized` in Lago, a corresponding `SalesInvoice` is created in AvaTax.
This marks the transaction as final and eligible for reporting to the appropriate tax authorities, ensuring compliance and traceability.
To calculate tax, Lago includes both the `ShipFrom` and `ShipTo` addresses for each invoice.
AvaTax uses these details to apply tax rules based on the nexus jurisdictions you’ve configured in your Avalara account.
The calculated tax data is returned from AvaTax and automatically applied to the Lago invoice.
Lago also keeps your records in sync by automatically updating AvaTax whenever an invoice is voided or disputed, or when a credit note is issued.
This ensures that your tax reporting in Avalara remains accurate and up to date at all times.
## Prerequisites
1. **Premium add-on feature**: To access Avatax via Lago, you must have access to the Premium add-on. If you don’t already have it enabled, please reach out to us for assistance.
2. **Getting Started**: We strongly recommend reviewing the [AvaTax Getting Started Guide](https://developer.avalara.com/documentation/sales-and-use-tax/) to familiarize yourself with the requirements and configuration steps.
3. **Billing entity address**: For accurate tax calculation, Avalara requires a valid ShipFrom address. This corresponds to the billing entity’s account address and must be configured in the Lago dashboard under **Settings > Entity > General information**.
4. **Nexus in Avalara**: Make sure your Avalara account is properly set up with all `nexus` jurisdictions. These are the states or regions where you are obligated to collect and remit sales tax.
5. **Customer exemptions**: If necessary, upload valid exemption certificates for your customers in Avalara. Ensure that when you create a customer profile in Lago, you use the same customer ID as in Avalara. This consistency allows Lago to correctly identify the customer and apply the exemption certificates when calculating taxes.
## Connect AvaTax to Lago
Lago supports connections to multiple AvaTax instances, enabling you to integrate both sandbox and production environments seamlessly.
**To connect an AvaTax instance:**
1. Navigate to **Settings > Integrations** in your Lago dashboard
2. Select **Avalara** from the available integrations
3. Create a unique name and code to identify this connection
4. Enter your Avalara credentials: Account ID, License key and Company code
5. Click **Create** to establish the connection
### Mapping items between Lago and Avalara (mandatory)
To synchronize invoices and retrieve tax data, Lago needs to establish a one-to-one relationship between its objects and Avalara products.
**You can define tax mappings per Lago entity when different entities require distinct Avalara Product IDs**. If the same mapping applies across entities, configure a default mapping. It will be used for any entity that doesn't have a specific override.
Follow these steps to map an item:
1. Navigate to the [Avalara Tax Code search](https://taxcode.avatax.avalara.com/) documentation page.
2. Click on a product and **copy its Tax code.**
3. In Lago, navigate to **Integration** > **Avalara** > **Mapping**.
4. Choose the item you want to associate with the Tax code selected in step 2.
5. **Paste the Tax code to map the item** — repeat this action for all items in Lago that require mapping.
The invoice will be marked as `failed` if any item requiring tax calculation from Avalara is not properly mapped and no fallback item is provided.
### Mapping a fallback item (mandatory)
The fallback item serves as a backup and is used if the mapping of other items is not defined.
This dummy item ensures continuous data synchronization between Lago and Avalara in the event of mapping issues.
## Customer configuration for tax calculation
### Customer synchronization
When creating or updating a Lago customer, you can establish a connection to an existing Avalara customer or automatically create a new one.
**Automatically creating a new Avalara customer**
To create a new customer in Avalara directly from Lago:
1. Create or update a Lago customer;
2. Ensure the customer has a valid address;
3. Verify the customer's state uses valid two or three-character ISO 3166 region codes;
4. Select your target Avalara connection;
5. Check the box labeled "Create this customer automatically in Avalara"; and
6. Save the customer to complete the process.
**Results:**
* **Success**: A new field appears in the Lago customer information tab with a direct link to the corresponding Avalara customer
* **Failure**: The `customer.tax_provider_error` webhook is triggered to notify you of any issues
**Importing an existing Avalara customer**
To link a Lago customer to an existing Avalara customer:
1. Create or update a Lago customer
2. Select your target Avalara connection
3. Ensure the box labeled "Create this customer automatically in Avalara" is unchecked
4. Enter the existing Avalara customer ID in the designated field
5. Save the customer to complete the import
**Results**:
* **Success**: A new field appears in the Lago customer information tab with with a direct link to the corresponding Avalara customer
* **Failure**: The `customer.tax_provider_error` webhook is triggered if the sync encounters issues
### Address requirements
Avalara requires that each customer in Lago has a valid shipping address with a valid state following the two or three character **ISO 3166 region codes**.
If a shipping address is not available, Lago will default to using the billing address for tax calculation purposes.
If both addresses are invalid or missing, Lago will be unable to generate the invoice, and the invoice status will be marked as failed.
In such cases, you will be notified of the failure in the dashboard and via webhook.
### Customer exemptions
If you need to apply exemptions to a customer, you can upload valid exemption certificates for your customers in Avalara.
Ensure that when you create a customer profile in Lago, you use the same customer ID as in Avalara.
This consistency allows Lago to correctly identify the customer and apply the exemption certificates when calculating taxes.
### Tax identifier
If a customer has a `tax_identification_number` configured in Lago, this ID will be sent to Avalara for tax calculation and reporting. This ID is essential for determining whether the transaction is subject to a reverse charge in eligible VAT countries.
### Tax exempt customers
For customers who qualify for tax exemptions, you need to create a Certificate in your Avalara dashboard. Ensure that the customer profile in Lago uses the same customer ID as in Avalara in the Avalara customer ID. This consistency allows Lago to correctly identify the customer and apply the exemption certificates when calculating taxes.
## Current usage
Lago queries Avalara for the current usage and wallet ongoing balance. To ensure the best experience, Lago caches the results of current usage taxes for 24 hours.
## Error management
### Refresh draft invoice with tax errors
When an invoice is in `draft` and encounters a tax synchronization error, you have the option to refresh the invoice to recalculate the tax. The invoice remains editable during this process, and the error will not prevent the invoice from being `finalized`. However, if the error persists after attempting to finalize the invoice, the invoice will be marked as `failed`.
### Retry synchronization for failed invoice
When an invoice fails due to a tax synchronization error, you have the option to manually re-sync each invoice individually from the invoice details page or via this [endpoint](/api-reference/invoices/retry_finalization). Alternatively, you can go to the integration settings and trigger a bulk invoice synchronization.
### Retry synchronization for voided / disputed invoices
When an invoice is voided or disputed, Lago will sync this updated record with Avalara to ensure your reports are accurate. If the sync fails, you will be notified via webhook. In that case, please manually resync the voided or disputed invoice through the dashboard.
### Retry synchronization for credit notes
When a credit note is created, Lago will sync this record with Avalara to ensure your reports are accurate. If the sync fails, you will be notified via webhook. In that case, please manually resync the credit note through the dashboard.
### Pay in advance non invoiceable charge
Lago will notify you via webhook if a tax error occurs when a non-invoiceable fee paid in advance is generated. The fee will not be created. Please note that you will need to fix the issue and resend the event to generate the fee. For any assistance, please contact the Lago team.
### Tax error scenario
If Lago is unable to generate an invoice or sync it to Avalara, you will be alerted via the dashboard and webhook.
Tax synchronization and invoice generation can fail due to the following reasons:
1. Incorrect connection settings (API key).
2. Items used in objects or fallback items not mapped.
3. Missing customer shipping or billing address.
4. Timeout or internal service error.
Tax synchronization can fail during the following processes:
1. Calculating taxes in one-off-invoice form
2. Refreshing a draft invoice
3. Finalizing an invoice
4. Generating a fee paid in advance non-invoiceable
5. Fetching current usage
6. Voiding an invoice
7. Disputing an invoice
8. Creating a credit note
If an issue arises, please check the mapping, verify the customer address and launch a synchronization; or contact the Lago team for assistance.
# Lago EU Taxes
Source: https://getlago.com/docs/integrations/taxes/lago-eu-taxes
Lago now features an automatic European tax detection integration for your customers.
## Enable Lago's EU Tax integration
Activate Lago's automatic EU tax detection in just a few steps:
1. Navigate to your Lago instance **Settings**;
2. Select the **'Lago EU Tax Management'** integration;
3. Enter or confirm your organization's country; and
4. Hit **'Connect'** to activate this integration.
## Automated EU tax rates detection
When you connect the Lago EU Tax Management integration, it automatically generates a list of standard European tax rates.
These rates, labeled as `automated` in Lago, are synchronized with the latest standard tax rates for European countries,
ensuring your tax calculations are always up-to-date and compliant.
Each tax rate begins with the `lago_` prefix, ensuring a uniform and easily identifiable format across your tax rate list.
This systematic approach simplifies the management and recognition of these automated tax entries within your system.
## Auto-application of taxes: decision tree
Before applying standard B2B/B2C rules, Lago checks the customer's **postal code** to detect EU special territories — regions that are outside EU VAT territory or have reduced rates despite belonging to an EU member state. If a match is found, the territory-specific rate is applied and VIES validation is skipped.
If no special territory is detected, Lago's next step involves verifying if a customer has a `tax_identification_number`. This check occurs whenever a customer's profile is created or updated, ensuring that the most current tax-related information is used in subsequent processes.
## Special territory detection
When a customer has a `zipcode` set, Lago matches it against known special territory postal code patterns. If matched, the standard country rate is overridden with the territory's exception rate.
Make sure to set the **zipcode** on your customer profile. Without a postal code, Lago falls back to the standard country rate and special territory detection is skipped.
The following 17 territories are supported across 7 EU countries:
| Country | Territory | Tax Code | Postal Code Pattern | Rate |
| -------- | --------------------- | -------------------------------------------- | ------------------- | --------------- |
| Spain | Canary Islands | `lago_eu_es_exception_canary_islands` | 35xxx, 38xxx | 0% |
| Spain | Ceuta | `lago_eu_es_exception_ceuta` | 51xxx | 0% |
| Spain | Melilla | `lago_eu_es_exception_melilla` | 52xxx | 0% |
| France | Guadeloupe | `lago_eu_fr_exception_guadeloupe` | 971xx | 8.5% (B2B only) |
| France | Martinique | `lago_eu_fr_exception_martinique` | 972xx | 8.5% (B2B only) |
| France | Guyane | `lago_eu_fr_exception_guyane` | 973xx | 0% (B2B only) |
| France | Réunion | `lago_eu_fr_exception_reunion` | 974xx | 8.5% (B2B only) |
| France | Mayotte | `lago_eu_fr_exception_mayotte` | 976xx | 0% (B2B only) |
| Germany | Büsingen am Hochrhein | `lago_eu_de_exception_busingen_am_hochrhein` | 78266 | 0% |
| Germany | Heligoland | `lago_eu_de_exception_heligoland` | 27498 | 0% |
| Italy | Livigno | `lago_eu_it_exception_livigno` | 23041 | 0% |
| Italy | Campione d'Italia | `lago_eu_it_exception_campione_d_italia` | 22061 | 0% |
| Portugal | Azores | `lago_eu_pt_exception_azores` | 95xx | 18% |
| Portugal | Madeira | `lago_eu_pt_exception_madeira` | 9xxx | 22% |
| Austria | Jungholz | `lago_eu_at_exception_jungholz` | 6691, 6992 | 19% |
| Austria | Mittelberg | `lago_eu_at_exception_mittelberg` | 6991, 6993 | 19% |
| Greece | Mount Athos | `lago_eu_gr_exception_mount_athos` | 63086 | 0% |
**France DOM-TOM exception:** For French overseas territories (Guadeloupe, Martinique, Guyane, Réunion, Mayotte), the exception rate only applies to **B2B customers** (those with a `tax_identification_number`). B2C customers in these territories are charged the standard French rate of 20%, in line with French tax law (CGI Articles 294–296).
### B2B tax decision process
When a `tax_identification_number` is identified on a customer profile, Lago conducts a real-time verification
using the [EU's VAT Information Exchange System (VIES)](https://ec.europa.eu/taxation_customs/vies/#/vat-validation) to
confirm the existence of the company.
**In case the VIES check matches a valid company:**
1. If the customer's company is registered in the same country as your organization, Lago applies the customer
country's tax rate;
2. If the customer's company is registered in the same country as your organization, but there is a tax exception for a particular zipcode, Lago applies the tax exception of this specific zipcode; or
3. If the customer's company is registered in a different country than your organization, Lago implements a
**reverse charge** mechanism, applying a 0% tax rate.
### B2C tax decision process
If the VIES check does not confirm an active company or if no `tax_identification_number` is provided,
Lago then assesses the `country` associated with your customer. Based on this:
1. If your customer's `country` is unspecified, Lago defaults to applying your organization's country tax rate; or
2. If your customer's `country` is within the European Union, Lago applies the tax rate corresponding your customer's EU country; or
3. If your customer's `country` is outside the European Union, Lago applies a **tax exempt** rate at 0%.
## Guidelines for VIES checks by Lago
Lago performs VIES verifications under these circumstances:
* The Lago EU Tax Management integration is activated;
* A customer profile is either created or updated. Changes in customer details could influence their applicable tax rates;
* Zipcodes are important to define tax exceptions. Make sure to define them for all your customers; and
* When a new tax rate is identified for a customer, Lago automatically updates the customer's profile by replacing the old tax rate with the new one.
## Logging VIES verifications
Lago ensures transparency and compliance by logging each VIES check. This occurs whenever you create or update a customer.
For each check, Lago dispatches a webhook message. This allows you to record these validations for compliance purposes.
You can access and review any of these automated checks as needed.
# Hightouch
Source: https://getlago.com/docs/integrations/usage/hightouch
Hightouch is a Data Activation platform that syncs data from sources (database, warehouses, spreadsheet and much more) to business applications and developer tools. This data can be sent to Lago, our usage-based billing platform, to automate your billing process and ensure accurate invoicing for your customers.
Here's a step-by-step guide to help you get started:
## Prerequisites
**In Lago:**
1. Create a Lago organization to manage your billing and invoicing;
2. Create a Billable metric to track the usage of your customers;
3. Create a Plan and price the above billable metric to determine the billing rates for your customers; and
4. Create a Customer and assign the Plan.
**In Hightouch:**
1. Create a Hightouch account;
2. Create a data source (ideally, product usage of your customer);
3. Create a **HTTP Request** destination.
## Send usage from Hightouch to Lago
### Create a data source
To accomplish this, you'll need first to create a source in Hightouch. This can be done by following these simple steps:
1. Navigate to the **Sources** tab;
2. Add a **new source**; and
3. Choose and set up a data source that is available in Hightouch (it could be a database, a warehouse or a spreadsheet, for instance).
### Use the HTTP Request destination
Lago uses Hightouch's HTTP Request to ingest usage. Here is how to set it up:
1. Go to the **Destinations** tab;
2. Select the **HTTP Request** destination;
3. Define your **Headers**. Lago requires `Authorization` (secret, used for the API Key) and `Content-Type: application/json` headers; and
4. Save this newly created destination.
### Create a Sync
In order to send usage from Hightouch to Lago, you will have to create a new **Sync**. To do so, go in the **Syncs** tab and create a new sync from a source to this HTTP Request destination.
1. Configure when you want to trigger the event (row added, row deleted, row updated);
2. Define `POST` as the targeted HTTP Method;
3. Define the targeted url (for usage events, use `https://api.getlago.com/api/v1/events`);
4. Send data as `JSON` and use the JSON editor;
5. Define rate limits, if applicable
### Example of JSON payload
You can define manually the JSON payload that will be sent to Lago. Note that Hightouch supports Liquid template language to insert variables from your source to your JSON payload. These variables are created following this syntax: `"{{ row.variable }}"`, *"variable"* being the column name of your source.
Here is a JSON payload example to send usage events to Lago:
```json theme={"dark"}
{
"event": {
"transaction_id": "{{ row.transactionId }}",
"external_customer_id": "{{ row.customerId }}",
"code": "invoice_created",
"properties": {
"invoice_id": "{{ row.invoiceId }}"
}
}
}
```
The `body` structure of the event depends on your use case. Please adapt it if needed (*ie: remove or add properties*).
### Test and activate your sync
Note that you can test your sync with a data sample. As a result of this test, you should see data flowing into Lago, in the events list. Once you are ready to go, you can activate this sync, and define the periodic trigger.
## Hightouch to Lago - demo video
If easier, please find a demo video explaining the full setup to send events from Hightouch to Lago.
# Segment
Source: https://getlago.com/docs/integrations/usage/segment
Segment is a powerful tool that allows you to track the usage of your customers, providing valuable insights that can help you make data-driven decisions. This data can be sent to Lago, our usage-based billing platform, to automate your billing process and ensure accurate invoicing for your customers.
Here's a step-by-step guide to help you get started:
## Prerequisites
**In Lago:**
1. Create a Lago organization to manage your billing and invoicing;
2. Create a Billable metric to track the usage of your customers;
3. Create a Plan and price the above billable metric to determine the billing rates for your customers; and
4. Create a Customer and assign the Plan.
**In Segment:**
1. Create a Segment account;
2. Create a data source (ideally, product usage of your customer);
## Send usage from Segment to Lago
### Create a function
To accomplish this, you'll need to create a custom **Function** in Segment. This can be done by following these simple steps:
1. Navigate to the **Catalog** in Segment;
2. Click the **Functions** tab to access the custom Functions feature;
3. Choose to create your first function and follow the prompts to set it up.
### Use the Destination function
Make sure to select the **Destination function**, as you want to send data from Segment to Lago.
### Post Request to Lago events
To successfully integrate Lago with Segment, you'll need to replace the pre-written functions in the code editor with the following code. This example function, written by the Lago team, will catch a **Track** event from Segment, define the targeted endpoint (events) in Lago, build the body of the request, and finally post the event.
```javascript theme={"dark"}
// Running everytime a Track call is made on Segment
async function onTrack(event, settings) {
// events endpoint to reach
const endpoint = 'https://api.getlago.com/api/v1/events';
// body of the event following Lago documentation
const body = {
event: {
transactionId: event.messageId,
externalCustomerId: event.userId,
code: event.event,
properties: {
invoiceId: event.properties.invoice_id
}
}
};
// Post event
const response = await fetch(endpoint, {
method: 'POST',
headers: {
'Authorization': `Bearer ${settings.api}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
return response.json();
}
```
This function can be adapted with Identify, Group or Page events. Please, refer to [Segment's documentation](https://segment.com/docs/connections/functions/destination-functions/) for all available actions.
The `body` structure of the event depends on your use case. Please adapt it if needed (*ie: remove or add properties*). You can also add conditions if you want to send data to Lago only on specific events.
### Use the test mode editor
By using a sample event, you can preview the incoming data fetched from a Segment event. This will help you post a request for existing data or debug.
### Hide sensitive data
Let's take back the example from the code written above. We decided to hide the **API Key** and mark it as sensitive information. By setting this as a variable, you make sure not to hard code your private key in the function.
To create **Settings** variables:
1. Go to the **Settings** tab;
2. **Add** a new Setting;
3. Define a **Name** and a **Label** for this Settings;
4. Define it as **Required** or **Optional**; and
5. Mark is as **Sensitive** or not.
### Send usage events to Lago
By running the function in Segment, this will send a test usage to Lago events. You can retrieve this event in the events list. By finalizing the setup in Segment, the function will be automatically triggered based on your defined behavior
## Segment to Lago - demo video
If easier, please find a demo video explaining the full setup of custom functions to send event from Segment.com to Lago.
# Clone Segment pricing
Source: https://getlago.com/docs/templates/hybrid/segment
Replicate Segment's hybrid pricing model with Lago.
Build a hybrid pricing and billing system like [Segment](https://segment.com/), the Customer Data Platform leader, based on subscription plans, with a usage-based component that makes your revenue grow with your users.
## Pricing structure
Segment offers three pricing plans, called 'Free', 'Team' and 'Business'. As the latter has a custom pricing, we will focus on the first two plans.
| Plan | Free plan | Team plan |
| --------------------------- | ---------- | ----------------- |
| Subscription Fee | \$0/month | \$120/month |
| Base Consumption (included) | 1,000 MTUs | 10,000 MTUs |
| Consumption (10k-25k MTUs) | n/a | \$0.012/month/MTU |
| Consumption (25k-100k MTUs) | n/a | \$0.011/month/MTU |
| Consumption (100k+ MTUs) | n/a | \$0.010/month/MTU |
| Trial Period | n/a | 14 days |
The usage-based component in Segment's pricing is related to **monthly tracked users (MTUs)**, namely the number of unique users whose data is stored on the platform each month.
## Get started
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__API_KEY__')
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
```
```javascript Javascript theme={"dark"}
import { Client } from 'lago-javascript-client';
const client = Client('__API_KEY__');
```
```go Go theme={"dark"}
package main
import (
"context"
lago "github.com/getlago/lago-go-client"
)
client := lago.New().SetApiKey("__API_KEY__")
ctx := context.TODO()
```
Create a billable metric to track unique users with deduplication.
1. Set the `aggregation_type` to `unique_count_agg` for counting unique users
2. Set the `field_name` to `user_id` to identify individual users
3. Set `recurring` to `false` for metered billing
```bash cURL highlight={7,9-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Monthly Tracked Users",
"code": "__BILLABLE_METRIC_CODE__",
"description": "Unique users tracked monthly",
"aggregation_type": "unique_count_agg",
"field_name": "user_id",
"recurring": false
}
}'
```
```python Python highlight={5,7-9,12} theme={"dark"}
from lago_python_client.models import BillableMetric
billable_metric = BillableMetric(
name='Monthly Tracked Users',
code='__BILLABLE_METRIC_CODE__',
description='Unique users tracked monthly',
aggregation_type='unique_count_agg',
field_name='user_id',
recurring=False
)
client.billable_metrics.create(billable_metric)
```
```ruby Ruby highlight={3,5-7} theme={"dark"}
client.billable_metrics.create({
name: 'Monthly Tracked Users',
code: '__BILLABLE_METRIC_CODE__',
description: 'Unique users tracked monthly',
aggregation_type: 'unique_count_agg',
field_name: 'user_id',
recurring: false
})
```
```javascript JavaScript highlight={3,5-7,10} theme={"dark"}
const billableMetric = {
name: 'Monthly Tracked Users',
code: '__BILLABLE_METRIC_CODE__',
description: 'Unique users tracked monthly',
aggregation_type: 'unique_count_agg',
field_name: 'user_id',
recurring: false
};
await client.billableMetrics.createBillableMetric({ billableMetric });
```
```go Go highlight={3,5-7,10} theme={"dark"}
billableMetricInput := &lago.BillableMetricInput{
Name: "Monthly Tracked Users",
Code: "__BILLABLE_METRIC_CODE__",
Description: "Unique users tracked monthly",
AggregationType: "unique_count_agg",
FieldName: "user_id",
Recurring: false,
}
billableMetric, err := client.BillableMetric().Create(ctx, billableMetricInput)
```
Create a Team plan with subscription fee and graduated usage charges.
1. Set the `amount_cents` to `12000` for \$120 monthly subscription
2. Set `pay_in_advance` to `true` for upfront payment
3. Set `trial_period` to `14` days for the trial period
4. Configure `graduated_ranges` with Segment's tiered pricing structure
```bash cURL expandable highlight={7,10-47} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Segment Team Plan",
"code": "__PLAN_CODE__",
"interval": "monthly",
"description": "Team plan with subscription and graduated usage",
"amount_cents": 12000,
"amount_currency": "USD",
"pay_in_advance": true,
"trial_period": 14,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "graduated",
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10000,
"flat_amount": "0",
"per_unit_amount": "0"
},
{
"from_value": 10001,
"to_value": 25000,
"flat_amount": "0",
"per_unit_amount": "0.012"
},
{
"from_value": 25001,
"to_value": 100000,
"flat_amount": "0",
"per_unit_amount": "0.011"
},
{
"from_value": 100001,
"to_value": null,
"flat_amount": "0",
"per_unit_amount": "0.010"
}
]
}
}
]
}
}'
```
```python Python expandable highlight={3-34,38,41,43-45,48} theme={"dark"}
from lago_python_client.models import Plan, Charge
charge = Charge(
billable_metric_id='__BILLABLE_METRIC_ID__',
charge_model='graduated',
properties={
'graduated_ranges': [
{
'from_value': 0,
'to_value': 10000,
'flat_amount': '0',
'per_unit_amount': '0'
},
{
'from_value': 10001,
'to_value': 25000,
'flat_amount': '0',
'per_unit_amount': '0.012'
},
{
'from_value': 25001,
'to_value': 100000,
'flat_amount': '0',
'per_unit_amount': '0.011'
},
{
'from_value': 100001,
'to_value': None,
'flat_amount': '0',
'per_unit_amount': '0.010'
}
]
}
)
plan = Plan(
name='Segment Team Plan',
code='__PLAN_CODE__',
interval='monthly',
description='Team plan with subscription and graduated usage',
amount_cents=12000,
amount_currency='USD',
pay_in_advance=True,
trial_period=14,
charges=[charge]
)
client.plans.create(plan)
```
```ruby Ruby expandable highlight={3,6,8-43} theme={"dark"}
client.plans.create({
name: 'Segment Team Plan',
code: '__PLAN_CODE__',
interval: 'monthly',
description: 'Team plan with subscription and graduated usage',
amount_cents: 12000,
amount_currency: 'USD',
pay_in_advance: true,
trial_period: 14,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'graduated',
properties: {
graduated_ranges: [
{
from_value: 0,
to_value: 10000,
flat_amount: '0',
per_unit_amount: '0'
},
{
from_value: 10001,
to_value: 25000,
flat_amount: '0',
per_unit_amount: '0.012'
},
{
from_value: 25001,
to_value: 100000,
flat_amount: '0',
per_unit_amount: '0.011'
},
{
from_value: 100001,
to_value: nil,
flat_amount: '0',
per_unit_amount: '0.010'
}
]
}
}
]
})
```
```javascript JavaScript expandable highlight={3,6,8-43,46} theme={"dark"}
const plan = {
name: 'Segment Team Plan',
code: '__PLAN_CODE__',
interval: 'monthly',
description: 'Team plan with subscription and graduated usage',
amount_cents: 12000,
amount_currency: 'USD',
pay_in_advance: true,
trial_period: 14,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'graduated',
properties: {
graduated_ranges: [
{
from_value: 0,
to_value: 10000,
flat_amount: '0',
per_unit_amount: '0'
},
{
from_value: 10001,
to_value: 25000,
flat_amount: '0',
per_unit_amount: '0.012'
},
{
from_value: 25001,
to_value: 100000,
flat_amount: '0',
per_unit_amount: '0.011'
},
{
from_value: 100001,
to_value: null,
flat_amount: '0',
per_unit_amount: '0.010'
}
]
}
}
]
};
await client.plans.createPlan({ plan });
```
```go Go expandable highlight={3,6,8-43,46} theme={"dark"}
planInput := &lago.PlanInput{
Name: "Segment Team Plan",
Code: "__PLAN_CODE__",
Interval: "monthly",
Description: "Team plan with subscription and graduated usage",
AmountCents: 12000,
AmountCurrency: "USD",
PayInAdvance: true,
TrialPeriod: 14,
Charges: []*lago.PlanChargeInput{
{
BillableMetricID: "__BILLABLE_METRIC_ID__",
ChargeModel: "graduated",
Properties: map[string]interface{}{
"graduated_ranges": []map[string]interface{}{
{
"from_value": 0,
"to_value": 10000,
"flat_amount": "0",
"per_unit_amount": "0",
},
{
"from_value": 10001,
"to_value": 25000,
"flat_amount": "0",
"per_unit_amount": "0.012",
},
{
"from_value": 25001,
"to_value": 100000,
"flat_amount": "0",
"per_unit_amount": "0.011",
},
{
"from_value": 100001,
"to_value": nil,
"flat_amount": "0",
"per_unit_amount": "0.010",
},
},
},
},
},
}
plan, err := client.Plan().Create(ctx, planInput)
```
Create a customer with a unique `external_id`.
```bash cURL highlight={6} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "Acme Inc",
"email": "john@acme.com",
"currency": "USD",
"timezone": "America/New_York"
}
}'
```
```python Python highlight={4,11} theme={"dark"}
from lago_python_client.models import Customer
customer = Customer(
external_id="__EXTERNAL_CUSTOMER_ID__",
name="Acme Inc",
email="john@acme.com",
currency="USD",
timezone="America/New_York"
)
client.customers.create(customer)
```
```ruby Ruby highlight={2} theme={"dark"}
client.customers.create(
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
)
```
```js Javascript highlight={2,9} theme={"dark"}
const customer = {
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
};
await client.customers.createCustomer({ customer });
```
```go Go highlight={2,9} theme={"dark"}
customerInput := &lago.CustomerInput{
ExternalID: "__EXTERNAL_CUSTOMER_ID__",
Name: "Acme Inc",
Email: "john@acme.com",
Currency: "USD",
Timezone: "America/New_York",
}
customer, err := client.Customer().Create(ctx, customerInput)
```
Refer to the [API reference](/api-reference/customers/create) to create a customer.
Create a subscription for the customer with the plan's `code`.
```bash cURL highlight={6-8} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"plan_code": "__PLAN_CODE__",
"external_id": "__EXTERNAL_SUBSCRIPTION_ID__"
}
}'
```
```python Python highlight={4-6,9} theme={"dark"}
from lago_python_client.models import Subscription
subscription = Subscription(
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
plan_code="__PLAN_CODE__",
external_id="__EXTERNAL_SUBSCRIPTION_ID__"
)
client.subscriptions.create(subscription)
```
```ruby Ruby highlight={2-4} theme={"dark"}
client.subscriptions.create(
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
)
```
```js Javascript highlight={2-4,7} theme={"dark"}
const subscription = {
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
};
await client.subscriptions.createSubscription({ subscription });
```
```go Go highlight={2-4,7} theme={"dark"}
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
PlanCode: "__PLAN_CODE__",
ExternalID: "__EXTERNAL_SUBSCRIPTION_ID__",
}
subscription, err := client.Subscription().Create(ctx, subscriptionInput)
```
Refer to the [API reference](/api-reference/subscriptions/assign-plan) to create a subscription.
Refer to [API reference](/api-reference/subscriptions/assign-plan) and [guide on assigning plans](/guide/subscriptions/assign-plan) in the documentation.
Send usage events to Lago to track usage.
1. Reference your billable metric with `code`
2. Reference the customer's subscription with `external_subscription_id`
3. Include usage and filters data in `properties`
```bash cURL highlight={7-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__TRANSACTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"properties": {
"user_id": "user_id_001"
}
}
}'
```
```python Python highlight={5-9,11} theme={"dark"}
from lago_python_client.models import Event
event = Event(
transaction_id='__TRANSACTION_ID__',
code='__BILLABLE_METRIC_CODE__',
external_subscription_id='__EXTERNAL_SUBSCRIPTION_ID__',
properties={
'user_id': 'user_id_001'
}
)
client.events.create(event)
```
```ruby Ruby highlight={3-7} theme={"dark"}
client.events.create({
transaction_id: '__TRANSACTION_ID__',
code: '__BILLABLE_METRIC_CODE__',
external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__',
properties: {
user_id: 'user_id_001'
}
})
```
```javascript JavaScript highlight={3-7,10} theme={"dark"}
const event = {
transaction_id: '__TRANSACTION_ID__',
code: '__BILLABLE_METRIC_CODE__',
external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__',
properties: {
user_id: 'user_id_001'
}
};
await client.events.createEvent({ event });
```
```go Go highlight={3-7,10} theme={"dark"}
eventInput := &lago.EventInput{
TransactionID: "__TRANSACTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Properties: map[string]interface{}{
"user_id": "user_id_001",
},
}
event, err := client.Event().Create(ctx, eventInput)
```
Refer to the [API reference](/api-reference/events/usage) to create an event.
Track real-time customer usage for the current billing period.
```bash cURL highlight={1} theme={"dark"}
curl --location --request GET "$LAGO_URL/api/v1/customers/__EXTERNAL_CUSTOMER_ID__/current_usage?external_subscription_id=__EXTERNAL_SUBSCRIPTION_ID__" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json'
```
```python Python highlight={1} theme={"dark"}
customer_usage = client.customers.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```ruby Ruby highlight={1} theme={"dark"}
customer_usage = client.customer.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```js Javascript highlight={1-4} theme={"dark"}
const customerUsage = await client.customers.findCustomerCurrentUsage(
'__EXTERNAL_CUSTOMER_ID__',
{ external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__' }
)
```
```go Go highlight={1} theme={"dark"}
customerUsage, err := client.Customer().CurrentUsage(ctx, "__EXTERNAL_CUSTOMER_ID__")
```
Refer to the [API reference](/api-reference/customer-usage/get-current) to get the current usage.
## Wrap-up
Hybrid pricing plans are very popular among SaaS, API, fintech and data companies like Segment.
With Lago, you can easily adapt this template to create your own hybrid pricing plan, using some of our most popular features:
* **Plan models**, including monthly/yearly plans that can be paid in advance or in arrears;
* **Billable metrics**, including multiple aggregation types; and
* **Charges**, including our graduated pricing model (and more).
Give it a try, click [here](https://www.getlago.com/get-started) to get started!
# Introduction
Source: https://getlago.com/docs/templates/introduction
Replicate these popular B2B pricing templates to kickstart your journey with Lago.
Whether you are an API company, a fintech scale-up, an established SaaS provider or an early-stage data platform, find the pricing template that meets your needs and discover how Lago can help you implement it.
Interactive demos showcasing different billing models using Lago's JavaScript SDK.
## Per-token pricing (AI)
}
href="/templates/per-token/mistral"
>
Build a transparent per-token pricing like Mistral, the famous AI company,
with multiple dimensions and prepaid credits.
}
href="/templates/per-token/openai"
>
Replicate OpenAI's per-token pricing, the famous AI company behind GPT
models, with multiple dimensions based on models and action types.
## Hybrid pricing
}
href="/templates/hybrid/segment"
>
Build a hybrid pricing and billing system like Segment, the CDP leader,
based on subscription plans, with a usage-based component that makes your
revenue grow with your users.
## Per-transaction pricing
}
href="/templates/per-transaction/stripe"
>
Implement a per-transaction pricing model like Stripe, the leading payments
infrastructure company, including fees based on the total amount and number
of transactions.
## Pay-as-you-go pricing
}
href="/templates/payg/algolia"
>
Discover how Algolia, the search and discovery platform, increases
conversion with commitment-free pricing options that adapt to customers’
needs.
}
href="/templates/payg/bigquery"
>
Implement a pay-as-you-go pricing model and offer free upfront credits to new users like Google BigQuery, the data analytics platform.
## Per-seat pricing
}
href="/templates/per-seat/notion"
>
Set up a per-user pricing like Notion, the collaboration software for
innovative teams, including plans based on the number of users and prepaid
credits.
# Clone Algolia pricing
Source: https://getlago.com/docs/templates/payg/algolia
Replicate Algolia's pay-as-you-go pricing model with Lago.
In this article, you will learn how to build a 'pay-as-you-go' billing system.
This template is suitable for companies whose pricing fully depends on usage, such as cloud service providers and API companies, that only charge their customers for the resources they consume.
## Pricing structure
For one of its products, Algolia Search, the platform offers its customers to subscribe for free and only pay based on usage.
| Model | Search API |
| ----------------------- | ----------------------- |
| Monthly price | \$1.50 / 1,000 requests |
| Free usage (each month) | 10,000 requests |
Although users don't need to subscribe to access the platform, Algolia offers its customers **discounts** based on volume and commitment (rates available upon request).
## Get started
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__API_KEY__')
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
```
```javascript Javascript theme={"dark"}
import { Client } from 'lago-javascript-client';
const client = Client('__API_KEY__');
```
```go Go theme={"dark"}
package main
import (
"context"
lago "github.com/getlago/lago-go-client"
)
client := lago.New().SetApiKey("__API_KEY__")
ctx := context.TODO()
```
Create billable metrics to track request usage for Search and Recommend APIs.
1. Set the `aggregation_type` to `sum_agg` to sum all request volumes
2. Set the `field_name` to `search_requests_volume` for Search API tracking
3. Set the `recurring` to `false` for metered billing
```bash cURL highlight={7,9-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Search API Requests",
"code": "__BILLABLE_METRIC_CODE__",
"description": "Search API request volume",
"aggregation_type": "sum_agg",
"field_name": "search_requests_volume",
"recurring": false
}
}'
```
```python Python highlight={5,7-9,12} theme={"dark"}
from lago_python_client.models import BillableMetric
billable_metric = BillableMetric(
name='Search API Requests',
code='__BILLABLE_METRIC_CODE__',
description='Search API request volume',
aggregation_type='sum_agg',
field_name='search_requests_volume',
recurring=False,
)
client.billable_metrics.create(billable_metric)
```
```ruby Ruby highlight={3,5-7} theme={"dark"}
client.billable_metrics.create({
name: 'Search API Requests',
code: '__BILLABLE_METRIC_CODE__',
description: 'Search API request volume',
aggregation_type: 'sum_agg',
field_name: 'search_requests_volume',
recurring: false
})
```
```javascript JavaScript highlight={3,5-7,10} theme={"dark"}
const billable_metric = {
name: 'Search API Requests',
code: '__BILLABLE_METRIC_CODE__',
description: 'Search API request volume',
aggregationType: 'sum_agg',
fieldName: 'search_requests_volume',
recurring: false
};
await client.billableMetrics.create({ billable_metric })
```
```go Go highlight={3,5-10} theme={"dark"}
billableMetricInput := &lago.BillableMetricInput{
Name: "Search API Requests",
Code: "__BILLABLE_METRIC_CODE__",
Description: "Search API request volume",
AggregationType: "sum_agg",
FieldName: "search_requests_volume",
Recurring: false,
}
billableMetric, err := client.BillableMetric().Create(ctx, billableMetricInput)
```
Create a plan to price packages of requests used.
1. Set the `amount_cents` to `0` since there is no subscription fee
2. Set the `charges` to use `package` pricing model with Algolia's rates
3. Configure `free_units` of 10,000 requests per month included
```bash cURL highlight={7,10,13-23} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Algolia Search",
"code": "__PLAN_CODE__",
"interval": "monthly",
"description": "Pay-as-you-go pricing for Algolia Search API",
"amount_cents": 0,
"amount_currency": "USD",
"pay_in_advance": false,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "package",
"properties": {
"amount": "1.50",
"free_units": 10000,
"package_size": 1000
}
}
]
}
}'
```
```python Python highlight={3-11,15,18,21,24} theme={"dark"}
from lago_python_client.models import Plan, Charge
charge = Charge(
billable_metric_id='__BILLABLE_METRIC_ID__',
charge_model='package',
properties={
'amount': '1.50',
'free_units': 10000,
'package_size': 1000
}
)
plan = Plan(
name='Algolia Search PAYG',
code='__PLAN_CODE__',
interval='monthly',
description='Pay-as-you-go pricing for Search API',
amount_cents=0,
amount_currency='USD',
pay_in_advance=False,
charges=[charge]
)
client.plans.create(plan)
```
```ruby Ruby highlight={3,6,9-19} theme={"dark"}
client.plans.create({
name: 'Algolia Search PAYG',
code: '__PLAN_CODE__',
interval: 'monthly',
description: 'Pay-as-you-go pricing for Search API',
amount_cents: 0,
amount_currency: 'USD',
pay_in_advance: false,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'package',
properties: {
amount: '1.50',
free_units: 10000,
package_size: 1000
}
}
]
})
```
```javascript JavaScript highlight={3,6,9-19,22} theme={"dark"}
const plan = {
name: 'Algolia Search PAYG',
code: '__PLAN_CODE__',
interval: 'monthly',
description: 'Pay-as-you-go pricing for Search API',
amount_cents: 0,
amount_currency: 'USD',
pay_in_advance: false,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'package',
properties: {
amount: '1.50',
free_units: 10000,
package_size: 1000
}
}
]
};
await client.plans.createPlan({ plan })
```
```go Go highlight={3,6,9-19,22} theme={"dark"}
planInput := &lago.PlanInput{
Name: "Algolia Search PAYG",
Code: "__PLAN_CODE__",
Interval: "monthly",
Description: "Pay-as-you-go pricing for Search API",
AmountCents: 0,
AmountCurrency: "USD",
PayInAdvance: false,
Charges: []*lago.PlanChargeInput{
{
BillableMetricID: "__BILLABLE_METRIC_ID__",
ChargeModel: "package",
Properties: map[string]interface{}{
"amount": "1.50",
"free_units": 10000,
"package_size": 1000,
},
},
},
}
plan, err := client.Plan().Create(ctx, planInput)
```
Refer to the [API reference](/api-reference/plans/create) and [guide on package charges](/guide/plans/charges/charge-models/package) to learn more.
Create a customer with a unique `external_id`.
```bash cURL highlight={6} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "Acme Inc",
"email": "john@acme.com",
"currency": "USD",
"timezone": "America/New_York"
}
}'
```
```python Python highlight={4,11} theme={"dark"}
from lago_python_client.models import Customer
customer = Customer(
external_id="__EXTERNAL_CUSTOMER_ID__",
name="Acme Inc",
email="john@acme.com",
currency="USD",
timezone="America/New_York"
)
client.customers.create(customer)
```
```ruby Ruby highlight={2} theme={"dark"}
client.customers.create(
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
)
```
```js Javascript highlight={2,9} theme={"dark"}
const customer = {
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
};
await client.customers.createCustomer({ customer });
```
```go Go highlight={2,9} theme={"dark"}
customerInput := &lago.CustomerInput{
ExternalID: "__EXTERNAL_CUSTOMER_ID__",
Name: "Acme Inc",
Email: "john@acme.com",
Currency: "USD",
Timezone: "America/New_York",
}
customer, err := client.Customer().Create(ctx, customerInput)
```
Refer to the [API reference](/api-reference/customers/create) to create a customer.
Create a subscription for the customer with the plan's `code`.
```bash cURL highlight={6-8} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"plan_code": "__PLAN_CODE__",
"external_id": "__EXTERNAL_SUBSCRIPTION_ID__"
}
}'
```
```python Python highlight={4-6,9} theme={"dark"}
from lago_python_client.models import Subscription
subscription = Subscription(
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
plan_code="__PLAN_CODE__",
external_id="__EXTERNAL_SUBSCRIPTION_ID__"
)
client.subscriptions.create(subscription)
```
```ruby Ruby highlight={2-4} theme={"dark"}
client.subscriptions.create(
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
)
```
```js Javascript highlight={2-4,7} theme={"dark"}
const subscription = {
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
};
await client.subscriptions.createSubscription({ subscription });
```
```go Go highlight={2-4,7} theme={"dark"}
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
PlanCode: "__PLAN_CODE__",
ExternalID: "__EXTERNAL_SUBSCRIPTION_ID__",
}
subscription, err := client.Subscription().Create(ctx, subscriptionInput)
```
Refer to the [API reference](/api-reference/subscriptions/assign-plan) to create a subscription.
Send usage events to Lago to track API requests.
1. Set the `code` to match your billable metric code
2. Include `search_requests_volume` property with the number of requests
```bash cURL highlight={7-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__TRANSACTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"properties": {
"search_requests_volume": 5000
}
}
}'
```
```python Python highlight={5-9,12} theme={"dark"}
from lago_python_client.models import Event
event = Event(
transaction_id="__TRANSACTION_ID__",
code="__BILLABLE_METRIC_CODE__",
external_subscription_id="__EXTERNAL_SUBSCRIPTION_ID__",
properties={
"search_requests_volume": 5000
}
)
client.events.create(event)
```
```ruby Ruby highlight={3-7} theme={"dark"}
client.events.create(
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
search_requests_volume: 5000
}
)
```
```js Javascript highlight={3-7,10} theme={"dark"}
const event = {
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
search_requests_volume: 5000
}
};
await client.events.createEvent({ event });
```
```go Go highlight={3-7,10} theme={"dark"}
eventInput := &lago.EventInput{
TransactionID: "__TRANSACTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Properties: map[string]interface{}{
"search_requests_volume": 5000,
},
}
event, err := client.Event().Create(ctx, eventInput)
```
Refer to the [API reference](/api-reference/events/usage) to create an event.
Track real-time customer usage for the current billing period.
```bash cURL highlight={1} theme={"dark"}
curl --location --request GET "$LAGO_URL/api/v1/customers/__EXTERNAL_CUSTOMER_ID__/current_usage?external_subscription_id=__EXTERNAL_SUBSCRIPTION_ID__" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json'
```
```python Python highlight={1} theme={"dark"}
customer_usage = client.customers.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```ruby Ruby highlight={1} theme={"dark"}
customer_usage = client.customer.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```js Javascript highlight={1-4} theme={"dark"}
const customerUsage = await client.customers.findCustomerCurrentUsage(
'__EXTERNAL_CUSTOMER_ID__',
{ external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__' }
)
```
```go Go highlight={1} theme={"dark"}
customerUsage, err := client.Customer().CurrentUsage(ctx, "__EXTERNAL_CUSTOMER_ID__")
```
Refer to the [API reference](/api-reference/customer-usage/get-current) to get the current usage.
## Wrap-up
'Pay-as-you-go' pricing strategies are popular among API companies like Algolia.
With Lago, you can adapt this template to your products and services, using some of our most popular features:
1. **Plan models**, with or without subscription;
2. **Billable metrics**, including the 'sum' aggregation type; and
3. **Charges**, including our package and graduated pricing models.
Give it a try, click [here](https://www.getlago.com/get-started) to get started!
# Clone Google BigQuery pricing
Source: https://getlago.com/docs/templates/payg/bigquery
Replicate BigQuery's pay-as-you-go pricing model and offer free upfront credits with Lago.
In this article, you will learn how to offer free upfront credits for new users on a 'pay-as-you-go' pricing model.
This template is fitted for infra companies, like this BigQuery example, but is also widely used among AI companies to let new users try their products easily.
[Mistral](https://mistral.ai/news/2024-ft-hackathon/#:~:text=We%20offer%20%24100%20free%20credits%20to%20selected%20hackathon%20participants) or [Perplexity](https://docs.perplexity.ai/docs/pricing#:~:text=pplx%2Dapi%20implements%20a%20usage,of%20free%20credit%20every%20month) are other great examples.
## Pricing structure
BigQuery offers customers the possibility to subscribe for free and only pay based on usage. For new customers, the platform offers \$300 worth of credits during 90 days to try the product completely for free.
| Plan | Cost per volume of data scanned |
| ----------------- | ---------------------------------------------- |
| On-Demand pricing | \$6.25 per TiB (a measure of compute capacity) |
## Get started
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__API_KEY__')
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
```
```javascript Javascript theme={"dark"}
import { Client } from 'lago-javascript-client';
const client = Client('__API_KEY__');
```
```go Go theme={"dark"}
package main
import (
"context"
lago "github.com/getlago/lago-go-client"
)
client := lago.New().SetApiKey("__API_KEY__")
ctx := context.TODO()
```
Create a billable metric to track data processing volume.
1. Set the `aggregation_type` to `sum_agg` to sum all data processed
2. Set the `field_name` to `data_processed_volume` for tracking usage
3. Set `recurring` to `false` for metered billing
```bash cURL highlight={7,9-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "BigQuery Data Processing",
"code": "__BILLABLE_METRIC_CODE__",
"description": "Data processing volume in TiB",
"aggregation_type": "sum_agg",
"field_name": "data_processed_volume",
"recurring": false
}
}'
```
```python Python highlight={5,7-9,12} theme={"dark"}
from lago_python_client.models import BillableMetric
billable_metric = BillableMetric(
name='BigQuery Data Processing',
code='__BILLABLE_METRIC_CODE__',
description='Data processing volume in TiB',
aggregation_type='sum_agg',
field_name='data_processed_volume',
recurring=False
)
client.billable_metrics.create(billable_metric)
```
```ruby Ruby highlight={3,5-7} theme={"dark"}
client.billable_metrics.create({
name: 'BigQuery Data Processing',
code: '__BILLABLE_METRIC_CODE__',
description: 'Data processing volume in TiB',
aggregation_type: 'sum_agg',
field_name: 'data_processed_volume',
recurring: false
})
```
```javascript JavaScript highlight={3,5-7,10} theme={"dark"}
const billableMetric = {
name: 'BigQuery Data Processing',
code: '__BILLABLE_METRIC_CODE__',
description: 'Data processing volume in TiB',
aggregation_type: 'sum_agg',
field_name: 'data_processed_volume',
recurring: false
};
await client.billableMetrics.createBillableMetric({ billableMetric })
```
```go Go highlight={3,5-7,10} theme={"dark"}
billableMetricInput := &lago.BillableMetricInput{
Name: "BigQuery Data Processing",
Code: "__BILLABLE_METRIC_CODE__",
Description: "Data processing volume in TiB",
AggregationType: "sum_agg",
FieldName: "data_processed_volume",
Recurring: false,
}
billableMetric, err := client.BillableMetric().Create(ctx, billableMetricInput)
```
Refer to the [API reference](/api-reference/billable-metrics/create) to create a billable metric.
Create a plan with graduated pricing to include free tier usage.
1. Set the `amount_cents` to `0` since there is no subscription fee
2. Use `graduated` charge model with BigQuery's \$6.25 per TiB rate
3. Configure first 10 TiB as free, then \$6.25 per TiB after that
```bash cURL highlight={7,10,13-34} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "BigQuery On-Demand",
"code": "__PLAN_CODE__",
"interval": "monthly",
"description": "Pay-as-you-go BigQuery pricing with free tier",
"amount_cents": 0,
"amount_currency": "USD",
"pay_in_advance": false,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "graduated",
"properties": {
"graduated_ranges": [
{
"from_value": 0,
"to_value": 10000,
"per_unit_amount": "0",
"flat_amount": "0"
},
{
"from_value": 10001,
"to_value": null,
"per_unit_amount": "6.25",
"flat_amount": "0"
}
]
}
}
]
}
}'
```
```python Python highlight={3-22,26,29,32,35} theme={"dark"}
from lago_python_client.models import Plan, Charge
charge = Charge(
billable_metric_id='__BILLABLE_METRIC_ID__',
charge_model='graduated',
properties={
'graduated_ranges': [
{
'from_value': 0,
'to_value': 10000,
'per_unit_amount': '0',
'flat_amount': '0'
},
{
'from_value': 10001,
'to_value': None,
'per_unit_amount': '6.25',
'flat_amount': '0'
}
]
}
)
plan = Plan(
name='BigQuery On-Demand',
code='__PLAN_CODE__',
interval='monthly',
description='Pay-as-you-go BigQuery pricing with free tier',
amount_cents=0,
amount_currency='USD',
pay_in_advance=False,
charges=[charge]
)
client.plans.create(plan)
```
```ruby Ruby highlight={3,6,9-30} theme={"dark"}
client.plans.create({
name: 'BigQuery On-Demand',
code: '__PLAN_CODE__',
interval: 'monthly',
description: 'Pay-as-you-go BigQuery pricing with free tier',
amount_cents: 0,
amount_currency: 'USD',
pay_in_advance: false,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'graduated',
properties: {
graduated_ranges: [
{
from_value: 0,
to_value: 10000,
per_unit_amount: '0',
flat_amount: '0'
},
{
from_value: 10001,
to_value: nil,
per_unit_amount: '6.25',
flat_amount: '0'
}
]
}
}
]
})
```
```javascript JavaScript highlight={3,6,9-30,33} theme={"dark"}
const plan = {
name: 'BigQuery On-Demand',
code: '__PLAN_CODE__',
interval: 'monthly',
description: 'Pay-as-you-go BigQuery pricing with free tier',
amount_cents: 0,
amount_currency: 'USD',
pay_in_advance: false,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'graduated',
properties: {
graduated_ranges: [
{
from_value: 0,
to_value: 10000,
per_unit_amount: '0',
flat_amount: '0'
},
{
from_value: 10001,
to_value: null,
per_unit_amount: '6.25',
flat_amount: '0'
}
]
}
}
]
};
await client.plans.createPlan({ plan })
```
```go Go highlight={3,6,9-30,33} theme={"dark"}
planInput := &lago.PlanInput{
Name: "BigQuery On-Demand",
Code: "__PLAN_CODE__",
Interval: "monthly",
Description: "Pay-as-you-go BigQuery pricing with free tier",
AmountCents: 0,
AmountCurrency: "USD",
PayInAdvance: false,
Charges: []*lago.ChargeInput{
{
BillableMetricID: "__BILLABLE_METRIC_ID__",
ChargeModel: "graduated",
Properties: map[string]interface{}{
"graduated_ranges": []map[string]interface{}{
{
"from_value": 0,
"to_value": 10000,
"per_unit_amount": "0",
"flat_amount": "0",
},
{
"from_value": 10001,
"to_value": nil,
"per_unit_amount": "6.25",
"flat_amount": "0",
},
},
},
},
},
}
plan, err := client.Plan().Create(ctx, planInput)
```
Refer to the [API reference](/api-reference/plans/create) and [guide on graduated pricing](/guide/plans/charges/charge-models/graduated) to learn more.
Create a customer with a unique `external_id`.
```bash cURL highlight={6} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "Acme Inc",
"email": "john@acme.com",
"currency": "USD",
"timezone": "America/New_York"
}
}'
```
```python Python highlight={4,11} theme={"dark"}
from lago_python_client.models import Customer
customer = Customer(
external_id="__EXTERNAL_CUSTOMER_ID__",
name="Acme Inc",
email="john@acme.com",
currency="USD",
timezone="America/New_York"
)
client.customers.create(customer)
```
```ruby Ruby highlight={2} theme={"dark"}
client.customers.create(
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
)
```
```js Javascript highlight={2,9} theme={"dark"}
const customer = {
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
};
await client.customers.createCustomer({ customer });
```
```go Go highlight={2,9} theme={"dark"}
customerInput := &lago.CustomerInput{
ExternalID: "__EXTERNAL_CUSTOMER_ID__",
Name: "Acme Inc",
Email: "john@acme.com",
Currency: "USD",
Timezone: "America/New_York",
}
customer, err := client.Customer().Create(ctx, customerInput)
```
Refer to the [API reference](/api-reference/customers/create) to create a customer.
BigQuery lets new users try its product for free by offering upfront credits valid for 90 days. We can replicate this logic using Lago's wallet feature.
1. Create a wallet with \$300 of free credits for the customer
2. Set `expiration_at` to 90 days from now for the trial period
```bash cURL highlight={6,8-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "BigQuery Trial Credits",
"rate_amount": "1.0",
"paid_credits": "300.0",
"granted_credits": "0.0",
"expiration_at": "2024-12-31T23:59:59Z"
}
}'
```
```python Python highlight={5,7-10,13} theme={"dark"}
from lago_python_client.models import Wallet
from datetime import datetime, timedelta
wallet = Wallet(
external_customer_id='__EXTERNAL_CUSTOMER_ID__',
name='BigQuery Trial Credits',
rate_amount='1.0',
paid_credits='300.0',
granted_credits='0.0',
expiration_at=(datetime.now() + timedelta(days=90)).isoformat() + 'Z'
)
client.wallets.create(wallet)
```
```ruby Ruby highlight={2,4-7} theme={"dark"}
client.wallets.create({
external_customer_id: '__EXTERNAL_CUSTOMER_ID__',
name: 'BigQuery Trial Credits',
rate_amount: '1.0',
paid_credits: '300.0',
granted_credits: '0.0',
expiration_at: (Date.today + 90).strftime('%Y-%m-%dT23:59:59Z')
})
```
```javascript JavaScript highlight={2,4-7,10} theme={"dark"}
const wallet = {
external_customer_id: '__EXTERNAL_CUSTOMER_ID__',
name: 'BigQuery Trial Credits',
rate_amount: '1.0',
paid_credits: '300.0',
granted_credits: '0.0',
expiration_at: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString()
}
await client.wallets.createWallet({ wallet })
```
```go Go highlight={4,6-9,12} theme={"dark"}
import "time"
walletInput := &lago.WalletInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
Name: "BigQuery Trial Credits",
RateAmount: "1.0",
PaidCredits: "300.0",
GrantedCredits: "0.0",
ExpirationAt: time.Now().AddDate(0, 0, 90).Format(time.RFC3339),
}
wallet, err := client.Wallet().Create(ctx, walletInput)
```
Refer to the [API reference](/api-reference/wallets/create) to create a wallet.
2. Create a subscription for the customer with the plan's `code`.
```bash cURL highlight={6-8} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"plan_code": "__PLAN_CODE__",
"external_id": "__EXTERNAL_SUBSCRIPTION_ID__"
}
}'
```
```python Python highlight={4-6,9} theme={"dark"}
from lago_python_client.models import Subscription
subscription = Subscription(
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
plan_code="__PLAN_CODE__",
external_id="__EXTERNAL_SUBSCRIPTION_ID__"
)
client.subscriptions.create(subscription)
```
```ruby Ruby highlight={2-4} theme={"dark"}
client.subscriptions.create(
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
)
```
```js Javascript highlight={2-4,7} theme={"dark"}
const subscription = {
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
};
await client.subscriptions.createSubscription({ subscription });
```
```go Go highlight={2-4,7} theme={"dark"}
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
PlanCode: "__PLAN_CODE__",
ExternalID: "__EXTERNAL_SUBSCRIPTION_ID__",
}
subscription, err := client.Subscription().Create(ctx, subscriptionInput)
```
Refer to the [API reference](/api-reference/subscriptions/assign-plan) to create a subscription.
Send usage events to Lago to track usage.
1. Reference your billable metric with `code`
2. Reference the customer's subscription with `external_subscription_id`
3. Include usage and filters data in `properties`
```bash cURL highlight={7-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__TRANSACTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"properties": {
"data_processed_volume": 10
}
}
}'
```
```python Python highlight={5-9} theme={"dark"}
from lago_python_client.models import Event
event = Event(
transaction_id="__TRANSACTION_ID__",
code="__BILLABLE_METRIC_CODE__",
external_subscription_id="__EXTERNAL_SUBSCRIPTION_ID__",
properties={
"data_processed_volume": 10
}
)
client.events.create(event)
```
```ruby Ruby highlight={3-7} theme={"dark"}
client.events.create(
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
data_processed_volume: 10
}
)
```
```js Javascript highlight={3-7,10} theme={"dark"}
const event = {
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
data_processed_volume: 10
}
};
await client.events.createEvent({ event });
```
```go Go highlight={3-7,10} theme={"dark"}
eventInput := &lago.EventInput{
TransactionID: "__TRANSACTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Properties: map[string]interface{}{
"data_processed_volume": 10,
},
}
event, err := client.Event().Create(ctx, eventInput)
```
Refer to the [API reference](/api-reference/events/usage) to create an event.
Track real-time customer usage for the current billing period.
```bash cURL highlight={1} theme={"dark"}
curl --location --request GET "$LAGO_URL/api/v1/customers/__EXTERNAL_CUSTOMER_ID__/current_usage?external_subscription_id=__EXTERNAL_SUBSCRIPTION_ID__" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json'
```
```python Python highlight={1} theme={"dark"}
customer_usage = client.customers.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```ruby Ruby highlight={1} theme={"dark"}
customer_usage = client.customer.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```js Javascript highlight={1-4} theme={"dark"}
const customerUsage = await client.customers.findCustomerCurrentUsage(
'__EXTERNAL_CUSTOMER_ID__',
{ external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__' }
)
```
```go Go highlight={1} theme={"dark"}
customerUsage, err := client.Customer().CurrentUsage(ctx, "__EXTERNAL_CUSTOMER_ID__")
```
Refer to the [API reference](/api-reference/customer-usage/get-current) to get the current usage.
## Wrap-up
Offering free upfront credits is a popular strategy among AI and infra companies with pay-as-you-go models like BigQuery.
With Lago, you can adapt this template to your products and services using:
1. Configure your pay-as-you-go pricing by aggregate using a **billable metric**;
2. Add this billable metric as **graduated charges** to a plan; and
3. Create a **wallet** and add prepaid free credits.
Give it a try, click [here](https://www.getlago.com/get-started) to get started!
# Clone Notion pricing
Source: https://getlago.com/docs/templates/per-seat/notion
Replicate Notion's per-seat pricing model with Lago.
Set up a per-user (or 'per-seat) pricing like [Notion](https://www.notion.so/product), the collaboration software for innovative teams, including plans based on the number of users and prepaid credits.
In this template, you will learn how to build a 'fair' billing system, with charges calculated according to the number of days of use.
This template is suitable for companies whose pricing depends on persistent metrics, such as productivity software (e.g. number of days users are active), fintechs (e.g. number of days payment cards are active) and data platforms (e.g. number of days integrations are active).
## Pricing structure
Notion offers a Personal Pro plan for individuals who want to collaborate with friends or clients, and a Team plan through which members can set up a collaborative workspace. While the Personal Pro plan is limited to one member, the Team plan allows companies to invite as many members as they need.
| Model | Team plan |
| ----- | ---------------------------- |
| Price | \$10 per user billed monthly |
## Get started
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__API_KEY__')
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
```
```javascript Javascript theme={"dark"}
import { Client } from 'lago-javascript-client';
const client = Client('__API_KEY__');
```
```go Go theme={"dark"}
package main
import (
"context"
lago "github.com/getlago/lago-go-client"
)
client := lago.New().SetApiKey("__API_KEY__")
ctx := context.TODO()
```
Create a recurring billable metric to track user activity over time.
1. Add a unique `code` for your billable metric
2. Set the `aggregation_type` to `unique_count_agg` for counting unique users
3. Set the `field_name` to `user_id` to identify individual users
4. Set `recurring` to `true` for persistent tracking across billing periods
```bash cURL highlight={7,9-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Active Users",
"code": "__BILLABLE_METRIC_CODE__",
"description": "Number of active users in the workspace",
"aggregation_type": "unique_count_agg",
"field_name": "user_id",
"recurring": true
}
}'
```
```python Python highlight={5,7-9,12} theme={"dark"}
from lago_python_client.models import BillableMetric
billable_metric = BillableMetric(
name='Active Users',
code='__BILLABLE_METRIC_CODE__',
description='Number of active users in the workspace',
aggregation_type='unique_count_agg',
field_name='user_id',
recurring=True
)
client.billable_metrics.create(billable_metric)
```
```ruby Ruby highlight={3,5-7} theme={"dark"}
client.billable_metrics.create({
name: 'Active Users',
code: '__BILLABLE_METRIC_CODE__',
description: 'Number of active users in the workspace',
aggregation_type: 'unique_count_agg',
field_name: 'user_id',
recurring: true
})
```
```javascript JavaScript highlight={3,5-7,10} theme={"dark"}
const billableMetric = {
name: 'Active Users',
code: '__BILLABLE_METRIC_CODE__',
description: 'Number of active users in the workspace',
aggregation_type: 'unique_count_agg',
field_name: 'user_id',
recurring: true
};
await client.billableMetrics.createBillableMetric({ billableMetric })
```
```go Go highlight={3,5-7,10} theme={"dark"}
billableMetricInput := &lago.BillableMetricInput{
Name: "Active Users",
Code: "__BILLABLE_METRIC_CODE__",
Description: "Number of active users in the workspace",
AggregationType: "unique_count_agg",
FieldName: "user_id",
Recurring: true,
}
billableMetric, err := client.BillableMetric().Create(ctx, billableMetricInput)
```
Refer to the [API reference](/api-reference/billable-metrics/create) and the [guide on recurring metrics](/guide/billable-metrics/recurring-vs-metered) to learn more.
Create a plan with prorated charges for fair per-seat billing.
1. Set the `amount_cents` to `0` since there is no subscription fee
2. Set the `charge_model` to `standard` for simple per-unit pricing
3. Enable `prorated` billing for fair daily calculations
4. Set the `amount` to `10` for \$10 per user per month
```bash cURL highlight={7,13-23} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Team Plan",
"code": "__PLAN_CODE__",
"description": "Per-seat pricing for team collaboration",
"amount_cents": 0,
"amount_currency": "USD",
"interval": "monthly",
"pay_in_advance": false,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "standard",
"invoiceable": true,
"prorated": true,
"properties": {
"amount": "10"
}
}
]
}
}'
```
```python Python highlight={3-11,15,21,24} theme={"dark"}
from lago_python_client.models import Plan, Charge
charge = Charge(
billable_metric_id='__BILLABLE_METRIC_ID__',
charge_model='standard',
invoiceable=True,
prorated=True,
properties={
'amount': '10'
}
)
plan = Plan(
name='Team Plan',
code='__PLAN_CODE__',
description='Per-seat pricing for team collaboration',
amount_cents=0,
amount_currency='USD',
interval='monthly',
pay_in_advance=False,
charges=[charge]
)
client.plans.create(plan)
```
```ruby Ruby highlight={3,9-19} theme={"dark"}
client.plans.create({
name: 'Team Plan',
code: '__PLAN_CODE__',
description: 'Per-seat pricing for team collaboration',
amount_cents: 0,
amount_currency: 'USD',
interval: 'monthly',
pay_in_advance: false,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'standard',
invoiceable: true,
prorated: true,
properties: {
amount: '10'
}
}
]
})
```
```javascript Javascript highlight={3,9-19,22} theme={"dark"}
const plan = {
name: 'Team Plan',
code: '__PLAN_CODE__',
description: 'Per-seat pricing for team collaboration',
amount_cents: 0,
amount_currency: 'USD',
interval: 'monthly',
pay_in_advance: false,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
charge_model: 'standard',
invoiceable: true,
prorated: true,
properties: {
amount: '10'
}
}
]
};
await client.plans.createPlan({ plan })
```
```go Go highlight={3,9-19,22} theme={"dark"}
planInput := &lago.PlanInput{
Name: "Team Plan",
Code: "__PLAN_CODE__",
Description: "Per-seat pricing for team collaboration",
AmountCents: 0,
AmountCurrency: "USD",
Interval: "monthly",
PayInAdvance: false,
Charges: []*lago.PlanChargeInput{
{
BillableMetricID: "__BILLABLE_METRIC_ID__",
ChargeModel: "standard",
Invoiceable: true,
Prorated: true,
Properties: map[string]interface{}{
"amount": "10",
},
},
},
}
plan, err := client.Plan().Create(ctx, planInput)
```
Refer to the [API reference](/api-reference/plans/create) and the [guide on prorated charges](/guide/plans/charges/prorated-vs-full) to learn more.
Create a customer with a unique `external_id`.
```bash cURL highlight={6} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "Acme Inc",
"email": "john@acme.com",
"currency": "USD",
"timezone": "America/New_York"
}
}'
```
```python Python highlight={4,11} theme={"dark"}
from lago_python_client.models import Customer
customer = Customer(
external_id="__EXTERNAL_CUSTOMER_ID__",
name="Acme Inc",
email="john@acme.com",
currency="USD",
timezone="America/New_York"
)
client.customers.create(customer)
```
```ruby Ruby highlight={2} theme={"dark"}
client.customers.create(
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
)
```
```js Javascript highlight={2,9} theme={"dark"}
const customer = {
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
};
await client.customers.createCustomer({ customer });
```
```go Go highlight={2,9} theme={"dark"}
customerInput := &lago.CustomerInput{
ExternalID: "__EXTERNAL_CUSTOMER_ID__",
Name: "Acme Inc",
Email: "john@acme.com",
Currency: "USD",
Timezone: "America/New_York",
}
customer, err := client.Customer().Create(ctx, customerInput)
```
Refer to the [API reference](/api-reference/customers/create) to create a customer.
Create a subscription for the customer with the plan's `code`.
```bash cURL highlight={6-8} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"plan_code": "__PLAN_CODE__",
"external_id": "__EXTERNAL_SUBSCRIPTION_ID__"
}
}'
```
```python Python highlight={4-6,9} theme={"dark"}
from lago_python_client.models import Subscription
subscription = Subscription(
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
plan_code="__PLAN_CODE__",
external_id="__EXTERNAL_SUBSCRIPTION_ID__"
)
client.subscriptions.create(subscription)
```
```ruby Ruby highlight={2-4} theme={"dark"}
client.subscriptions.create(
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
)
```
```js Javascript highlight={2-4,7} theme={"dark"}
const subscription = {
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
};
await client.subscriptions.createSubscription({ subscription });
```
```go Go highlight={2-4,7} theme={"dark"}
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
PlanCode: "__PLAN_CODE__",
ExternalID: "__EXTERNAL_SUBSCRIPTION_ID__",
}
subscription, err := client.Subscription().Create(ctx, subscriptionInput)
```
Refer to the [API reference](/api-reference/subscriptions/assign-plan) to create a subscription.
Send usage events to Lago to track usage.
1. Reference your billable metric with `code`
2. Reference the customer's subscription with `external_subscription_id`
3. Include `user_id` in properties to track individual users
4. Set `operation_type` to `add` when adding users, `remove` when removing
```bash cURL highlight={7-12} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__TRANSACTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"properties": {
"user_id": "user_123",
"operation_type": "add"
}
}
}'
```
```python Python highlight={5-10,13} theme={"dark"}
from lago_python_client.models import Event
event = Event(
transaction_id='__TRANSACTION_ID__',
code='__BILLABLE_METRIC_CODE__',
external_subscription_id='__EXTERNAL_SUBSCRIPTION_ID__',
properties={
'user_id': 'user_123',
'operation_type': 'add'
}
)
client.events.create(event)
```
```ruby Ruby highlight={3-8} theme={"dark"}
client.events.create({
transaction_id: '__TRANSACTION_ID__',
code: '__BILLABLE_METRIC_CODE__',
external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__',
properties: {
user_id: 'user_123',
operation_type: 'add'
}
})
```
```javascript Javascript highlight={3-8,11} theme={"dark"}
const event = {
transaction_id: '__TRANSACTION_ID__',
code: '__BILLABLE_METRIC_CODE__',
external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__',
properties: {
user_id: 'user_123',
operation_type: 'add'
}
};
await client.events.createEvent({ event })
```
```go Go highlight={3-8,11} theme={"dark"}
eventInput := &lago.EventInput{
TransactionID: "__TRANSACTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Properties: map[string]interface{}{
"user_id": "user_123",
"operation_type": "add",
},
}
event, err := client.Event().Create(ctx, eventInput)
```
Refer to the [API reference](/api-reference/events/usage) to create an event.
Track real-time customer usage for the current billing period.
```bash cURL highlight={1} theme={"dark"}
curl --location --request GET "$LAGO_URL/api/v1/customers/__EXTERNAL_CUSTOMER_ID__/current_usage?external_subscription_id=__EXTERNAL_SUBSCRIPTION_ID__" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json'
```
```python Python highlight={1} theme={"dark"}
customer_usage = client.customers.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```ruby Ruby highlight={1} theme={"dark"}
customer_usage = client.customer.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```js Javascript highlight={1-4} theme={"dark"}
const customerUsage = await client.customers.findCustomerCurrentUsage(
'__EXTERNAL_CUSTOMER_ID__',
{ external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__' }
)
```
```go Go highlight={1} theme={"dark"}
customerUsage, err := client.Customer().CurrentUsage(ctx, "__EXTERNAL_CUSTOMER_ID__")
```
Refer to the [API reference](/api-reference/customer-usage/get-current) to get the current usage.
## Wrap-up
For software companies like Notion, implementing a 'fair' per-user pricing model is a good way to **increase transparency and customer satisfaction**.
With Lago, you can create your own persistent metrics to adapt this template to your products and services.
Give it a try, click [here](https://www.getlago.com/get-started) to get started!
# Clone Mistral pricing
Source: https://getlago.com/docs/templates/per-token/mistral
Replicate Mistral's per-token pricing model with Lago.
In this article, you will learn how Mistral is using Lago to build a billing system based on AI tokens.
This template is suitable for Large Language Model (LLM) and Generative AI companies whose pricing can vary based on the application or model used.
## Pricing structure
For Mistral, pricing depends on the language model used. Here are several price points they offer:
Prices are per 1M tokens used. You can think of tokens as pieces of words (learn more [here](https://mistral.ai/technology/#models))."
| Models | Input | Output |
| -------------- | ----------------- | ----------------- |
| mistral-small | \$1 / 1M tokens | \$3 / 1M tokens |
| mistral-medium | \$2.7 / 1M tokens | \$8.1 / 1M tokens |
| mistral-large | \$4 / 1M tokens | \$12 / 1M tokens |
## Get started
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__API_KEY__')
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
```
```javascript Javascript theme={"dark"}
import { Client } from 'lago-javascript-client';
const client = Client('__API_KEY__');
```
```go Go theme={"dark"}
package main
import (
"context"
lago "github.com/getlago/lago-go-client"
)
client := lago.New().SetApiKey("__API_KEY__")
ctx := context.TODO()
```
Create a single billable metric to track token usage across different models and input/output types.
1. Add a unique `code` for your billable metric
2. Set `aggregation_type` to `sum_agg`
3. Set `field_name` to `tokens`
4. Set `recurring` to `false`
5. Set `filters` to distinguish between models and token types
```bash cURL highlight={7,9-21} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "AI Tokens",
"code": "__BILLABLE_METRIC_CODE__",
"description": "Token usage across Mistral AI models",
"aggregation_type": "sum_agg",
"field_name": "tokens",
"recurring": false,
"filters": [
{
"key": "model",
"values": ["mistral-small", "mistral-medium", "mistral-large"]
},
{
"key": "type",
"values": ["input", "output"]
}
]
}
}'
```
```python Python highlight={3-6,8-11,15,17-20,23} theme={"dark"}
from lago_python_client.models import BillableMetric, BillableMetricFilter
model_filter = BillableMetricFilter(
key='model',
values=['mistral-small', 'mistral-medium', 'mistral-large']
)
type_filter = BillableMetricFilter(
key='type',
values=['input', 'output']
)
billable_metric = BillableMetric(
name='Tokens',
code='__BILLABLE_METRIC_CODE__',
description='Token usage across Mistral AI models',
aggregation_type='sum_agg',
field_name='tokens',
recurring=False,
filters=[model_filter, type_filter]
)
client.billable_metrics.create(billable_metric)
```
```ruby Ruby highlight={3,5-17} theme={"dark"}
client.billable_metrics.create({
name: 'Tokens',
code: '__BILLABLE_METRIC_CODE__',
description: 'Token usage across Mistral AI models',
aggregation_type: 'sum_agg',
field_name: 'tokens',
recurring: false,
filters: [
{
key: 'model',
values: ['mistral-small', 'mistral-medium', 'mistral-large']
},
{
key: 'type',
values: ['input', 'output']
}
]
})
```
```js Javascript highlight={3,5-7,8-17,20} theme={"dark"}
const billableMetric = {
name: "Tokens",
code: "__BILLABLE_METRIC_CODE__",
description: "Token usage across Mistral AI models",
aggregation_type: "sum_agg",
field_name: "tokens",
recurring: false,
filters: [
{
key: "model",
values: ["mistral-small", "mistral-medium", "mistral-large"]
},
{
key: "type",
values: ["input", "output"]
}
]
};
await client.billableMetrics.createBillableMetric({ billableMetric });
```
```go Go highlight={3,5-17,20} theme={"dark"}
bmInput := &lago.BillableMetricInput{
Name: "Tokens",
Code: "__BILLABLE_METRIC_CODE__",
Description: "Token usage across Mistral AI models",
AggregationType: lago.SumAggregation,
FieldName: "tokens",
Recurring: false,
Filters: []lago.BillableMetricFilter{
{
Key: "model",
Values: []string{"mistral-small", "mistral-medium", "mistral-large"},
},
{
Key: "type",
Values: []string{"input", "output"},
},
},
}
billableMetric, err := client.BillableMetric().Create(ctx, bmInput)
```
Refer to the [API reference](/api-reference/billable-metrics/create) and [guide on filters](/guide/billable-metrics/filters) to learn more.
Create a plan to price packages of tokens used with Mistral's specific pricing tiers.
1. Add a unique `code` for your plan
2. Under `charges`, configure pricing tiers for different models and token types
```bash cURL expandable highlight={7,12-66} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Mistral AI Pricing",
"code": "__PLAN_CODE__",
"amount_cents": 0,
"amount_currency": "USD",
"interval": "monthly",
"pay_in_advance": false,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "package",
"filters": [
{
"invoice_display_name": "mistral-small-input",
"properties": {
"amount": "1",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["mistral-small"],
"type": ["input"]
}
},
{
"invoice_display_name": "mistral-small-output",
"properties": {
"amount": "3",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["mistral-small"],
"type": ["output"]
}
},
{
"invoice_display_name": "mistral-large-input",
"properties": {
"amount": "4",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["mistral-large"],
"type": ["input"]
}
},
{
"invoice_display_name": "mistral-large-output",
"properties": {
"amount": "12",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["mistral-large"],
"type": ["output"]
}
}
]
}
]
}
}'
```
```python Python expandable highlight={4-8,10-14,16-20,22-26,29-33,37,42,45} theme={"dark"}
from lago_python_client.models import Plan, Charge, ChargeFilter
# Filters for different models and token types
small_input_filter = ChargeFilter(
invoice_display_name="mistral-small-input",
properties={"amount": "1", "free_units": 0, "package_size": 1000000},
values={"model": ["mistral-small"], "type": ["input"]}
)
small_output_filter = ChargeFilter(
invoice_display_name="mistral-small-output",
properties={"amount": "3", "free_units": 0, "package_size": 1000000},
values={"model": ["mistral-small"], "type": ["output"]}
)
large_input_filter = ChargeFilter(
invoice_display_name="mistral-large-input",
properties={"amount": "4", "free_units": 0, "package_size": 1000000},
values={"model": ["mistral-large"], "type": ["input"]}
)
large_output_filter = ChargeFilter(
invoice_display_name="mistral-large-output",
properties={"amount": "12", "free_units": 0, "package_size": 1000000},
values={"model": ["mistral-large"], "type": ["output"]}
)
# Charge for all filters
charge = Charge(
billable_metric_id="__BILLABLE_METRIC_ID__",
charge_model="package",
filters=[small_input_filter, small_output_filter, large_input_filter, large_output_filter]
)
plan = Plan(
name="Mistral Plan",
code="__PLAN_CODE__",
amount_cents=0,
amount_currency="USD",
interval="monthly",
pay_in_advance=False,
charges=[charge]
)
client.plans.create(plan)
```
```ruby Ruby expandable highlight={3,8-35} theme={"dark"}
client.plans.create({
name: "Mistral AI Pricing",
code: "__PLAN_CODE__",
amount_cents: 0,
amount_currency: "USD",
interval: "monthly",
pay_in_advance: false,
charges: [
{
billable_metric_id: "__BILLABLE_METRIC_ID__",
charge_model: "package",
filters: [
{
invoice_display_name: "mistral-small-input",
properties: { amount: "1", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-small"], type: ["input"] }
},
{
invoice_display_name: "mistral-small-output",
properties: { amount: "3", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-small"], type: ["output"] }
},
{
invoice_display_name: "mistral-large-input",
properties: { amount: "4", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-large"], type: ["input"] }
},
{
invoice_display_name: "mistral-large-output",
properties: { amount: "12", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-large"], type: ["output"] }
}
]
}
]
})
```
```js Javascript expandable highlight={3,8-35,38} theme={"dark"}
const plan = {
name: "Mistral AI Pricing",
code: "__PLAN_CODE__",
amount_cents: 0,
amount_currency: "USD",
interval: "monthly",
pay_in_advance: false,
charges: [
{
billable_metric_id: "__BILLABLE_METRIC_ID__",
charge_model: "package",
filters: [
{
invoice_display_name: "mistral-small-input",
properties: { amount: "1", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-small"], type: ["input"] }
},
{
invoice_display_name: "mistral-small-output",
properties: { amount: "3", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-small"], type: ["output"] }
},
{
invoice_display_name: "mistral-large-input",
properties: { amount: "4", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-large"], type: ["input"] }
},
{
invoice_display_name: "mistral-large-output",
properties: { amount: "12", free_units: 0, package_size: 1000000 },
values: { model: ["mistral-large"], type: ["output"] }
}
]
}
]
};
await client.plans.createPlan({ plan });
```
```go Go expandable highlight={3,8-51,54} theme={"dark"}
planInput := &lago.PlanInput{
Name: "Mistral AI Pricing",
Code: "__PLAN_CODE__",
AmountCents: 0,
AmountCurrency: "USD",
Interval: "monthly",
PayInAdvance: false,
Charges: []lago.PlanChargeInput{
{
BillableMetricID: "__BILLABLE_METRIC_ID__",
ChargeModel: "package",
Filters: []lago.ChargeFilter{
{
InvoiceDisplayName: "mistral-small-input",
Properties: map[string]interface{}{
"amount": "1", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"mistral-small"}, "type": []string{"input"},
},
},
{
InvoiceDisplayName: "mistral-small-output",
Properties: map[string]interface{}{
"amount": "3", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"mistral-small"}, "type": []string{"output"},
},
},
{
InvoiceDisplayName: "mistral-large-input",
Properties: map[string]interface{}{
"amount": "4", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"mistral-large"}, "type": []string{"input"},
},
},
{
InvoiceDisplayName: "mistral-large-output",
Properties: map[string]interface{}{
"amount": "12", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"mistral-large"}, "type": []string{"output"},
},
},
},
},
},
}
plan, err := client.Plan().Create(ctx, planInput)
```
Refer to the [API reference](/api-reference/plans/create) and [guide on charges with filters](/guide/plans/charges/charges-with-filters) to learn more.
Create a customer with a unique `external_id`.
```bash cURL highlight={6} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "Acme Inc",
"email": "john@acme.com",
"currency": "USD",
"timezone": "America/New_York"
}
}'
```
```python Python highlight={4,11} theme={"dark"}
from lago_python_client.models import Customer
customer = Customer(
external_id="__EXTERNAL_CUSTOMER_ID__",
name="Acme Inc",
email="john@acme.com",
currency="USD",
timezone="America/New_York"
)
client.customers.create(customer)
```
```ruby Ruby highlight={2} theme={"dark"}
client.customers.create(
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
)
```
```js Javascript highlight={2,9} theme={"dark"}
const customer = {
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
};
await client.customers.createCustomer({ customer });
```
```go Go highlight={2,9} theme={"dark"}
customerInput := &lago.CustomerInput{
ExternalID: "__EXTERNAL_CUSTOMER_ID__",
Name: "Acme Inc",
Email: "john@acme.com",
Currency: "USD",
Timezone: "America/New_York",
}
customer, err := client.Customer().Create(ctx, customerInput)
```
Refer to the [API reference](/api-reference/customers/create) to create a customer.
1. Create a wallet with the customer's `external_customer_id`,
set the wallet `currency` and `rate_amount` for credit conversion
```bash cURL highlight={7,11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/wallets" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"wallet": {
"name": "AI Credits",
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"currency": "USD",
"paid_credits": "100.0",
"granted_credits": "25.0",
"rate_amount": "1.0"
}
}'
```
```python Python highlight={5,9} theme={"dark"}
from lago_python_client.models import Wallet
wallet = Wallet(
name="AI Credits",
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
currency="USD",
paid_credits="100.0",
granted_credits="25.0",
rate_amount="1.0"
)
client.wallets.create(wallet)
```
```ruby Ruby highlight={3,7} theme={"dark"}
client.wallets.create({
name: "AI Credits",
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
currency: "USD",
paid_credits: "100.0",
granted_credits: "25.0",
rate_amount: "1.0"
})
```
```js Javascript highlight={3,7,10} theme={"dark"}
const wallet = {
name: "AI Credits",
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
currency: "USD",
paid_credits: 100.0,
granted_credits: 25.0,
rate_amount: 1.0
};
await client.wallets.createWallet({ wallet });
```
```go Go highlight={3,7,10} theme={"dark"}
walletInput := &lago.WalletInput{
Name: "AI Credits",
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
Currency: "USD",
PaidCredits: "100.0",
GrantedCredits: "25.0",
RateAmount: "1.0",
}
wallet, err := lagoClient.Wallet().Create(walletInput)
```
Refer to the [API reference](/api-reference/wallets/create) to create a wallet.
2. Create a subscription for the customer with the plan's `code`.
```bash cURL highlight={6-8} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"plan_code": "__PLAN_CODE__",
"external_id": "__EXTERNAL_SUBSCRIPTION_ID__"
}
}'
```
```python Python highlight={4-6,9} theme={"dark"}
from lago_python_client.models import Subscription
subscription = Subscription(
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
plan_code="__PLAN_CODE__",
external_id="__EXTERNAL_SUBSCRIPTION_ID__"
)
client.subscriptions.create(subscription)
```
```ruby Ruby highlight={2-4} theme={"dark"}
client.subscriptions.create(
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
)
```
```js Javascript highlight={2-4,7} theme={"dark"}
const subscription = {
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
};
await client.subscriptions.createSubscription({ subscription });
```
```go Go highlight={2-4,7} theme={"dark"}
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
PlanCode: "__PLAN_CODE__",
ExternalID: "__EXTERNAL_SUBSCRIPTION_ID__",
}
subscription, err := client.Subscription().Create(ctx, subscriptionInput)
```
Refer to the [API reference](/api-reference/subscriptions/assign-plan) to create a subscription.
Send usage events to Lago to track usage.
1. Reference your billable metric with `code`
2. Reference the customer's subscription with `external_subscription_id`
3. Include usage and filters data in `properties`
```bash cURL highlight={7-13} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__TRANSACTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"properties": {
"tokens": 2000000,
"model": "mistral-small",
"type": "input"
}
}
}'
```
```python Python highlight={5-11} theme={"dark"}
from lago_python_client.models import Event
event = Event(
transaction_id="__TRANSACTION_ID__",
code="__BILLABLE_METRIC_CODE__",
external_subscription_id="__EXTERNAL_SUBSCRIPTION_ID__",
properties={
"tokens": 2000000,
"model": "mistral-small",
"type": "input"
}
)
client.events.create(event)
```
```ruby Ruby highlight={3-9} theme={"dark"}
client.events.create(
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
tokens: 2000000,
model: "mistral-small",
type: "input"
}
)
```
```js Javascript highlight={3-9,12} theme={"dark"}
const event = {
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
tokens: 2000000,
model: "mistral-small",
type: "input"
}
};
await client.events.createEvent({ event });
```
```go Go highlight={3-9,12} theme={"dark"}
eventInput := &lago.EventInput{
TransactionID: "__TRANSACTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Properties: map[string]interface{}{
"tokens": 2000000,
"model": "mistral-small",
"type": "input",
},
}
event, err := client.Event().Create(ctx, eventInput)
```
Refer to the [API reference](/api-reference/events/usage) to create an event.
Track real-time customer usage for the current billing period.
```bash cURL highlight={1} theme={"dark"}
curl --location --request GET "$LAGO_URL/api/v1/customers/__EXTERNAL_CUSTOMER_ID__/current_usage?external_subscription_id=__EXTERNAL_SUBSCRIPTION_ID__" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json'
```
```python Python highlight={1} theme={"dark"}
customer_usage = client.customers.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```ruby Ruby highlight={1} theme={"dark"}
customer_usage = client.customer.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```js Javascript highlight={1-4} theme={"dark"}
const customerUsage = await client.customers.findCustomerCurrentUsage(
'__EXTERNAL_CUSTOMER_ID__',
{ external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__' }
)
```
```go Go highlight={1} theme={"dark"}
customerUsage, err := client.Customer().CurrentUsage(ctx, "__EXTERNAL_CUSTOMER_ID__")
```
Refer to the [API reference](/api-reference/customer-usage/get-current) to get the current usage.
## Wrap-up
Per-token pricing offers flexibility and visibility, and allows LLM and Generative AI companies like Mistral to attract more customers.
With Lago, you can create your own metric dimensions to adapt this template to your products and services.
Give it a try, click [here](https://www.getlago.com/get-started) to get started!
# Clone OpenAI pricing
Source: https://getlago.com/docs/templates/per-token/openai
Replicate OpenAI's per-token pricing model with Lago.
In this article, you will learn how to build a billing system with Lago based on tokens.
This template is suitable for Large Language Model (LLM) and Generative AI companies whose pricing can vary based on the application or model used.
## Pricing structure
For OpenAI, pricing depends on the language model used. Here are several price points they offer:
*"Prices are per 1,000 tokens. You can think of tokens as pieces of words, where 1,000 tokens is about 750 words (learn more [here](https://platform.openai.com/tokenizer))."*
| Model | Input | Output |
| ----------- | --------------------- | --------------------- |
| 8K context | \$0.03 / 1,000 tokens | \$0.06 / 1,000 tokens |
| 32K context | \$0.06 / 1,000 tokens | \$0.12 / 1,000 tokens |
## Get started
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__API_KEY__')
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
```
```javascript Javascript theme={"dark"}
import { Client } from 'lago-javascript-client';
const client = Client('__API_KEY__');
```
```go Go theme={"dark"}
package main
import (
"context"
lago "github.com/getlago/lago-go-client"
)
client := lago.New().SetApiKey("__API_KEY__")
ctx := context.TODO()
```
Create a single billable metric to track token usage across different models and input/output types.
1. Add a unique `code` for your billable metric
2. Set `aggregation_type` to `sum_agg`
3. Set `field_name` to `tokens`
4. Set `recurring` to `false`
5. Set `filters` to distinguish between models and token types
```bash cURL highlight={7,9-21} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "AI Tokens",
"code": "__BILLABLE_METRIC_CODE__",
"description": "Token usage across OpenAI models",
"aggregation_type": "sum_agg",
"field_name": "tokens",
"recurring": false,
"filters": [
{
"key": "model",
"values": ["8k", "32k"]
},
{
"key": "type",
"values": ["input", "output"]
}
]
}
}'
```
```python Python highlight={3-6,8-11,15,17-20,23} theme={"dark"}
from lago_python_client.models import BillableMetric, BillableMetricFilter
model_filter = BillableMetricFilter(
key='model',
values=['8k', '32k']
)
type_filter = BillableMetricFilter(
key='type',
values=['input', 'output']
)
billable_metric = BillableMetric(
name='Tokens',
code='__BILLABLE_METRIC_CODE__',
description='Token usage across OpenAI models',
aggregation_type='sum_agg',
field_name='tokens',
recurring=False,
filters=[model_filter, type_filter]
)
client.billable_metrics.create(billable_metric)
```
```ruby Ruby highlight={3,5-17} theme={"dark"}
client.billable_metrics.create({
name: 'Tokens',
code: '__BILLABLE_METRIC_CODE__',
description: 'Token usage across OpenAI models',
aggregation_type: 'sum_agg',
field_name: 'tokens',
recurring: false,
filters: [
{
key: 'model',
values: ['8k', '32k']
},
{
key: 'type',
values: ['input', 'output']
}
]
})
```
```js Javascript highlight={3,5-7,8-17,20} theme={"dark"}
const billableMetric = {
name: "Tokens",
code: "__BILLABLE_METRIC_CODE__",
description: "Token usage across OpenAI models",
aggregation_type: "sum_agg",
field_name: "tokens",
recurring: false,
filters: [
{
key: "model",
values: ["8k", "32k"]
},
{
key: "type",
values: ["input", "output"]
}
]
};
await client.billableMetrics.createBillableMetric(billableMetric);
```
```go Go highlight={3,5-17,20} theme={"dark"}
bmInput := &lago.BillableMetricInput{
Name: "Tokens",
Code: "__BILLABLE_METRIC_CODE__",
Description: "Token usage across OpenAI models",
AggregationType: lago.SumAggregation,
FieldName: "tokens",
Recurring: false,
Filters: []lago.BillableMetricFilter{
{
Key: "type",
Values: []string{"input", "output"},
},
{
Key: "model",
Values: []string{"8k", "32k"},
},
},
}
billableMetric, err := lagoClient.BillableMetric().Create(bmInput)
```
Refer to the [API reference](/api-reference/billable-metrics/create) and [guide on filters](/guide/billable-metrics/filters) to learn more.
Create a plan to price packages of tokens used with OpenAI's specific pricing tiers.
1. Add a unique `code` for your plan
2. Under `charges`, configure pricing tiers for different models and token types
```bash cURL expandable highlight={7,12-67} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "OpenAI Pricing",
"code": "__PLAN_CODE__",
"amount_cents": 0,
"amount_currency": "USD",
"interval": "monthly",
"pay_in_advance": false,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"charge_model": "package",
"filters": [
{
"invoice_display_name": "8k-input",
"properties": {
"amount": "0.03",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["8k"],
"type": ["input"]
}
},
{
"invoice_display_name": "8k-output",
"properties": {
"amount": "0.06",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["8k"],
"type": ["output"]
}
},
{
"invoice_display_name": "32k-input",
"properties": {
"amount": "0.06",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["32k"],
"type": ["input"]
}
},
{
"invoice_display_name": "32k-output",
"properties": {
"amount": "0.12",
"free_units": 0,
"package_size": 1000000
},
"values": {
"model": ["32k"],
"type": ["output"]
}
}
]
}
]
}
}'
```
```python Python expandable highlight={4-8,10-14,16-20,22-26,29-33,37,42,45} theme={"dark"}
from lago_python_client.models import Plan, Charge, ChargeFilter
# Filters for different models and token types
small_input_filter = ChargeFilter(
invoice_display_name="8k-input",
properties={"amount": "0.03", "free_units": 0, "package_size": 1000000},
values={"model": ["8k"], "type": ["input"]}
)
small_output_filter = ChargeFilter(
invoice_display_name="8k-output",
properties={"amount": "0.06", "free_units": 0, "package_size": 1000000},
values={"model": ["8k"], "type": ["output"]}
)
large_input_filter = ChargeFilter(
invoice_display_name="32k-input",
properties={"amount": "0.06", "free_units": 0, "package_size": 1000000},
values={"model": ["32k"], "type": ["input"]}
)
large_output_filter = ChargeFilter(
invoice_display_name="32k-output",
properties={"amount": "0.12", "free_units": 0, "package_size": 1000000},
values={"model": ["32k"], "type": ["output"]}
)
# Charge for all filters
charge = Charge(
billable_metric_id="__BILLABLE_METRIC_ID__",
charge_model="package",
filters=[small_input_filter, small_output_filter, large_input_filter, large_output_filter]
)
plan = Plan(
name="OpenAI Plan",
code="__PLAN_CODE__",
amount_cents=0,
amount_currency="USD",
interval="monthly",
pay_in_advance=False,
charges=[charge]
)
client.plans.create(plan)
```
```ruby Ruby expandable highlight={3,8-35} theme={"dark"}
client.plans.create({
name: "OpenAI Pricing",
code: "__PLAN_CODE__",
amount_cents: 0,
amount_currency: "USD",
interval: "monthly",
pay_in_advance: false,
charges: [
{
billable_metric_id: "__BILLABLE_METRIC_ID__",
charge_model: "package",
filters: [
{
invoice_display_name: "8k-input",
properties: { amount: "0.03", free_units: 0, package_size: 1000000 },
values: { model: ["8k"], type: ["input"] }
},
{
invoice_display_name: "8k-output",
properties: { amount: "0.06", free_units: 0, package_size: 1000000 },
values: { model: ["8k"], type: ["output"] }
},
{
invoice_display_name: "32k-input",
properties: { amount: "0.06", free_units: 0, package_size: 1000000 },
values: { model: ["32k"], type: ["input"] }
},
{
invoice_display_name: "32k-output",
properties: { amount: "0.12", free_units: 0, package_size: 1000000 },
values: { model: ["32k"], type: ["output"] }
}
]
}
]
})
```
```js Javascript expandable highlight={3,8-35,38} theme={"dark"}
const plan = {
name: "OpenAI Pricing",
code: "__PLAN_CODE__",
amount_cents: 0,
amount_currency: "USD",
interval: "monthly",
pay_in_advance: false,
charges: [
{
billable_metric_id: "__BILLABLE_METRIC_ID__",
charge_model: "package",
filters: [
{
invoice_display_name: "8k-input",
properties: { amount: "0.03", free_units: 0, package_size: 1000000 },
values: { model: ["8k"], type: ["input"] }
},
{
invoice_display_name: "8k-output",
properties: { amount: "0.06", free_units: 0, package_size: 1000000 },
values: { model: ["8k"], type: ["output"] }
},
{
invoice_display_name: "32k-input",
properties: { amount: "0.06", free_units: 0, package_size: 1000000 },
values: { model: ["32k"], type: ["input"] }
},
{
invoice_display_name: "32k-output",
properties: { amount: "0.12", free_units: 0, package_size: 1000000 },
values: { model: ["32k"], type: ["output"] }
}
]
}
]
};
await client.plans.createPlan({ plan });
```
```go Go expandable highlight={3,8-51,54} theme={"dark"}
planInput := &lago.PlanInput{
Name: "OpenAI Pricing",
Code: "__PLAN_CODE__",
AmountCents: 0,
AmountCurrency: "USD",
Interval: "monthly",
PayInAdvance: false,
Charges: []lago.PlanChargeInput{
{
BillableMetricID: "__BILLABLE_METRIC_ID__",
ChargeModel: "package",
Filters: []lago.ChargeFilter{
{
InvoiceDisplayName: "8k-input",
Properties: map[string]interface{}{
"amount": "0.03", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"8k"}, "type": []string{"input"},
},
},
{
InvoiceDisplayName: "8k-output",
Properties: map[string]interface{}{
"amount": "0.06", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"8k"}, "type": []string{"output"},
},
},
{
InvoiceDisplayName: "32k-input",
Properties: map[string]interface{}{
"amount": "0.06", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"32k"}, "type": []string{"input"},
},
},
{
InvoiceDisplayName: "32k-output",
Properties: map[string]interface{}{
"amount": "0.12", "free_units": 0, "package_size": 1000000,
},
Values: map[string]string{
"model": []string{"32k"}, "type": []string{"output"},
},
},
},
},
},
}
plan, err := lagoClient.Plan().Create(planInput)
```
Refer to the [API reference](/api-reference/plans/create) and [guide on charges with filters](/guide/plans/charges/charges-with-filters) to learn more.
Create a customer with a unique `external_id`.
```bash cURL highlight={6} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "Acme Inc",
"email": "john@acme.com",
"currency": "USD",
"timezone": "America/New_York"
}
}'
```
```python Python highlight={4,11} theme={"dark"}
from lago_python_client.models import Customer
customer = Customer(
external_id="__EXTERNAL_CUSTOMER_ID__",
name="Acme Inc",
email="john@acme.com",
currency="USD",
timezone="America/New_York"
)
client.customers.create(customer)
```
```ruby Ruby highlight={2} theme={"dark"}
client.customers.create(
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
)
```
```js Javascript highlight={2,9} theme={"dark"}
const customer = {
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
};
await client.customers.createCustomer({ customer });
```
```go Go highlight={2,9} theme={"dark"}
customerInput := &lago.CustomerInput{
ExternalID: "__EXTERNAL_CUSTOMER_ID__",
Name: "Acme Inc",
Email: "john@acme.com",
Currency: "USD",
Timezone: "America/New_York",
}
customer, err := client.Customer().Create(ctx, customerInput)
```
Refer to the [API reference](/api-reference/customers/create) to create a customer.
Create a subscription for the customer with the plan's `code`.
```bash cURL highlight={6-8} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"plan_code": "__PLAN_CODE__",
"external_id": "__EXTERNAL_SUBSCRIPTION_ID__"
}
}'
```
```python Python highlight={4-6,9} theme={"dark"}
from lago_python_client.models import Subscription
subscription = Subscription(
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
plan_code="__PLAN_CODE__",
external_id="__EXTERNAL_SUBSCRIPTION_ID__"
)
client.subscriptions.create(subscription)
```
```ruby Ruby highlight={2-4} theme={"dark"}
client.subscriptions.create(
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
)
```
```js Javascript highlight={2-4,7} theme={"dark"}
const subscription = {
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
};
await client.subscriptions.createSubscription({ subscription });
```
```go Go highlight={2-4,7} theme={"dark"}
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
PlanCode: "__PLAN_CODE__",
ExternalID: "__EXTERNAL_SUBSCRIPTION_ID__",
}
subscription, err := client.Subscription().Create(ctx, subscriptionInput)
```
Refer to the [API reference](/api-reference/subscriptions/assign-plan) to create a subscription.
Send usage events to Lago to track usage.
1. Reference your billable metric with `code`
2. Reference the customer's subscription with `external_subscription_id`
3. Include usage and filters data in `properties`
```bash cURL highlight={10,11,12-16} theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__TRANSACTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"properties": {
"total": 5000,
"model": "8k",
"type": "input"
}
}
}'
```
```python Python highlight={9,10-15} theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import Event
client = Client(api_key='__API_KEY__')
event = Event(
transaction_id="__TRANSACTION_ID__",
code="__BILLABLE_METRIC_CODE__",
external_subscription_id="__EXTERNAL_SUBSCRIPTION_ID__",
properties={
"total": 5000,
"model": "8k",
"type": "input"
}
)
try:
client.events.create(event)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
```
```ruby Ruby highlight={7,8-13} theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
client.events.create(
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
total: 5000,
model: "8k",
type: "input"
}
)
```
```js Javascript highlight={4,5-10} theme={"dark"}
await client.events.createEvent({
event: {
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
total: 5000,
model: "8k",
type: "input"
}
}
});
```
```go Go highlight={10-16} theme={"dark"}
eventInput := &lago.EventInput{
TransactionID: "__TRANSACTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Properties: map[string]interface{}{
"total": 5000,
"model": "8k",
"type": "input",
},
}
event, err := client.Event().Create(ctx, eventInput)
```
Refer to the [API reference](/api-reference/events/usage) to create an event.
Track real-time customer usage for the current billing period.
```bash cURL highlight={1} theme={"dark"}
curl --location --request GET "$LAGO_URL/api/v1/customers/__EXTERNAL_CUSTOMER_ID__/current_usage?external_subscription_id=__EXTERNAL_SUBSCRIPTION_ID__" \
--header 'Authorization: Bearer __API_KEY__' \
--header 'Content-Type: application/json'
```
```python Python highlight={1} theme={"dark"}
customer_usage = client.customers.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```ruby Ruby highlight={1} theme={"dark"}
customer_usage = client.customer.current_usage('__EXTERNAL_CUSTOMER_ID__', '__EXTERNAL_SUBSCRIPTION_ID__')
```
```js Javascript highlight={1-4} theme={"dark"}
const customerUsage = await client.customers.findCustomerCurrentUsage(
'__EXTERNAL_CUSTOMER_ID__',
{ external_subscription_id: '__EXTERNAL_SUBSCRIPTION_ID__' }
)
```
```go Go highlight={1} theme={"dark"}
customerUsage, err := client.Customer().CurrentUsage(ctx, "__EXTERNAL_CUSTOMER_ID__")
```
Refer to the [API reference](/api-reference/customer-usage/get-current) to get the current usage.
## Wrap-up
Per-token pricing offers flexibility and visibility, and allows LLM and Generative AI companies like OpenAI to attract more customers.
With Lago, you can create your own metric dimensions to adapt this template to your products and services.
Give it a try, click [here](https://www.getlago.com/get-started) to get started!
# Clone Stripe pricing
Source: https://getlago.com/docs/templates/per-transaction/stripe
Replicate Stripe's per-transaction pricing model with Lago.
Implement a per-transaction pricing model like Stripe, the leading payments infrastructure company, including fees based on the total amount and number of transactions.
In this article, you will learn how to build a per-transaction billing system with Lago, where a single event can trigger instant charges.
This template is suitable for companies whose pricing depends on transactions, such as fintechs and marketplaces that deduct their fees from their customers' revenue.
## Pricing structure
Stripe offers "pay-as-you-go" pricing based on successful card charges processed via its platform.
Stripe's API includes many payment options. Rates and fixed fees per transaction vary depending on the payment method.
| Payment Method | Percentage Charge (based on transaction amount) | Fixed Fee (per transaction) |
| ------------------------- | ----------------------------------------------- | --------------------------- |
| Card payments (online) | 2.9% | \$0.30 |
| Card payments (in-person) | 2.7% | \$0.05 |
As Stripe supports more 20 payment methods in the US and most of them share the same charge model, we will focus on card payments.
## Get started
```bash cURL theme={"dark"}
LAGO_URL="https://api.getlago.com"
API_KEY="__API_KEY__"
```
```python Python theme={"dark"}
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
client = Client(api_key='__API_KEY__')
```
```ruby Ruby theme={"dark"}
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__API_KEY__')
```
```javascript Javascript theme={"dark"}
import { Client } from 'lago-javascript-client';
const client = Client('__API_KEY__');
```
```go Go theme={"dark"}
package main
import (
"context"
lago "github.com/getlago/lago-go-client"
)
client := lago.New().SetApiKey("__API_KEY__")
ctx := context.TODO()
```
Create a billable metric to track transaction usage for each payment method.
1. Set the `aggregation_type` to `sum_agg` to sum transaction amounts
2. Set the `field_name` to `amount` to track transaction values
3. Add a unique `code` for your billable metric
4. Configure `filters` to distinguish between payment types
```bash cURL highlight={7,9-16} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/billable_metrics" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"billable_metric": {
"name": "Transaction Amount",
"code": "__BILLABLE_METRIC_CODE__",
"description": "Total amount of transactions processed",
"aggregation_type": "sum_agg",
"field_name": "amount",
"filters": [
{
"key": "type",
"values": ["online", "in-person"]
}
]
}
}'
```
```python Python highlight={3-6,10,12-14,17} theme={"dark"}
from lago_python_client.models import BillableMetric, BillableMetricFilter
billable_metric_filter = BillableMetricFilter(
key='type',
values=['online', 'in-person']
)
billable_metric = BillableMetric(
name='Transaction Amount',
code='__BILLABLE_METRIC_CODE__',
description='Total amount of transactions processed',
aggregation_type='sum_agg',
field_name='amount',
filters=[billable_metric_filter]
)
client.billable_metrics.create(billable_metric)
```
```ruby Ruby highlight={3,5-12} theme={"dark"}
client.billable_metrics.create({
name: 'Transaction Amount',
code: '__BILLABLE_METRIC_CODE__',
description: 'Total amount of transactions processed',
aggregation_type: 'sum_agg',
field_name: 'amount',
filters: [
{
key: 'type',
values: ['online', 'in-person']
}
]
})
```
```javascript Javascript highlight={3,5-12,15} theme={"dark"}
const billableMetric = {
name: 'Transaction Amount',
code: '__BILLABLE_METRIC_CODE__',
description: 'Total amount of transactions processed',
aggregation_type: 'sum_agg',
field_name: 'amount',
filters: [
{
key: 'type',
values: ['online', 'in-person']
}
]
};
await client.billableMetrics.createBillableMetric({ billableMetric })
```
```go Go highlight={3,5-12,15} theme={"dark"}
billableMetricInput := &lago.BillableMetricInput{
Name: "Transaction Amount",
Code: "__BILLABLE_METRIC_CODE__",
Description: "Total amount of transactions processed",
AggregationType: "sum_agg",
FieldName: "amount",
Filters: []lago.BillableMetricFilter{
{
Key: "type",
Values: []string{"online", "in-person"},
},
},
}
billableMetric, err := client.BillableMetric().Create(ctx, billableMetricInput)
```
Refer to the [API reference](/api-reference/billable-metrics/create) and [guide on filters](/guide/billable-metrics/filters) to learn more.
Create a plan with percentage-based charges that are paid in advance.
1. Set the `amount_cents` to `0` since there is no subscription fee
2. Configure `charge_model` to `percentage` for percentage-based pricing
3. Enable `pay_in_advance` for instant charging
4. Set `invoiceable` to `false` to avoid creating invoices for the charges
5. Set `charges` with different rates for online vs in-person payments
```bash cURL expandable highlight={7,9,11-37} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/plans" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"plan": {
"name": "Payment Processing Plan",
"code": "__PLAN_CODE__",
"description": "Per-transaction pricing for payment processing",
"amount_cents": 0,
"amount_currency": "USD",
"pay_in_advance": true,
"charges": [
{
"billable_metric_id": "__BILLABLE_METRIC_ID__",
"invoice_display_name": "Online Card Payment",
"charge_model": "percentage",
"invoiceable": false,
"filters": [
{
"invoice_display_name": "Online Card Payment",
"values": { "type": ["online"] },
"properties": {
"rate": "2.9",
"fixed_amount": "0.30"
}
},
{
"invoice_display_name": "In-person Card Payment",
"values": { "type": ["in-person"] },
"properties": {
"rate": "2.7",
"fixed_amount": "0.05"
}
}
]
}
]
}
}'
```
```python Python expandable highlight={3-27,32,34-35,38} theme={"dark"}
from lago_python_client.models import Plan, Charge
online_charge_filter = ChargeFilter(
invoice_display_name="Online Card Payment",
values={"type": ["online"]},
properties={
'rate': '2.9',
'fixed_amount': '0.30'
}
)
in_person_charge_filter = ChargeFilter(
invoice_display_name="In-person Card Payment",
values={"type": ["in-person"]},
properties={
'rate': '2.7',
'fixed_amount': '0.05'
}
)
charge = Charge(
billable_metric_code='__BILLABLE_METRIC_CODE__',
charge_model='percentage',
invoiceable=False,
filters=[online_charge_filter, in_person_charge_filter]
)
plan = Plan(
name='Payment Processing',
code='__PLAN_CODE__',
description='Per-transaction pricing for payment processing',
amount_cents=0,
amount_currency='USD',
pay_in_advance=True,
charges=[charge]
)
client.plans.create(plan)
```
```ruby Ruby expandable highlight={3,5,8-33} theme={"dark"}
client.plans.create({
name: 'Payment Processing',
code: '__PLAN_CODE__',
description: 'Per-transaction pricing for payment processing',
amount_cents: 0,
amount_currency: 'USD',
pay_in_advance: true,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
invoice_display_name: 'Online Card Payment',
charge_model: 'percentage',
invoiceable: false,
filters: [
{
invoice_display_name: 'Online Card Payment',
values: { type: ['online'] },
properties: {
rate: '2.9',
fixed_amount: '0.30'
}
},
{
invoice_display_name: 'In-person Card Payment',
values: { type: ['in-person'] },
properties: {
rate: '2.7',
fixed_amount: '0.05'
}
}
]
}
]
})
```
```javascript Javascript expandable highlight={3,5,7,8-33,36} theme={"dark"}
const plan = {
name: 'Payment Processing Plan',
code: '__PLAN_CODE__',
description: 'Per-transaction pricing for payment processing',
amount_cents: 0,
amount_currency: 'USD',
pay_in_advance: true,
charges: [
{
billable_metric_id: '__BILLABLE_METRIC_ID__',
invoice_display_name: 'Online Card Payment',
charge_model: 'percentage',
invoiceable: false,
filters: [
{
invoice_display_name: 'Online Card Payment',
values: { type: ['online'] },
properties: {
rate: '2.9',
fixed_amount: '0.30'
}
},
{
invoice_display_name: 'In-person Card Payment',
values: { type: ['in-person'] },
properties: {
rate: '2.7',
fixed_amount: '0.05'
}
}
],
},
],
};
await client.plans.createPlan({ plan });
```
```go Go expandable highlight={3,5,7,8-37,40} theme={"dark"}
planInput := &lago.PlanInput{
Name: "Payment Processing Plan",
Code: "__PLAN_CODE__",
Description: "Per-transaction pricing for payment processing",
AmountCents: 0,
AmountCurrency: "USD",
PayInAdvance: true,
Charges: []lago.ChargeInput{
{
BillableMetricID: "__BILLABLE_METRIC_ID__",
InvoiceDisplayName: "Online Card Payment",
ChargeModel: "percentage",
Invoiceable: false,
Filters: []lago.ChargeFilter{
{
InvoiceDisplayName: "Online Card Payment",
Values: map[string]interface{}{
"type": "online",
},
Properties: map[string]interface{}{
"rate": "2.9",
"fixed_amount": "0.30",
},
},
{
InvoiceDisplayName: "In-person Card Payment",
Values: map[string]interface{}{
"type": "in-person",
},
Properties: map[string]interface{}{
"rate": "2.7",
"fixed_amount": "0.05",
},
},
},
},
},
}
plan, err := client.Plan().Create(ctx, planInput)
```
Refer to the [API reference](/api-reference/plans/create) and [guide on percentage charges](/guide/plans/charges/charge-models/percentage) to learn more.
Create a customer with a unique `external_id`.
```bash cURL highlight={6} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/customers" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"customer": {
"external_id": "__EXTERNAL_CUSTOMER_ID__",
"name": "Acme Inc",
"email": "john@acme.com",
"currency": "USD",
"timezone": "America/New_York"
}
}'
```
```python Python highlight={4,11} theme={"dark"}
from lago_python_client.models import Customer
customer = Customer(
external_id="__EXTERNAL_CUSTOMER_ID__",
name="Acme Inc",
email="john@acme.com",
currency="USD",
timezone="America/New_York"
)
client.customers.create(customer)
```
```ruby Ruby highlight={2} theme={"dark"}
client.customers.create(
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
)
```
```js Javascript highlight={2,9} theme={"dark"}
const customer = {
external_id: "__EXTERNAL_CUSTOMER_ID__",
name: "Acme Inc",
email: "john@acme.com",
currency: "USD",
timezone: "America/New_York"
};
await client.customers.createCustomer({ customer });
```
```go Go highlight={2,9} theme={"dark"}
customerInput := &lago.CustomerInput{
ExternalID: "__EXTERNAL_CUSTOMER_ID__",
Name: "Acme Inc",
Email: "john@acme.com",
Currency: "USD",
Timezone: "America/New_York",
}
customer, err := client.Customer().Create(ctx, customerInput)
```
Refer to the [API reference](/api-reference/customers/create) to create a customer.
Create a subscription for the customer with the plan's `code`.
```bash cURL highlight={6-8} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/subscriptions" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"subscription": {
"external_customer_id": "__EXTERNAL_CUSTOMER_ID__",
"plan_code": "__PLAN_CODE__",
"external_id": "__EXTERNAL_SUBSCRIPTION_ID__"
}
}'
```
```python Python highlight={4-6,9} theme={"dark"}
from lago_python_client.models import Subscription
subscription = Subscription(
external_customer_id="__EXTERNAL_CUSTOMER_ID__",
plan_code="__PLAN_CODE__",
external_id="__EXTERNAL_SUBSCRIPTION_ID__"
)
client.subscriptions.create(subscription)
```
```ruby Ruby highlight={2-4} theme={"dark"}
client.subscriptions.create(
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
)
```
```js Javascript highlight={2-4,7} theme={"dark"}
const subscription = {
external_customer_id: "__EXTERNAL_CUSTOMER_ID__",
plan_code: "__PLAN_CODE__",
external_id: "__EXTERNAL_SUBSCRIPTION_ID__"
};
await client.subscriptions.createSubscription({ subscription });
```
```go Go highlight={2-4,7} theme={"dark"}
subscriptionInput := &lago.SubscriptionInput{
ExternalCustomerID: "__EXTERNAL_CUSTOMER_ID__",
PlanCode: "__PLAN_CODE__",
ExternalID: "__EXTERNAL_SUBSCRIPTION_ID__",
}
subscription, err := client.Subscription().Create(ctx, subscriptionInput)
```
Refer to the [API reference](/api-reference/subscriptions/assign-plan) to create a subscription.
Refer to [API reference](/api-reference/subscriptions/assign-plan) and [guide on assigning plans](/guide/subscriptions/assign-plan) in the documentation.
Send transaction events to Lago for instant processing and charging.
1. Set the `code` to match your billable metric code
2. Use `external_customer_id` to identify the customer
3. Include `amount` in properties for the transaction value
4. Add `type` property to specify online or in-person payment
```bash cURL highlight={7-12} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/events" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"transaction_id": "__TRANSACTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"properties": {
"amount": 200,
"type": "online"
}
}
}'
```
```python Python highlight={5-10,13} theme={"dark"}
from lago_python_client.models import Event
event = Event(
transaction_id="__TRANSACTION_ID__",
code="__BILLABLE_METRIC_CODE__",
external_subscription_id="__EXTERNAL_SUBSCRIPTION_ID__",
properties={
"amount": 200,
"type": "online"
}
)
client.events.create(event)
```
```ruby Ruby highlight={3-8} theme={"dark"}
client.events.create(
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
"amount": 200,
"type": "online"
}
)
```
```js Javascript highlight={3-8,11} theme={"dark"}
const event = {
transaction_id: "__TRANSACTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
properties: {
"amount": 200,
"type": "online"
}
};
await client.events.createEvent({ event });
```
```go Go highlight={3-8,11} theme={"dark"}
eventInput := &lago.EventInput{
TransactionID: "__TRANSACTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Properties: map[string]interface{}{
"amount": 200,
"type": "online",
},
}
event, err := client.Event().Create(ctx, eventInput)
```
Refer to the [API reference](/api-reference/events/usage) to create an event.
Calculate transaction fees before processing to show users expected costs.
1. Use `external_subscription_id` to identify the subscription
2. Set the `code` to match your billable metric code
3. Include `amount` for the transaction value to estimate
4. Add `type` to get accurate rates for payment method
```bash cURL highlight={6-11} theme={"dark"}
curl --location --request POST "$LAGO_URL/api/v1/events/estimate_fees" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"event": {
"external_subscription_id": "__EXTERNAL_SUBSCRIPTION_ID__",
"code": "__BILLABLE_METRIC_CODE__",
"properties": {
"amount": 1200,
"type": "online"
}
}
}'
```
```python Python highlight={4-9,12} theme={"dark"}
from lago_python_client.models import Event
event = Event(
external_subscription_id="__EXTERNAL_SUBSCRIPTION_ID__",
code="__BILLABLE_METRIC_CODE__",
properties={
"amount": 1200,
"type": "online"
}
)
client.events.estimate_fees(event)
```
```ruby Ruby highlight={2-7} theme={"dark"}
client.events.estimate_fees(
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
properties: {
"amount": 1200,
"type": "online"
}
)
```
```javascript Javascript highlight={2-7,10} theme={"dark"}
const event = {
external_subscription_id: "__EXTERNAL_SUBSCRIPTION_ID__",
code: "__BILLABLE_METRIC_CODE__",
properties: {
"amount": 1200,
"type": "online"
}
};
await client.events.eventEstimateFees({ event });
```
```go Go highlight={2-7,10} theme={"dark"}
eventEstimateInput := &lago.EventEstimateFeesInput{
ExternalSubscriptionID: "__EXTERNAL_SUBSCRIPTION_ID__",
Code: "__BILLABLE_METRIC_CODE__",
Properties: map[string]string{
"amount": 1200,
"type": "online",
},
}
estimateFees, err := client.Event().EstimateFees(ctx, eventEstimateInput)
```
Refer to the [API reference](/api-reference/events/estimated-fee) to estimate fees.
## Wrap-up
For fintech companies like Stripe, implementing a per-transaction pricing model is a good way to **increase revenue as customers grow and capture value everytime a transaction is processed**.
With Lago, you can create your own billable metrics and use the percentage charge model paid instantly to adapt this template to your products and services.
Give it a try, click [here](https://www.getlago.com/get-started) to get started!
# null
Source: https://getlago.com/docs/welcome