LAGO_URL="https://api.getlago.com"
QUOTE_VERSION_ID="__QUOTE_VERSION_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/quote_versions/$QUOTE_VERSION_ID/approve" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"expires_at": "2026-06-30T23:59:59Z"
}'
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import QuoteVersionApprove
client = Client(api_key='__YOUR_API_KEY__')
try:
client.quote_versions.approve(
'__QUOTE_VERSION_ID__',
QuoteVersionApprove(expires_at='2026-06-30T23:59:59Z'),
)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.quote_versions.approve('__QUOTE_VERSION_ID__', expires_at: '2026-06-30T23:59:59Z')
await client.quoteVersions.approveQuoteVersion("__QUOTE_VERSION_ID__", {
expires_at: "2026-06-30T23:59:59Z",
});
import (
"context"
"fmt"
"time"
lago "github.com/getlago/lago-go-client"
)
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
ctx := context.Background()
expiresAt := time.Date(2026, time.June, 30, 23, 59, 59, 0, time.UTC)
quoteVersion, err := lagoClient.QuoteVersion().Approve(ctx, "__QUOTE_VERSION_ID__", &lago.QuoteVersionApproveInput{
ExpiresAt: &expiresAt,
})
if err != nil {
// Error is *lago.Error
panic(err)
}
// quoteVersion is *lago.QuoteVersion
fmt.Println(quoteVersion)
}
{
"quote_version": {
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"lago_quote_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"lago_organization_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"version": 1,
"status": "draft",
"currency": "USD",
"billing_entity_code": "acme_corp",
"void_reason": "manual",
"approved_at": "2026-04-29T08:59:51Z",
"voided_at": "2026-04-29T08:59:51Z",
"created_at": "2026-04-29T08:59:51Z",
"updated_at": "2026-04-29T08:59:51Z",
"content": "<h1>Quote QT-2026-0001</h1><p>Prepared for Acme Corp.</p>",
"billing_items": {
"addOns": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"type": "add_on",
"payload": {
"code": "setup_fee",
"units": 1,
"unitAmountCents": 10000,
"totalAmountCents": 10000,
"fromDatetime": "2026-01-01T00:00:00Z",
"toDatetime": "2026-12-31T23:59:59Z"
},
"overrides": {
"description": "Onboarding package, discounted for the first year",
"units": 2,
"unitAmountCents": 8000,
"totalAmountCents": 16000,
"invoiceDisplayName": "Onboarding",
"fromDatetime": "2026-01-01T00:00:00Z",
"toDatetime": "2026-12-31T23:59:59Z"
}
}
],
"plans": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"type": "plan",
"payload": {
"code": "premium_plan",
"subscriptionExternalId": "sub_1234567890",
"subscriptionName": "Premium plan - Acme Corp",
"billingTime": "calendar",
"startDate": "2026-01-01T00:00:00Z",
"endDate": "2027-01-01T00:00:00Z",
"paymentMethodId": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"charges": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"billableMetric": {
"code": "api_calls"
},
"chargeModel": "standard"
}
],
"fixedCharges": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"addOn": {
"code": "seats"
},
"chargeModel": "standard"
}
]
},
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"overrides": {
"amountCents": 50000,
"amountCurrency": "USD",
"invoiceDisplayName": "Premium",
"name": "Premium plan - Acme Corp",
"description": "Negotiated premium plan",
"trialPeriod": 30,
"minimumCommitment": {
"amountCents": 100000,
"invoiceDisplayName": "Annual commitment"
},
"usageThresholds": [
{
"amountCents": 100000,
"recurring": false,
"thresholdDisplayName": "First 1,000 EUR of usage"
}
],
"charges": [
{
"billableMetricCode": "api_calls",
"chargeModel": "standard",
"properties": {
"amount": "0.02"
},
"minAmountCents": 10000,
"invoiceDisplayName": "API calls"
}
],
"fixedCharges": [
{
"addOnCode": "seats",
"units": "10",
"properties": {
"amount": "5"
},
"invoiceDisplayName": "Seats"
}
]
}
}
],
"coupons": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"type": "coupon",
"payload": {
"code": "welcome_offer",
"type": "fixed_amount",
"amountCents": 10000,
"currency": "USD",
"percentageRate": 10.5,
"frequency": "once",
"frequencyDuration": 3
},
"overrides": {
"amountCents": 15000,
"amountCurrency": "USD",
"percentageRate": 15,
"frequency": "recurring",
"frequencyDuration": 6
}
}
],
"walletCredits": [
{
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"type": "wallet_credit",
"payload": {
"paidCredits": "100.0",
"grantedCredits": "20.0",
"rateAmount": "1.0",
"currency": "USD",
"expirationAt": "2027-01-01T00:00:00Z",
"appliesTo": {
"feeTypes": [
"charge"
],
"billableMetricCodes": [
"api_calls"
]
},
"recurringTransactionRules": [
{
"trigger": "interval",
"interval": "monthly",
"thresholdCredits": "10.0",
"method": "fixed",
"targetOngoingBalance": "100.0",
"grantsTargetTopUp": false,
"paidCredits": "100.0",
"grantedCredits": "20.0",
"startedAt": "2026-01-01T00:00:00Z",
"expirationAt": "2027-01-01T00:00:00Z",
"transactionName": "Monthly top-up",
"invoiceRequiresSuccessfulPayment": false
}
]
}
}
]
}
}
}{
"status": 401,
"error": "Unauthorized"
}{
"status": 403,
"error": "Forbidden",
"code": "feature_unavailable"
}{
"status": 404,
"error": "Not Found",
"code": "object_not_found"
}{
"status": 422,
"error": "Unprocessable entity",
"code": "validation_errors",
"error_details": {}
}Approve a quote version
This endpoint approves a quote version and generates the order form to send to the customer for signature.
Only a draft version can be approved, and its billing_items must be complete: approval validates them against the catalog and against the customer, and returns a 422 when the deal cannot be executed as quoted.
The expires_at of the generated order form is bounded by the deal’s own term, so a signing window reaching beyond the day the deal stops being executable is rejected.
A concurrent write on the same quote is reported as a 422 rather than retried, so a duplicated call can fail while the first one is still in flight.
This is a premium feature.
LAGO_URL="https://api.getlago.com"
QUOTE_VERSION_ID="__QUOTE_VERSION_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/quote_versions/$QUOTE_VERSION_ID/approve" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"expires_at": "2026-06-30T23:59:59Z"
}'
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import QuoteVersionApprove
client = Client(api_key='__YOUR_API_KEY__')
try:
client.quote_versions.approve(
'__QUOTE_VERSION_ID__',
QuoteVersionApprove(expires_at='2026-06-30T23:59:59Z'),
)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.quote_versions.approve('__QUOTE_VERSION_ID__', expires_at: '2026-06-30T23:59:59Z')
await client.quoteVersions.approveQuoteVersion("__QUOTE_VERSION_ID__", {
expires_at: "2026-06-30T23:59:59Z",
});
import (
"context"
"fmt"
"time"
lago "github.com/getlago/lago-go-client"
)
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
ctx := context.Background()
expiresAt := time.Date(2026, time.June, 30, 23, 59, 59, 0, time.UTC)
quoteVersion, err := lagoClient.QuoteVersion().Approve(ctx, "__QUOTE_VERSION_ID__", &lago.QuoteVersionApproveInput{
ExpiresAt: &expiresAt,
})
if err != nil {
// Error is *lago.Error
panic(err)
}
// quoteVersion is *lago.QuoteVersion
fmt.Println(quoteVersion)
}
{
"quote_version": {
"lago_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"lago_quote_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"lago_organization_id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"version": 1,
"status": "draft",
"currency": "USD",
"billing_entity_code": "acme_corp",
"void_reason": "manual",
"approved_at": "2026-04-29T08:59:51Z",
"voided_at": "2026-04-29T08:59:51Z",
"created_at": "2026-04-29T08:59:51Z",
"updated_at": "2026-04-29T08:59:51Z",
"content": "<h1>Quote QT-2026-0001</h1><p>Prepared for Acme Corp.</p>",
"billing_items": {
"addOns": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"type": "add_on",
"payload": {
"code": "setup_fee",
"units": 1,
"unitAmountCents": 10000,
"totalAmountCents": 10000,
"fromDatetime": "2026-01-01T00:00:00Z",
"toDatetime": "2026-12-31T23:59:59Z"
},
"overrides": {
"description": "Onboarding package, discounted for the first year",
"units": 2,
"unitAmountCents": 8000,
"totalAmountCents": 16000,
"invoiceDisplayName": "Onboarding",
"fromDatetime": "2026-01-01T00:00:00Z",
"toDatetime": "2026-12-31T23:59:59Z"
}
}
],
"plans": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"type": "plan",
"payload": {
"code": "premium_plan",
"subscriptionExternalId": "sub_1234567890",
"subscriptionName": "Premium plan - Acme Corp",
"billingTime": "calendar",
"startDate": "2026-01-01T00:00:00Z",
"endDate": "2027-01-01T00:00:00Z",
"paymentMethodId": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"charges": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"billableMetric": {
"code": "api_calls"
},
"chargeModel": "standard"
}
],
"fixedCharges": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"addOn": {
"code": "seats"
},
"chargeModel": "standard"
}
]
},
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"overrides": {
"amountCents": 50000,
"amountCurrency": "USD",
"invoiceDisplayName": "Premium",
"name": "Premium plan - Acme Corp",
"description": "Negotiated premium plan",
"trialPeriod": 30,
"minimumCommitment": {
"amountCents": 100000,
"invoiceDisplayName": "Annual commitment"
},
"usageThresholds": [
{
"amountCents": 100000,
"recurring": false,
"thresholdDisplayName": "First 1,000 EUR of usage"
}
],
"charges": [
{
"billableMetricCode": "api_calls",
"chargeModel": "standard",
"properties": {
"amount": "0.02"
},
"minAmountCents": 10000,
"invoiceDisplayName": "API calls"
}
],
"fixedCharges": [
{
"addOnCode": "seats",
"units": "10",
"properties": {
"amount": "5"
},
"invoiceDisplayName": "Seats"
}
]
}
}
],
"coupons": [
{
"id": "1a901a90-1a90-1a90-1a90-1a901a901a90",
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"type": "coupon",
"payload": {
"code": "welcome_offer",
"type": "fixed_amount",
"amountCents": 10000,
"currency": "USD",
"percentageRate": 10.5,
"frequency": "once",
"frequencyDuration": 3
},
"overrides": {
"amountCents": 15000,
"amountCurrency": "USD",
"percentageRate": 15,
"frequency": "recurring",
"frequencyDuration": 6
}
}
],
"walletCredits": [
{
"localId": "b5c1e2a4-4e1e-4a7f-9f0e-9c1a0c7e1f2b",
"type": "wallet_credit",
"payload": {
"paidCredits": "100.0",
"grantedCredits": "20.0",
"rateAmount": "1.0",
"currency": "USD",
"expirationAt": "2027-01-01T00:00:00Z",
"appliesTo": {
"feeTypes": [
"charge"
],
"billableMetricCodes": [
"api_calls"
]
},
"recurringTransactionRules": [
{
"trigger": "interval",
"interval": "monthly",
"thresholdCredits": "10.0",
"method": "fixed",
"targetOngoingBalance": "100.0",
"grantsTargetTopUp": false,
"paidCredits": "100.0",
"grantedCredits": "20.0",
"startedAt": "2026-01-01T00:00:00Z",
"expirationAt": "2027-01-01T00:00:00Z",
"transactionName": "Monthly top-up",
"invoiceRequiresSuccessfulPayment": false
}
]
}
}
]
}
}
}{
"status": 401,
"error": "Unauthorized"
}{
"status": 403,
"error": "Forbidden",
"code": "feature_unavailable"
}{
"status": 404,
"error": "Not Found",
"code": "object_not_found"
}{
"status": 422,
"error": "Unprocessable entity",
"code": "validation_errors",
"error_details": {}
}LAGO_URL="https://api.getlago.com"
QUOTE_VERSION_ID="__QUOTE_VERSION_ID__"
API_KEY="__YOUR_API_KEY__"
curl --location --request POST "$LAGO_URL/api/v1/quote_versions/$QUOTE_VERSION_ID/approve" \
--header "Authorization: Bearer $API_KEY" \
--header 'Content-Type: application/json' \
--data-raw '{
"expires_at": "2026-06-30T23:59:59Z"
}'
from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models import QuoteVersionApprove
client = Client(api_key='__YOUR_API_KEY__')
try:
client.quote_versions.approve(
'__QUOTE_VERSION_ID__',
QuoteVersionApprove(expires_at='2026-06-30T23:59:59Z'),
)
except LagoApiError as e:
repair_broken_state(e) # do something on error or raise your own exception
require 'lago-ruby-client'
client = Lago::Api::Client.new(api_key: '__YOUR_API_KEY__')
client.quote_versions.approve('__QUOTE_VERSION_ID__', expires_at: '2026-06-30T23:59:59Z')
await client.quoteVersions.approveQuoteVersion("__QUOTE_VERSION_ID__", {
expires_at: "2026-06-30T23:59:59Z",
});
import (
"context"
"fmt"
"time"
lago "github.com/getlago/lago-go-client"
)
func main() {
lagoClient := lago.New().SetApiKey("__YOUR_API_KEY__")
ctx := context.Background()
expiresAt := time.Date(2026, time.June, 30, 23, 59, 59, 0, time.UTC)
quoteVersion, err := lagoClient.QuoteVersion().Approve(ctx, "__QUOTE_VERSION_ID__", &lago.QuoteVersionApproveInput{
ExpiresAt: &expiresAt,
})
if err != nil {
// Error is *lago.Error
panic(err)
}
// quoteVersion is *lago.QuoteVersion
fmt.Println(quoteVersion)
}
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Path Parameters
Unique identifier assigned to the quote version within the Lago application. This ID is exclusively created by Lago and serves as a unique identifier for the quote version's record within the Lago system.
"1a901a90-1a90-1a90-1a90-1a901a901a90"
Body
Approve quote version payload
Parameters available when approving a quote version.
The date and time in UTC (ISO 8601) when the order form generated by the approval expires. It must be in the future, and must fall strictly before the day the quoted deal stops being executable, otherwise the approval is rejected with a 422. That boundary is the earliest of the endDate of any quoted plan and the expirationAt of any quoted wallet credit or recurring top-up rule. A one_off quote carries none of them, so its signing window is never bounded. When expires_at is omitted, the order form never expires.
"2026-06-30T23:59:59Z"
Response
Quote version approved
Show child attributes
Show child attributes
Was this page helpful?