# Faturamento Automático — Documentação > Documentação completa: assinaturas, faturas, pagamentos, NF-e, gateways, dunning e portal do cliente. ## en Welcome to the Automatic Billing documentation, the B2B2C platform for billing, subscriptions, and recurring payments for the Brazilian market. - [Automatic Billing — Documentation](https://docs.billing.kobana.com.br/en/index.md): Welcome to the Automatic Billing documentation, the B2B2C platform for billing, subscriptions, and recurring payments for the Brazilian market. ### search - [Search the documentation](https://docs.billing.kobana.com.br/en/search.md) ### api - [API reference](https://docs.billing.kobana.com.br/en/api.md) #### overview - [Authentication](https://docs.billing.kobana.com.br/en/api/overview/authentication.md): The Automatic Billing API uses a Kobana Account access token to authenticate every request. - [Data Retention](https://docs.billing.kobana.com.br/en/api/overview/data-retention.md): This page describes how long each type of data is kept in Automatic Billing. - [Endpoints](https://docs.billing.kobana.com.br/en/api/overview/endpoints.md): Platform (web access) - [Idempotency](https://docs.billing.kobana.com.br/en/api/overview/idempotency.md): The API supports idempotency so requests can be safely retried without executing the same operation twice. Useful when a call is interrupted in transit and you don't get a response — for example, a request to create a subscription that drops on a network error can be retried with the same key, guaranteeing that only one subscription is created. - [Introduction](https://docs.billing.kobana.com.br/en/api/overview/introduction.md): If you are a dev, have fun! ✨ - [OpenAPI](https://docs.billing.kobana.com.br/en/api/overview/openapi.md): We publicly maintain the Automatic Billing API specification files in an open format so you can download them and use them in the tool of your choice. - [Listing and Pagination](https://docs.billing.kobana.com.br/en/api/overview/pagination.md): All GET endpoints that return collections (/v1/customers, /v1/subscriptions, /v1/invoices, etc.) use page-number pagination. - [Postman](https://docs.billing.kobana.com.br/en/api/overview/postman.md): If you prefer testing the API through Postman, download the collection in your preferred language and import it — or open the online version straight from Kobana's public workspace. - [Rate Limit](https://docs.billing.kobana.com.br/en/api/overview/rate-limit.md): When a client exceeds the limit associated with it, subsequent requests are blocked. - [User-Agent](https://docs.billing.kobana.com.br/en/api/overview/user-agent.md): You can include the User-Agent header with your application's name and a valid email address, so that we can contact you in case: - [Webhooks](https://docs.billing.kobana.com.br/en/api/overview/webhooks.md): Webhooks are HTTP notifications sent by the Automatic Billing API whenever a relevant event occurs in your Organization — subscription created, invoice paid, NF-e issued, etc. - [billing_account.suspended](https://docs.billing.kobana.com.br/en/api/overview/webhooks/billing-account-suspended.md): Fired when a BillingAccount is suspended for delinquency or by a manual operator action. - [company.db.updated](https://docs.billing.kobana.com.br/en/api/overview/webhooks/company-updated.md): Fired on every update to any field of a company (Company). - [coupon.redeemed](https://docs.billing.kobana.com.br/en/api/overview/webhooks/coupon-redeemed.md): Fired when a coupon is redeemed on a subscription or invoice. - [credit.applied](https://docs.billing.kobana.com.br/en/api/overview/webhooks/credit-applied.md): Fired when an existing credit is applied to an invoice, reducing the amount due. - [customer.db.created](https://docs.billing.kobana.com.br/en/api/overview/webhooks/customer-created.md): Fired when a new customer (individual or legal entity) is registered in the Organization. - [invoice.paid](https://docs.billing.kobana.com.br/en/api/overview/webhooks/invoice-paid.md): Fired when an invoice has its payment confirmed and its status changes to paid. - [nfe.issued](https://docs.billing.kobana.com.br/en/api/overview/webhooks/nfe-issued.md): Fired when the NF-e (Brazilian electronic invoice) is successfully issued by the integrated tax provider. - [payment_method.expired](https://docs.billing.kobana.com.br/en/api/overview/webhooks/payment-method-expired.md): Fired when a payment method expires (expired card, canceled mandate, etc.). - [payment.succeeded](https://docs.billing.kobana.com.br/en/api/overview/webhooks/payment-succeeded.md): Fired when a payment is confirmed by the gateway with status succeeded. - [plan.db.updated](https://docs.billing.kobana.com.br/en/api/overview/webhooks/plan-updated.md): Fired on every update to any field of a Plan. - [product.archived](https://docs.billing.kobana.com.br/en/api/overview/webhooks/product-archived.md): Fired when a product is archived and removed from the active catalog. - [proposal.accepted](https://docs.billing.kobana.com.br/en/api/overview/webhooks/proposal-accepted.md): Fired when the customer accepts a commercial proposal that was sent. - [service_item.db.updated](https://docs.billing.kobana.com.br/en/api/overview/webhooks/service-item-updated.md): Fired on every update to service items (CNAE codes, ISS, tax description). - [subscription.status_changed](https://docs.billing.kobana.com.br/en/api/overview/webhooks/subscription-status-changed.md): Fired whenever a subscription's status changes (active, trialing, past_due, paused, canceled). ### assinaturas - [Subscriptions](https://docs.billing.kobana.com.br/en/assinaturas.md) #### ciclo-de-vida States - [Subscription Lifecycle](https://docs.billing.kobana.com.br/en/assinaturas/ciclo-de-vida.md): States #### mudanca-de-plano The system allows customers to change their subscription plan with automatic proration calculation. - [Plan Change (Upgrade/Downgrade)](https://docs.billing.kobana.com.br/en/assinaturas/mudanca-de-plano.md): The system allows customers to change their subscription plan with automatic proration calculation. #### mudancas-de-itens Besides plan changes (upgrade/downgrade), Automatic Billing supports changes to the individual items of a subscription — changing quantities, adding add-ons, swapping a one-off product or a metered item without having to change the main plan. The /dashboard/subscription-changes screen groups the history of these changes and the default proration settings. - [Subscription Item Changes](https://docs.billing.kobana.com.br/en/assinaturas/mudancas-de-itens.md): Besides plan changes (upgrade/downgrade), Automatic Billing supports changes to the individual items of a subscription — changing quantities, adding add-ons, swapping a one-off product or a metered item without having to change the main plan. The /dashboard/subscription-changes screen groups the history of these changes and the default proration settings. #### pausar-assinatura The pause subscription feature allows you to temporarily suspend billing for a customer without canceling the subscription. It is a strategic retention tool. - [Pause Subscription](https://docs.billing.kobana.com.br/en/assinaturas/pausar-assinatura.md): The pause subscription feature allows you to temporarily suspend billing for a customer without canceling the subscription. It is a strategic retention tool. #### termos-de-cobranca Billing terms define how and when the customer is charged for the subscription. - [Billing Terms](https://docs.billing.kobana.com.br/en/assinaturas/termos-de-cobranca.md): Billing terms define how and when the customer is charged for the subscription. ### cli #### overview - [Authentication](https://docs.billing.kobana.com.br/en/cli/overview/authentication.md): KOBANA_TOKEN holds one product's credential at a time. A Automatic Billing token does not authenticate against any other Kobana product, and vice versa. - [Environment variables](https://docs.billing.kobana.com.br/en/cli/overview/environment-variables.md): Every variable can also be set in a .env file (loaded via dotenvy). - [Exit codes](https://docs.billing.kobana.com.br/en/cli/overview/exit-codes.md): Every kobana invocation exits with one of these codes, so a script can branch on failure class without parsing the JSON error body. - [Installation](https://docs.billing.kobana.com.br/en/cli/overview/installation.md): Homebrew (macOS and Linux) - [Introduction](https://docs.billing.kobana.com.br/en/cli/overview/introduction.md): kobana is a single command-line tool for every Kobana product's API — Automatic Billing included. It is built and maintained in its own repository (kobana-cli), not by this product, and it does not hardcode endpoints: at startup it parses the OpenAPI 3.1 specs embedded in the binary and builds its command tree from them. Updating the API surface is a matter of refreshing the embedded spec and shipping a new build — no per-endpoint code. #### resources - [Billing accounts](https://docs.billing.kobana.com.br/en/cli/resources/billing-accounts.md): The account that accumulates a customer's subscriptions, invoices and credits. Suspending halts billing without ending the relationship; closing ends it. - [Digital certificates](https://docs.billing.kobana.com.br/en/cli/resources/certificates.md): The A1 certificates used to sign tax documents. The file is uploaded once and never comes back in a response. - [Companies](https://docs.billing.kobana.com.br/en/cli/resources/companies.md): The issuing companies — who is charging. They carry the fiscal profile used when issuing invoices, and one of them is the default. - [Coupons](https://docs.billing.kobana.com.br/en/cli/resources/coupons.md): Discounts with validity rules and usage limits. redemptions shows where each coupon was actually applied. - [Credits](https://docs.billing.kobana.com.br/en/cli/resources/credits.md): Balance in the customer's favour, applicable to future invoices. Applying and removing credits are commands on the invoice itself. - [Customers](https://docs.billing.kobana.com.br/en/cli/resources/customers.md): Who gets billed, their portal users and the consolidated statement. recalculate-mrr recomputes the customer's recurring revenue. - [Dashboard users](https://docs.billing.kobana.com.br/en/cli/resources/dashboard-users.md): Who has access to your organization's dashboard — the operators, not the customers. - [Invoices](https://docs.billing.kobana.com.br/en/cli/resources/invoices.md): The document to be charged, from draft to paid. finalize seals the draft, pay records settlement, void cancels it, and instalments live under installments. - [Invoices (NF-e)](https://docs.billing.kobana.com.br/en/cli/resources/nfes.md): The tax document behind an invoice: issue, cancel, download PDF and XML, and follow every attempt at the city hall. Barueri has commands of its own. - [Organization](https://docs.billing.kobana.com.br/en/cli/resources/organization.md): The settings at the top of the hierarchy, shared by every company in the account. - [Resources](https://docs.billing.kobana.com.br/en/cli/resources/overview.md): Every billing resource below is generated from the same OpenAPI spec documented in the API Reference — the CLI dispatches to the exact same endpoints, so filters, validation and delete behaviour are identical. Reach for schema introspection whenever a command's exact parameters aren't obvious from the examples here. - [Payment methods](https://docs.billing.kobana.com.br/en/cli/resources/payment-methods.md): A customer's saved cards and other methods, and which one is the default. - [Payments](https://docs.billing.kobana.com.br/en/cli/resources/payments.md): The settlement attempts on an invoice: retry, card swap, due-date change, refund and re-sending the billing e-mail. - [Plan changes](https://docs.billing.kobana.com.br/en/cli/resources/plan-changes.md): Upgrades and downgrades: the rules for what can become what, the proration configuration and the statistics of what actually changed. - [Plan groups](https://docs.billing.kobana.com.br/en/cli/resources/plan-groups.md): The shelf plans are displayed and ordered on. reorder changes the order; archive takes the group out of circulation without deleting it. - [Plans](https://docs.billing.kobana.com.br/en/cli/resources/plans.md): What gets subscribed to: price, billing period and the list of items the plan delivers. The bulk-* operations act on many plans at once. - [Product groups](https://docs.billing.kobana.com.br/en/cli/resources/product-groups.md): The grouping of the product catalogue, with its own ordering and archiving. - [Products](https://docs.billing.kobana.com.br/en/cli/resources/products.md): The catalogue of what you charge for, item by item, before it becomes a plan or an invoice line. Publish, archive and restore control visibility without destroying history. - [Proposal templates](https://docs.billing.kobana.com.br/en/cli/resources/proposal-templates.md): The templates proposals are born from, with one marked as the default. - [Proposals](https://docs.billing.kobana.com.br/en/cli/resources/proposals.md): The quote before the subscription: publish, send, generate a PDF and accept. Accepting is what turns the proposal into a subscription — and undo-accept reverses it. - [Service items](https://docs.billing.kobana.com.br/en/cli/resources/service-items.md): The municipal service list entries used to describe what an invoice (NFS-e) is charging for. - [Subscription changes](https://docs.billing.kobana.com.br/en/cli/resources/subscription-changes.md): The configuration for how subscription changes get applied — immediately, next cycle, with or without proration. - [Subscription item changes](https://docs.billing.kobana.com.br/en/cli/resources/subscription-item-changes.md): The history of changes to a subscription's items, and the cancellation of a change that is still scheduled. - [Subscriptions](https://docs.billing.kobana.com.br/en/cli/resources/subscriptions.md): The live contract between a customer and a plan: activate, pause, resume, change plan and cancel. create-invoice forces an invoice outside the cycle. - [Tax periods](https://docs.billing.kobana.com.br/en/cli/resources/tax-periods.md): The tax periods that group issued invoices. - [Tax rules](https://docs.billing.kobana.com.br/en/cli/resources/tax-rules.md): Which tax applies to what, and at what rate — what invoice issuing consults. - [Team roles](https://docs.billing.kobana.com.br/en/cli/resources/team-roles.md): The roles that define what each dashboard user can do. - [Usage](https://docs.billing.kobana.com.br/en/cli/resources/usage.md): The usage events that feed metered billing, with daily and monthly snapshots and a consolidated summary. - [Withholdings](https://docs.billing.kobana.com.br/en/cli/resources/withholdings.md): Amounts the customer withheld at source, which can be converted into credit. #### usage - [Global flags](https://docs.billing.kobana.com.br/en/cli/usage/global-flags.md): | Flag | Description | - [Helpers](https://docs.billing.kobana.com.br/en/cli/usage/helpers.md): Helpers are commands prefixed with + that provide multi-step workflows the dynamic commands alone cannot: simplified interfaces, batch operations, or calls composed across multiple endpoints. They do not wrap a single API call already available through the dynamic commands — every helper flag controls orchestration logic, not a reshaped version of --params/--json. - [Usage](https://docs.billing.kobana.com.br/en/cli/usage/overview.md): Syntax - [Schema introspection](https://docs.billing.kobana.com.br/en/cli/usage/schema.md): Returns parameters, required fields, types and responses — all derived from the embedded OpenAPI spec, so it is always in sync with what a command actually accepts. The path has the same shape as the command: ... ### configuracoes - [Settings](https://docs.billing.kobana.com.br/en/configuracoes.md) #### analytics The Analytics area (/dashboard/analytics) turns billing operational data into SaaS metrics for the finance and product teams: MRR, ARR, churn, LTV, ARPU, cohort retention and the billing funnel. - [Analytics](https://docs.billing.kobana.com.br/en/configuracoes/analytics.md): The Analytics area (/dashboard/analytics) turns billing operational data into SaaS metrics for the finance and product teams: MRR, ARR, churn, LTV, ARPU, cohort retention and the billing funnel. #### api-keys At /dashboard/api the organization manages its API keys. Each key - [API Keys](https://docs.billing.kobana.com.br/en/configuracoes/api-keys.md): At /dashboard/api the organization manages its API keys. Each key #### auditoria The audit trail (/dashboard/audit) records every data change made in the dashboard or via the API. Each entry captures who made it, what was changed, the values before and after, IP, User-Agent and time, forming an immutable history for compliance, debugging and incident analysis. - [Audit Log](https://docs.billing.kobana.com.br/en/configuracoes/auditoria.md): The audit trail (/dashboard/audit) records every data change made in the dashboard or via the API. Each entry captures who made it, what was changed, the values before and after, IP, User-Agent and time, forming an immutable history for compliance, debugging and incident analysis. #### configuracoes-de-cobranca Settings that affect the organization's pricing and billing behavior. - [Billing Settings](https://docs.billing.kobana.com.br/en/configuracoes/configuracoes-de-cobranca.md): Settings that affect the organization's pricing and billing behavior. #### empresa Companies represent the legal entities that issue invoices and NF-e. An organization can have multiple companies (headquarters and branches). - [Company (Fiscal Entity)](https://docs.billing.kobana.com.br/en/configuracoes/empresa.md): Companies represent the legal entities that issue invoices and NF-e. An organization can have multiple companies (headquarters and branches). #### eventos The events screen (/dashboard/events) exposes the internal stream of domain events the system generates every time a relevant state changes — invoice.created, payment.succeeded, subscription.canceled, nfe.issued and dozens of others. It is the same queue that feeds Webhooks and the customer history in the portal. - [Events](https://docs.billing.kobana.com.br/en/configuracoes/eventos.md): The events screen (/dashboard/events) exposes the internal stream of domain events the system generates every time a relevant state changes — invoice.created, payment.succeeded, subscription.canceled, nfe.issued and dozens of others. It is the same queue that feeds Webhooks and the customer history in the portal. #### feriados Holidays are the days the banks are closed. They serve two purposes: - [Holidays](https://docs.billing.kobana.com.br/en/configuracoes/feriados.md): Holidays are the days the banks are closed. They serve two purposes: #### membros The members page (/dashboard/members) lists everyone with access to the organization's dashboard. Each member has an email linked to Kobana authentication and one or more roles that define what they can see and change. - [Members and Roles](https://docs.billing.kobana.com.br/en/configuracoes/membros.md): The members page (/dashboard/members) lists everyone with access to the organization's dashboard. Each member has an email linked to Kobana authentication and one or more roles that define what they can see and change. #### notificacoes The notification system sends multichannel communications to customers about important events. - [Notifications](https://docs.billing.kobana.com.br/en/configuracoes/notificacoes.md): The notification system sends multichannel communications to customers about important events. #### perfil The /dashboard/profile page gathers the personal preferences of the signed-in operator: theme, language, time zone and notification settings. Unlike the organization's settings (which affect all members), profile preferences are per user and are stored both locally and on the server. - [User Profile](https://docs.billing.kobana.com.br/en/configuracoes/perfil.md): The /dashboard/profile page gathers the personal preferences of the signed-in operator: theme, language, time zone and notification settings. Unlike the organization's settings (which affect all members), profile preferences are per user and are stored both locally and on the server. #### rate-limiting The system implements API request limits to protect the platform and ensure fair usage. - [Rate Limiting](https://docs.billing.kobana.com.br/en/configuracoes/rate-limiting.md): The system implements API request limits to protect the platform and ensure fair usage. #### relatorios The reports center (/dashboard/reports) is where the finance, operations and support teams generate tabular extractions of the organization's data. Unlike Analytics, which aggregates metrics, reports deliver row-by-row data ready for reconciliation, auditing or building external spreadsheets. - [Reports](https://docs.billing.kobana.com.br/en/configuracoes/relatorios.md): The reports center (/dashboard/reports) is where the finance, operations and support teams generate tabular extractions of the organization's data. Unlike Analytics, which aggregates metrics, reports deliver row-by-row data ready for reconciliation, auditing or building external spreadsheets. #### templates-de-email Email templates allow you to customize transactional communications sent to customers. - [Email Templates](https://docs.billing.kobana.com.br/en/configuracoes/templates-de-email.md): Email templates allow you to customize transactional communications sent to customers. #### uso The /dashboard/usage screen consolidates the metered consumption of all the organization's customers: API events, messages sent, transactions processed, storage — any metric the catalog defines as "usage" and that is billed by consumption. - [Usage and Consumption](https://docs.billing.kobana.com.br/en/configuracoes/uso.md): The /dashboard/usage screen consolidates the metered consumption of all the organization's customers: API events, messages sent, transactions processed, storage — any metric the catalog defines as "usage" and that is billed by consumption. #### usuarios The /dashboard/users page lists the customer portal users — individuals linked to a billing account (BillingAccount) who can sign in to the portal to view invoices, pay boletos, manage cards and update their details. - [Users](https://docs.billing.kobana.com.br/en/configuracoes/usuarios.md): The /dashboard/users page lists the customer portal users — individuals linked to a billing account (BillingAccount) who can sign in to the portal to view invoices, pay boletos, manage cards and update their details. ### contas - [Accounts](https://docs.billing.kobana.com.br/en/contas.md) #### clientes Customers are represented by the Person model (Person) with different types depending on the context. - [Customers (Persons)](https://docs.billing.kobana.com.br/en/contas/clientes.md): Customers are represented by the Person model (Person) with different types depending on the context. #### contas-de-cobranca Billing accounts (BillingAccount) represent the financial relationship between an organization and its customer. Each account has subscriptions, invoices, payments, and payment methods. - [Billing Accounts](https://docs.billing.kobana.com.br/en/contas/contas-de-cobranca.md): Billing accounts (BillingAccount) represent the financial relationship between an organization and its customer. Each account has subscriptions, invoices, payments, and payment methods. #### empresas At /dashboard/companies the organization registers its issuing legal entities — the companies that sign contracts, invoices and NF-e. An organization can have several companies (headquarters, branches or different CNPJs from the same group) and set one as the default for billing. - [Companies](https://docs.billing.kobana.com.br/en/contas/empresas.md): At /dashboard/companies the organization registers its issuing legal entities — the companies that sign contracts, invoices and NF-e. An organization can have several companies (headquarters, branches or different CNPJs from the same group) and set one as the default for billing. #### organizacoes Organizations are the platform's tenants. Each organization is a business that uses Automatic Billing to charge its own customers. - [Organizations](https://docs.billing.kobana.com.br/en/contas/organizacoes.md): Organizations are the platform's tenants. Each organization is a business that uses Automatic Billing to charge its own customers. #### portal-do-cliente The customer portal allows end customers of each organization to manage their subscriptions, invoices, and payment methods autonomously. - [Customer Portal](https://docs.billing.kobana.com.br/en/contas/portal-do-cliente.md): The customer portal allows end customers of each organization to manage their subscriptions, invoices, and payment methods autonomously. ### cupons-e-descontos - [Coupons and Discounts](https://docs.billing.kobana.com.br/en/cupons-e-descontos.md) #### codigos-de-desconto Discount codes are applied directly to subscriptions at the time of creation, offering recurring or one-time discounts. - [Discount Codes](https://docs.billing.kobana.com.br/en/cupons-e-descontos/codigos-de-desconto.md): Discount codes are applied directly to subscriptions at the time of creation, offering recurring or one-time discounts. #### cupons Coupons are promotional codes that customers can redeem to get discounts on purchases and invoices. - [Coupons](https://docs.billing.kobana.com.br/en/cupons-e-descontos/cupons.md): Coupons are promotional codes that customers can redeem to get discounts on purchases and invoices. ### docs-mcp This documentation has its own MCP server. It lets an AI assistant (Claude, - [Docs MCP](https://docs.billing.kobana.com.br/en/docs-mcp.md): This documentation has its own MCP server. It lets an AI assistant (Claude, ### exportacao-e-importacao - [Export and Import](https://docs.billing.kobana.com.br/en/exportacao-e-importacao.md) #### exportacoes Export platform data in different formats for reports and integrations. - [Exports](https://docs.billing.kobana.com.br/en/exportacao-e-importacao/exportacoes.md): Export platform data in different formats for reports and integrations. #### importacoes Import data in bulk to the platform via file upload. - [Imports](https://docs.billing.kobana.com.br/en/exportacao-e-importacao/importacoes.md): Import data in bulk to the platform via file upload. ### faturas-e-pagamentos - [Invoices and Payments](https://docs.billing.kobana.com.br/en/faturas-e-pagamentos.md) #### creditos The credit system allows adding balance to a customer's account that is automatically applied to future invoices. - [Credits](https://docs.billing.kobana.com.br/en/faturas-e-pagamentos/creditos.md): The credit system allows adding balance to a customer's account that is automatically applied to future invoices. #### faturas Invoices represent charges sent to customers. Each invoice contains line items detailing the products and amounts charged. - [Invoices](https://docs.billing.kobana.com.br/en/faturas-e-pagamentos/faturas.md): Invoices represent charges sent to customers. Each invoice contains line items detailing the products and amounts charged. #### metodos-de-pagamento Each billing account can have multiple stored payment methods. One of them is marked as the default for automatic charges. - [Payment Methods](https://docs.billing.kobana.com.br/en/faturas-e-pagamentos/metodos-de-pagamento.md): Each billing account can have multiple stored payment methods. One of them is marked as the default for automatic charges. #### pagamentos Payments represent charge attempts associated with invoices. Each payment tracks the status, method, gateway used, and provider response. - [Payments](https://docs.billing.kobana.com.br/en/faturas-e-pagamentos/pagamentos.md): Payments represent charge attempts associated with invoices. Each payment tracks the status, method, gateway used, and provider response. #### parcelamento Invoices can be split into multiple installments with individual due dates. - [Installments](https://docs.billing.kobana.com.br/en/faturas-e-pagamentos/parcelamento.md): Invoices can be split into multiple installments with individual due dates. ### gateways-de-pagamento - [Payment Gateways](https://docs.billing.kobana.com.br/en/gateways-de-pagamento.md) #### callbacks Payment gateway providers send notifications to the system when payment statuses change. These notifications are processed asynchronously. - [Callbacks (Provider Webhooks)](https://docs.billing.kobana.com.br/en/gateways-de-pagamento/callbacks.md): Payment gateway providers send notifications to the system when payment statuses change. These notifications are processed asynchronously. #### configuracao Each organization can configure multiple gateways and set defaults per payment method. - [Gateway Configuration](https://docs.billing.kobana.com.br/en/gateways-de-pagamento/configuracao.md): Each organization can configure multiple gateways and set defaults per payment method. #### provedores The system supports three payment providers, each with specific capabilities. - [Gateway Providers](https://docs.billing.kobana.com.br/en/gateways-de-pagamento/provedores.md): The system supports three payment providers, each with specific capabilities. ### gestao-de-inadimplencia - [Dunning](https://docs.billing.kobana.com.br/en/gestao-de-inadimplencia.md) #### configuracao-de-dunning The dunning configuration defines how the system handles overdue payments: how many attempts, the interval between them, and the behavior after exhaustion. - [Dunning Configuration](https://docs.billing.kobana.com.br/en/gestao-de-inadimplencia/configuracao-de-dunning.md): The dunning configuration defines how the system handles overdue payments: how many attempts, the interval between them, and the behavior after exhaustion. #### juros-e-multa An overdue invoice can accrue a fine (charged once) and interest (accruing per day of delay). A late fee policy defines both, applies organization-wide, and can be overridden per customer, per subscription or per invoice. - [Late Fees](https://docs.billing.kobana.com.br/en/gestao-de-inadimplencia/juros-e-multa.md): An overdue invoice can accrue a fine (charged once) and interest (accruing per day of delay). A late fee policy defines both, applies organization-wide, and can be overridden per customer, per subscription or per invoice. #### recuperacao-de-receita The system tracks all revenue recovered via dunning for efficiency analysis. - [Revenue Recovery](https://docs.billing.kobana.com.br/en/gestao-de-inadimplencia/recuperacao-de-receita.md): The system tracks all revenue recovered via dunning for efficiency analysis. #### suspensao Delinquent accounts are automatically suspended when the grace period is exceeded. - [Account Suspension](https://docs.billing.kobana.com.br/en/gestao-de-inadimplencia/suspensao.md): Delinquent accounts are automatically suspended when the grace period is exceeded. #### tentativas-de-pagamento The retry system automatically processes charge attempts for overdue invoices. - [Payment Retries](https://docs.billing.kobana.com.br/en/gestao-de-inadimplencia/tentativas-de-pagamento.md): The retry system automatically processes charge attempts for overdue invoices. ### getting-started The Getting Started page (/dashboard/getting-started) is the starting point for new organizations. It presents a guided sequence of the tasks needed to start recurring billing: register the company, set up gateways and NF-e, create plans and products, import customers and activate the first subscription. - [Getting Started](https://docs.billing.kobana.com.br/en/getting-started.md): The Getting Started page (/dashboard/getting-started) is the starting point for new organizations. It presents a guided sequence of the tasks needed to start recurring billing: register the company, set up gateways and NF-e, create plans and products, import customers and activate the first subscription. ### impostos - [Taxes](https://docs.billing.kobana.com.br/en/impostos.md) #### motor-de-calculo The calculation engine determines all applicable taxes based on tax rules, the company profile, and the customer's tax type. - [Tax Calculation Engine](https://docs.billing.kobana.com.br/en/impostos/motor-de-calculo.md): The calculation engine determines all applicable taxes based on tax rules, the company profile, and the customer's tax type. #### perfil-fiscal The tax profile defines the tax configuration of each company (legal entity) within the organization. - [Tax Profile](https://docs.billing.kobana.com.br/en/impostos/perfil-fiscal.md): The tax profile defines the tax configuration of each company (legal entity) within the organization. #### periodos-fiscais Fiscal periods aggregate invoices for monthly or quarterly tax assessment. - [Fiscal Periods](https://docs.billing.kobana.com.br/en/impostos/periodos-fiscais.md): Fiscal periods aggregate invoices for monthly or quarterly tax assessment. #### regras-fiscais Tax rules allow configuring tax rates with different levels of specificity. - [Tax Rules](https://docs.billing.kobana.com.br/en/impostos/regras-fiscais.md): Tax rules allow configuring tax rates with different levels of specificity. #### relatorios-fiscais The fiscal reports area (/dashboard/fiscal/reports) consolidates the information needed for accounting close and for generating ancillary tax obligations. The data is built from the organization's paid invoices, issued NF-e, withholdings and closed tax periods. - [Fiscal Reports](https://docs.billing.kobana.com.br/en/impostos/relatorios-fiscais.md): The fiscal reports area (/dashboard/fiscal/reports) consolidates the information needed for accounting close and for generating ancillary tax obligations. The data is built from the organization's paid invoices, issued NF-e, withholdings and closed tax periods. #### retencoes Withholdings are taxes retained by the payer (customer) that must be tracked, reported, and offset. - [Withholdings at Source](https://docs.billing.kobana.com.br/en/impostos/retencoes.md): Withholdings are taxes retained by the payer (customer) that must be tracked, reported, and offset. #### simples-nacional The system automatically calculates the DAS (Simples Nacional Collection Document) based on revenue and the correct annex. - [Simples Nacional](https://docs.billing.kobana.com.br/en/impostos/simples-nacional.md): The system automatically calculates the DAS (Simples Nacional Collection Document) based on revenue and the correct annex. ### mcp #### overview - [Authentication](https://docs.billing.kobana.com.br/en/mcp/overview/authentication.md): The MCP server accepts a Bearer token in the Authorization header, and nothing else — no cookie, no client certificate. - [Clients](https://docs.billing.kobana.com.br/en/mcp/overview/clients.md): Any client that speaks Streamable HTTP MCP and can run the MCP OAuth 2.1 flow can connect. You only provide the URL; the client discovers where to authenticate on its own, opens the Kobana sign-in in the browser and keeps the token — see Authentication. - [Endpoints](https://docs.billing.kobana.com.br/en/mcp/overview/endpoints.md): MCP server - [Errors](https://docs.billing.kobana.com.br/en/mcp/overview/errors.md): Failures arrive on two different channels, and the difference matters: one is a broken request, the other is something the model is meant to read and react to. - [Idempotency](https://docs.billing.kobana.com.br/en/mcp/overview/idempotency.md): The tools that create a resource or move money accept an optional idempotency_key argument. It is sent to the endpoint as the X-Idempotency-Key header the REST API already honours. - [Introduction](https://docs.billing.kobana.com.br/en/mcp/overview/introduction.md): The Automatic Billing MCP server is a remote Model Context Protocol server that exposes the operations of the public API — customers, subscriptions, invoices, payments, tax invoices, proposals and usage — as tools an AI client can call. You connect it by URL; there is nothing to install. - [Listing, Sorting and Fields](https://docs.billing.kobana.com.br/en/mcp/overview/pagination.md): The _list tools use the same pagination as the REST API: by page number*. - [Rate Limiting](https://docs.billing.kobana.com.br/en/mcp/overview/rate-limit.md): The MCP server shares the same limits as the REST API, counted per person and organization — the token's sub and org, not the token itself. - [Resources and prompts](https://docs.billing.kobana.com.br/en/mcp/overview/resources-and-prompts.md): Besides tools, the server offers three things the client uses on its own: resources (documents the user attaches to the conversation), prompts (ready-made scripts the user picks) and completions (autocomplete for their arguments). On the 2026-07-28 era it also asks for confirmation before running a destructive tool. - [Transport](https://docs.billing.kobana.com.br/en/mcp/overview/transport.md): Streamable HTTP, stateless. One JSON-RPC 2.0 message per POST, one JSON response. There is no Mcp-Session-Id, no resumability and no server→client stream: the application runs several replicas, and every long operation already answers immediately and finishes in a background worker rather than on the MCP channel. #### tools - [Catalogue](https://docs.billing.kobana.com.br/en/mcp/tools/catalog.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Customers and access](https://docs.billing.kobana.com.br/en/mcp/tools/customers.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Tax and invoicing (NF-e)](https://docs.billing.kobana.com.br/en/mcp/tools/fiscal.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Invoices and receivables](https://docs.billing.kobana.com.br/en/mcp/tools/invoices.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Organization and schemas](https://docs.billing.kobana.com.br/en/mcp/tools/organization.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Tools](https://docs.billing.kobana.com.br/en/mcp/tools/overview.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Proposals](https://docs.billing.kobana.com.br/en/mcp/tools/proposals.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Subscriptions](https://docs.billing.kobana.com.br/en/mcp/tools/subscriptions.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} - [Usage](https://docs.billing.kobana.com.br/en/mcp/tools/usage.md): {/ Generated from the tool registry. The names, permissions and endpoints below are the ones tools/list returns. /} ### nota-fiscal - [Invoices (NF-e)](https://docs.billing.kobana.com.br/en/nota-fiscal.md) #### certificados The /dashboard/certificates page manages the A1 digital certificates used to sign NF-e and to authenticate with the municipal web services. Each certificate is linked to a registered company and is stored encrypted at rest. - [Digital Certificates](https://docs.billing.kobana.com.br/en/nota-fiscal/certificados.md): The /dashboard/certificates page manages the A1 digital certificates used to sign NF-e and to authenticate with the municipal web services. Each certificate is linked to a registered company and is stored encrypted at rest. #### configuracao Each organization can enable and configure automatic invoice issuance. - [NF-e Configuration](https://docs.billing.kobana.com.br/en/nota-fiscal/configuracao.md): Each organization can enable and configure automatic invoice issuance. #### emissao NF-e Statuses - [NF-e Issuance](https://docs.billing.kobana.com.br/en/nota-fiscal/emissao.md): NF-e Statuses #### provedores The system abstracts communication with NF-e providers through a common interface. - [NF-e Providers](https://docs.billing.kobana.com.br/en/nota-fiscal/provedores.md): The system abstracts communication with NF-e providers through a common interface. #### tentativas The system implements automatic retry for failed issuances. - [NF-e Retries](https://docs.billing.kobana.com.br/en/nota-fiscal/tentativas.md): The system implements automatic retry for failed issuances. ### planos-e-produtos - [Plans and Products](https://docs.billing.kobana.com.br/en/planos-e-produtos.md) #### grupos-de-planos Plan groups allow you to organize related plans to simplify management and visualization in the dashboard. - [Plan Groups](https://docs.billing.kobana.com.br/en/planos-e-produtos/grupos-de-planos.md): Plan groups allow you to organize related plans to simplify management and visualization in the dashboard. #### grupos-de-produtos Product groups allow you to categorize products to simplify organization, dashboard filtering, and linking with proposal templates. - [Product Groups](https://docs.billing.kobana.com.br/en/planos-e-produtos/grupos-de-produtos.md): Product groups allow you to categorize products to simplify organization, dashboard filtering, and linking with proposal templates. #### itens-de-servico Service items (/dashboard/service-items) are the catalog of fiscal descriptions used on service invoices and NF-e. Each item carries the information the municipality requires at issuance: municipal service code, LC 116 code, national tax code, and default ISS, PIS, COFINS, IR, INSS and CSLL rates. - [Service Items](https://docs.billing.kobana.com.br/en/planos-e-produtos/itens-de-servico.md): Service items (/dashboard/service-items) are the catalog of fiscal descriptions used on service invoices and NF-e. Each item carries the information the municipality requires at issuance: municipal service code, LC 116 code, national tax code, and default ISS, PIS, COFINS, IR, INSS and CSLL rates. #### planos Plans are the templates that define how your customers will be billed. Each plan groups products with specific prices and configures the billing cycle, trial period, and included features. - [Plans](https://docs.billing.kobana.com.br/en/planos-e-produtos/planos.md): Plans are the templates that define how your customers will be billed. Each plan groups products with specific prices and configures the billing cycle, trial period, and included features. #### precos Each product can have multiple prices, allowing variants by currency, billing interval, or pricing model. Prices are largely immutable after creation — only the name and metadata can be changed. To change values, deactivate the old price and create a new one. - [Prices and Pricing Models](https://docs.billing.kobana.com.br/en/planos-e-produtos/precos.md): Each product can have multiple prices, allowing variants by currency, billing interval, or pricing model. Prices are largely immutable after creation — only the name and metadata can be changed. To change values, deactivate the old price and create a new one. #### produtos Products represent the billable services or resources of your organization. Each product can have multiple prices and supports a one-level hierarchy (root product with children/add-ons). - [Products](https://docs.billing.kobana.com.br/en/planos-e-produtos/produtos.md): Products represent the billable services or resources of your organization. Each product can have multiple prices and supports a one-level hierarchy (root product with children/add-ons). ### portal - [Customer Portal](https://docs.billing.kobana.com.br/en/portal.md) #### assinaturas The /portal/subscriptions page lists the subscriptions linked to the authenticated billing account. Each row shows the plan, status, recurring amount, next cycle and available actions. - [Subscriptions](https://docs.billing.kobana.com.br/en/portal/assinaturas.md): The /portal/subscriptions page lists the subscriptions linked to the authenticated billing account. Each row shows the plan, status, recurring amount, next cycle and available actions. #### configuracoes The /portal/settings page groups billing account preferences that affect how the customer receives charges and communications. - [Settings](https://docs.billing.kobana.com.br/en/portal/configuracoes.md): The /portal/settings page groups billing account preferences that affect how the customer receives charges and communications. #### conta At /portal/account the customer manages the billing account details (BillingAccount) — legal name, CNPJ/CPF, state and municipal registration, address, finance contact and emails for receiving invoices. - [Account](https://docs.billing.kobana.com.br/en/portal/conta.md): At /portal/account the customer manages the billing account details (BillingAccount) — legal name, CNPJ/CPF, state and municipal registration, address, finance contact and emails for receiving invoices. #### creditos The /portal/credits page shows the billing account's credit balance and the history of applications. Credits arise for various reasons — downgrade proration, invoice refund, manual adjustment by the organization, promotion — and are automatically applied to upcoming invoices. - [Credits](https://docs.billing.kobana.com.br/en/portal/creditos.md): The /portal/credits page shows the billing account's credit balance and the history of applications. Credits arise for various reasons — downgrade proration, invoice refund, manual adjustment by the organization, promotion — and are automatically applied to upcoming invoices. #### faturas The /portal/invoices page lists all invoices of the billing account, with filters by status and period. The customer can view them, download the PDF, copy the boleto's typeable line or the PIX QR code, pay online and check the related NF-e. - [Invoices](https://docs.billing.kobana.com.br/en/portal/faturas.md): The /portal/invoices page lists all invoices of the billing account, with filters by status and period. The customer can view them, download the PDF, copy the boleto's typeable line or the PIX QR code, pay online and check the related NF-e. #### metodos-de-pagamento At /portal/payment-methods the customer manages the payment methods associated with the billing account. The page supports multiple methods at once and defines which one is the default for automatic charges. - [Payment Methods](https://docs.billing.kobana.com.br/en/portal/metodos-de-pagamento.md): At /portal/payment-methods the customer manages the payment methods associated with the billing account. The page supports multiple methods at once and defines which one is the default for automatic charges. #### pagamentos The /portal/payments page shows the history of payments already processed on the billing account — regardless of method or originating invoice. It is the statement view, useful for accounting checks and billing questions. - [Payments](https://docs.billing.kobana.com.br/en/portal/pagamentos.md): The /portal/payments page shows the history of payments already processed on the billing account — regardless of method or originating invoice. It is the statement view, useful for accounting checks and billing questions. #### perfil The /portal/profile page gathers the personal preferences of the user signed in to the portal. Unlike Account, which covers the paying legal entity or individual, the profile is per person who uses the portal. - [Profile](https://docs.billing.kobana.com.br/en/portal/perfil.md): The /portal/profile page gathers the personal preferences of the user signed in to the portal. Unlike Account, which covers the paying legal entity or individual, the profile is per person who uses the portal. #### produtos The /portal/products page is the self-service storefront of the products and plans the organization has published for direct sale in the portal. The customer can purchase new products without going through the sales team, with checkout integrated with the payment methods already registered. - [Products](https://docs.billing.kobana.com.br/en/portal/produtos.md): The /portal/products page is the self-service storefront of the products and plans the organization has published for direct sale in the portal. The customer can purchase new products without going through the sales team, with checkout integrated with the payment methods already registered. #### propostas At /portal/proposals the customer sees the commercial proposals sent by the organization's team. Each proposal details plans, items, discounts, terms and conditions — and can be accepted directly in the portal, becoming an active subscription. - [Proposals](https://docs.billing.kobana.com.br/en/portal/propostas.md): At /portal/proposals the customer sees the commercial proposals sent by the organization's team. Each proposal details plans, items, discounts, terms and conditions — and can be accepted directly in the portal, becoming an active subscription. #### uso The /portal/usage page shows the customer the metered consumption accumulated in the current cycle — how many API calls, messages sent, events processed or GBs stored, according to the metrics defined by the organization. - [Usage](https://docs.billing.kobana.com.br/en/portal/uso.md): The /portal/usage page shows the customer the metered consumption accumulated in the current cycle — how many API calls, messages sent, events processed or GBs stored, according to the metrics defined by the organization. #### visao-geral The portal home page (/portal) gives a summary of the customer's financial relationship with the organization: active subscription, next invoice, last payment, available credits and shortcuts to the most common actions. - [Overview](https://docs.billing.kobana.com.br/en/portal/visao-geral.md): The portal home page (/portal) gives a summary of the customer's financial relationship with the organization: active subscription, next invoice, last payment, available credits and shortcuts to the most common actions. ### propostas - [Proposals](https://docs.billing.kobana.com.br/en/propostas.md) #### geracao-de-pdf The system generates proposal PDFs by integrating with Google Docs/Slides via Google Apps Script. - [PDF Generation](https://docs.billing.kobana.com.br/en/propostas/geracao-de-pdf.md): The system generates proposal PDFs by integrating with Google Docs/Slides via Google Apps Script. #### propostas Proposals are commercial documents sent to customers or prospects containing items, prices, and payment terms. - [Proposals](https://docs.billing.kobana.com.br/en/propostas/propostas.md): Proposals are commercial documents sent to customers or prospects containing items, prices, and payment terms. #### templates Templates define the document model used to generate proposal PDFs. - [Proposal Templates](https://docs.billing.kobana.com.br/en/propostas/templates.md): Templates define the document model used to generate proposal PDFs. ### webhooks - [Webhooks](https://docs.billing.kobana.com.br/en/webhooks.md) #### endpoints Each organization can configure multiple endpoints to receive event notifications. - [Webhook Endpoints](https://docs.billing.kobana.com.br/en/webhooks/endpoints.md): Each organization can configure multiple endpoints to receive event notifications. #### entregas Each notification sent to an endpoint is recorded as a delivery, enabling monitoring and retry. - [Webhook Deliveries](https://docs.billing.kobana.com.br/en/webhooks/entregas.md): Each notification sent to an endpoint is recorded as a delivery, enabling monitoring and retry. #### eventos The system emits events for all significant operations. Each organization can subscribe to the relevant types. - [Webhook Events](https://docs.billing.kobana.com.br/en/webhooks/eventos.md): The system emits events for all significant operations. Each organization can subscribe to the relevant types. --- # Full Documentation Content [Skip to main content](#__docusaurus_skipToContent_fallback) [![Kobana](/en/img/kobana-logo-hor-positivo.png)![Kobana](/en/img/kobana-logo-hor-negativo.png)](https://docs.billing.kobana.com.br/en/en/.md) [**Automatic Billing**](https://docs.billing.kobana.com.br/en/en/.md) Documentation [Documentation](https://docs.billing.kobana.com.br/en/en/.md)[API](https://docs.billing.kobana.com.br/en/en/api/overview/introduction.md)[MCP](https://docs.billing.kobana.com.br/en/en/mcp/overview/introduction.md)[CLI](https://docs.billing.kobana.com.br/en/en/cli/overview/introduction.md) Ask AI [](#) * [🇧🇷 Português](https://docs.billing.kobana.com.br/en/pt/search) * [🇺🇸 English](https://docs.billing.kobana.com.br/en/en/search.md) * [🇪🇸 Español](https://docs.billing.kobana.com.br/en/es/search) Search # Search the documentation ![Empresa Neutra em Carbono](/en/img/badge-neutra-carbono.webp)![Empresa Parceira da Natureza](/en/img/badge-parceira-natureza.webp) Comercial[3003-0386](tel:+551130030386) [](https://wa.me/551130030386)[](mailto:comercial@kobana.com.br) ![Kobana](/en/img/kobana-logo-site.webp)![](/en/img/kobana-cegonha.webp) © 2008/2026 Kobana Tecnologia Ltda. | CNPJ: 05.813.794/0001-26 | Calçada das Margaridas, 163, Sala 02 — Centro Comercial Alphaville — Barueri, SP — 06453-038 --- # API reference --- # Authentication The Automatic Billing API uses a **Kobana Account access token** to authenticate every request. ## The token[​](#the-token "Direct link to The token") The token is an `RS256` JWT issued by the **Kobana Authorization Server** (`account.kobana.com.br`). This API only **verifies** it, against the public key that server publishes — it holds no signing key and cannot issue any token. The **`org`** claim identifies your organization: all returned data is automatically scoped to it. Requirements checked on every request: | Claim | Requirement | | ----- | ----------------------------------------------------------------------------------------------------------------------------- | | `iss` | The Authorization Server identifier, as a URL: `https://account[.{env}].kobana.com.br` | | `aud` | The URL of this API: `https://api.billing[.{env}].kobana.com.br`. It may be a **list** — the rule is *contains*, not equality | | `exp` | **Required.** A token with no expiration is rejected | | `org` | **The Kobana account** on whose behalf the token acts — it is what resolves the organization here, and it is **required** | | `sub` | **The person** (`users.public_id`). It goes to auditing and attribution; it scopes nothing | | `jti` | Unique token id — the basis of auditing | :::caution Change from the API key Until September 2026 the credential was a key created in the dashboard (`kb_…`), with a public prefix and a secret shown only once. The key was both the credential and what verified it — whoever read the key store could act as any organization, and every rotation was a conversation with a customer. Now the Authorization Server issues the token and the platform only verifies it. **A key created under Settings → API no longer authenticates this API.** ::: Check the environment The token is **different** between Sandbox and Production — the `aud` of one is not valid in the other. Do not reuse a token across environments. ## How to send the token[​](#how-to-send-the-token "Direct link to How to send the token") Include the `Authorization: Bearer ` header in every request. ``` export KOBANA_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx curl -i \ -H "Authorization: Bearer $KOBANA_TOKEN" \ -H 'Content-Type: application/json' \ -H 'User-Agent: Meu Nome (meunome@example.com)' \ -X GET 'https://api.billing.sandbox.kobana.com.br/v1/organization' ``` ## Valid request[​](#valid-request "Direct link to Valid request") With a valid token, the response carries the authenticated Organization's data. ``` HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Request-Id: req_01HABCDEF { "id": "org_01HORG", "name": "Minha Empresa", "email": "contato@minhaempresa.com.br", "document_type": "cnpj", "document_number": "12345678000190", "environment": "sandbox", "created_at": "2026-01-01T00:00:00.000Z" } ``` ## Invalid request[​](#invalid-request "Direct link to Invalid request") A missing, malformed or expired token returns `401 Unauthorized`. ``` curl -i \ -H "Authorization: Bearer tokeninvalido" \ -H 'Content-Type: application/json' \ -H 'User-Agent: Meu Nome (meunome@example.com)' \ -X GET 'https://api.billing.sandbox.kobana.com.br/v1/organization' ``` ``` HTTP/1.1 401 Unauthorized Content-Type: application/json; charset=utf-8 { "error": { "code": "invalid_token", "message": "Token de acesso inválido ou expirado." } } ``` Fine-grained codes help you find the error right away: `invalid_token` (missing, malformed or invalid signature), `invalid_audience` (token from another Kobana app) and `unknown_organization` — the latter is a `403`: the token is valid, it is the organization that is not here. **If our Authorization Server is down**, the response is `5xx`, not `401`. This is deliberate: a `401` would send you debugging a perfectly good credential during our outage. Try again in a moment. :::note `sub` is not the tenant `sub` is the person and `org` is the customer — they are uuids from different tables, so swapping them does not cause a format error. A token without `org` is rejected instead of falling back to `sub`: that fallback would match no organization and answer `403` on everything, with the symptom pointing at permissions rather than at the claim that was read. ::: ## Scopes[​](#scopes "Direct link to Scopes") Scopes are **enforced on every request**, and each request requires **a single access level**: what the method asks for (`GET` reads, `DELETE` deletes, `POST`/`PUT`/`PATCH` write), or what the endpoint declares when no method says it (bulk import and export). There are two token formats, and each is read differently. ### The six access levels[​](#the-six-access-levels "Direct link to The six access levels") | Level | Grants | | -------- | --------------------------------------- | | `read` | Read (`GET`, `HEAD`) | | `write` | Read and write (`POST`, `PUT`, `PATCH`) | | `delete` | Deletion (`DELETE`), single or batch | | `import` | Bulk import | | `export` | Bulk export | | `all` | Everything | **One level never stands in for another.** `write` does not delete, import or export; `delete`, `import` and `export` neither read nor write. Combine the levels your integration needs — `read delete` lists and deletes, `read write delete` does all three. ### The level each endpoint requires[​](#the-level-each-endpoint-requires "Direct link to The level each endpoint requires") | Endpoint | Level | | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | | `GET` / `HEAD` | `read` | | `POST` / `PUT` / `PATCH` | `write` | | `DELETE` — every deletion is a `DELETE`, including the batch one (`DELETE /v1/{resource}/bulk`) and the one that only marks the record as deleted | `delete` | | `POST /v1/nfes/import-barueri` | `import` | | Bulk export — this API has none yet; the PDF or XML of **one** document (`/invoices/{id}/pdf`, `/nfes/{id}/xml`) is a read | `export` | | `GET /v1/me` | Any valid token | Every `DELETE` is a deletion, and nothing but a deletion is a `DELETE`: archiving (`POST …/archive`), unarchiving (`POST …/unarchive`), deactivating (`POST …/deactivate`), closing (`POST …/close`) and canceling (`POST …/cancel`) are writes. A deletion is a **soft delete** whenever the record has history to preserve: it gets `deleted_at` and disappears from every read (lists, `GET` by id, filters), while the invoices, payments and NFS-e that reference it keep the reference. :::caution October 2026 change * **`DELETE` requires `delete`** (or `all`). Before, a `DELETE` also accepted `write`; a token with only `write` now receives `403 insufficient_scope` when deleting. Request the `delete` level in the Kobana Account for the integrations that delete. * **`POST /v1/nfes/import-barueri` requires `import`** (or `all`); `write` is not enough. * **`DELETE` now deletes** (soft delete, `deleted_at`) where it used to only change a status. Anyone who used `DELETE` to archive, deactivate or close must call the dedicated route: | Endpoint | Before | Now | For the old effect | | ------------------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------- | | `DELETE /v1/products/{id}` | archived | deletes | `POST /v1/products/{id}/archive` | | `DELETE /v1/plans/{id}` | archived; `?hard=true` deleted a draft | deletes (the `hard` parameter no longer exists) | `POST /v1/plans/{id}/archive` (new) | | `DELETE /v1/companies/{id}` | deactivated | deletes | `POST /v1/companies/{id}/deactivate` | | `DELETE /v1/billing_accounts/{id}` | closed (`?reason=`) and returned the account | deletes, along with payment methods, cards, portal users and files, and returns `{ "deleted": true }` | `POST /v1/billing_accounts/{id}/close` | | `DELETE /v1/customers/{id}/users/{user_id}` | deleted the pending invitation; suspended the active user | deletes both | — | | `DELETE /v1/service_items/{id}` | deleted, or only deactivated if a tax rule used it | deletes | `PATCH` with `is_active=false` | | `DELETE /v1/payment_methods/{id}` | marked it `removed` | deletes (and stays `removed` where it appears through a relation) | — | | `DELETE /v1/{products,plans}/bulk` | deleted permanently | deletes (soft delete), same rules as the single `DELETE` | — | A deleted record no longer appears in any `GET` — not even with a status filter. To keep querying it, archive instead of deleting. * **Endpoints that changed method** — same JSON body, same response; the old endpoint no longer exists: | Before | Now | | --------------------------------------------------------------------- | ------------------------------------------------ | | `POST /v1/nfes/bulk-delete` | `DELETE /v1/nfes/bulk` | | `POST /v1/plans/bulk-delete` | `DELETE /v1/plans/bulk` | | `POST /v1/products/bulk-delete` | `DELETE /v1/products/bulk` | | `POST /v1/proposals/bulk-delete` | `DELETE /v1/proposals/bulk` | | `DELETE /v1/product_groups/{id}/archive` (unarchive) | `POST /v1/product_groups/{id}/unarchive` | | `DELETE /v1/subscription_item_changes/{id}` (cancel scheduled change) | `POST /v1/subscription_item_changes/{id}/cancel` | | ::: | | ### Token with access levels only[​](#token-with-access-levels-only "Direct link to Token with access levels only") A token with no `billing/…` scope (that of a REST integration) is read only by the **access levels** it carries, and they apply to all resources: `read write` reads and writes everything, and deletes nothing. ### Token with resource scopes[​](#token-with-resource-scopes "Direct link to Token with resource scopes") A token that carries `billing/…` scopes (the personal token created in the Kobana Account wizard, or that of an MCP client) has **two orthogonal axes**: the **resource**, always prefixed by the app (`billing/subscriptions`), and the **level**, an unprefixed global scope (`write`, `delete`, `import`, `export`). **Resources define the reach, and levels only apply within it.** Reading requires the resource; anything else requires the resource *and* the level. | Group | Resource scopes | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Customers and access | `billing/customers`, `billing/companies`, `billing/portal_users`, `billing/dashboard_users`, `billing/team_roles` | | Catalog | `billing/plans`, `billing/plan_groups`, `billing/products`, `billing/product_groups`, `billing/service_items` | | Subscriptions | `billing/subscriptions`, `billing/subscription_changes`, `billing/subscription_item_changes`, `billing/plan_changes` | | Billing | `billing/invoices`, `billing/payments`, `billing/payment_methods`, `billing/credits`, `billing/coupons` | | Tax | `billing/nfes`, `billing/tax_rules`, `billing/tax_periods`, `billing/withholdings`, `billing/certificates` | | Proposals | `billing/proposals`, `billing/proposal_templates` | | Account and usage | `billing/organization`, `billing/billing_accounts`, `billing/usage` | | **Resource wildcard** | `billing/all` — reaches **all** resources, including those not on the list, and **grants no level** | | **Global levels** | `write` (`POST`, `PUT`, `PATCH`), `delete` (`DELETE`), `import` (bulk import), `export` (bulk export) — apply to the resources the token reaches; `all` grants every one | Three examples: `billing/invoices` reads invoices and does not write; `billing/invoices write` also creates, changes and cancels, and still neither deletes nor reaches subscriptions; `billing/products write delete` maintains the product catalog, batch deletion included. Bank accounts, banks, Pix keys, holidays, late fee policies and credit purchases (`/bank_accounts`, `/banks`, `/pix_keys`, `/holidays`, `/late_fee_policies`, `/credit_purchases`) have no resource scope of their own: a token with resource scopes only reaches them with `billing/all`. The granular form `billing/invoices:write` is an **exception** to the grammar, not the default format: it satisfies both axes for that one resource only, and exists for "reads one resource, writes another". `billing/*` is a **registration** wildcard and is never issued in a token — the comparison here is always literal. A token that carries no scope this API recognizes — neither an access level nor `billing/…` — reaches nothing beyond `GET /v1/me`. ### Insufficient scope[​](#insufficient-scope "Direct link to Insufficient scope") A missing scope answers `403 insufficient_scope`, with the levels that would have sufficed and the scopes the token carries: ``` HTTP/1.1 403 Forbidden Content-Type: application/json; charset=utf-8 { "error": { "code": "insufficient_scope", "message": "This token was not granted delete access. Authorize again with delete access to delete data.", "details": { "required": ["delete", "all"], "granted": ["read", "write"] } } } ``` `GET /v1/me` answers any valid token, whatever its scope — it is how you check the token you have. ## Best practices[​](#best-practices "Direct link to Best practices") * **Never** commit tokens to git. Use environment variables or vaults (AWS Secrets Manager, Vault, etc.). * Use distinct tokens per integration (CRM, ERP, frontend, etc.) — it makes swapping one without taking down the others easier, and auditing by `jti` stays readable. * Request the minimum scopes needed (principle of least privilege) — a resource with no verb when the integration only reads. * Prefer short-lived tokens: this API does not consult a revocation list, so a leaked token is valid until its `exp`. Replace the credential in the Kobana Account as soon as you learn of the leak. * HTTPS required — calls over HTTP are rejected. --- # Data Retention This page describes how long each type of data is kept in Automatic Billing. ## Active Customers[​](#active-customers "Direct link to Active Customers") Retention time for Organizations with active subscriptions and payments up to date. | Data type | Time (in months) | | ---------------------------- | ---------------- | | Events | 12 | | Webhook Deliveries | 12 | | Email Sends | 12 | | SMS Sends | 12 | | Audit Logs | 12 | | API Requests | 3 | | Invoices | Indefinitely | | Payments | Indefinitely | | Subscriptions | Indefinitely | | Plans and Products | Indefinitely | | Customers (Billing Accounts) | Indefinitely | | Issued NF-e | Indefinitely | | Coupons and Credits | Indefinitely | | Any data not listed | Indefinitely | ## Inactive Customers[​](#inactive-customers "Direct link to Inactive Customers") Retention time for Organizations with canceled or suspended subscriptions, or delinquent accounts beyond the grace period. | Data type | Time (in months) | | ---------------------------- | ------------------- | | Events | 1 | | Webhook Deliveries | 1 | | Email Sends | 1 | | SMS Sends | 1 | | Audit Logs | 3 | | Invoices | 3 | | Payments | 3 | | Subscriptions | 3 | | Plans and Products | 3 | | Customers (Billing Accounts) | 3 | | Issued NF-e | 60 (tax obligation) | | Coupons and Credits | 3 | | Any other data not listed | 3 | NF-e has a minimum retention of 5 years under Brazilian tax law, even after the Organization becomes inactive. The times above may be changed at any time. ## Sandbox[​](#sandbox "Direct link to Sandbox") Data in Sandbox may be cleared at any time without prior notice. Do not rely on Sandbox for long-term retention of test data. --- # Endpoints ## Platform (web access)[​](#platform-web-access "Direct link to Platform (web access)") | Environment | URL | | ----------- | ------------------------------------------- | | Sandbox | | | Production | | ## API (v1)[​](#api-v1 "Direct link to API (v1)") | Environment | URL | | ----------- | ------------------------------------------- | | Sandbox | | | Production | | ## Documentation[​](#documentation "Direct link to Documentation") | Environment | URL | | ------------- | ------------------------------------ | | Documentation | | --- # Idempotency The API supports idempotency so requests can be safely retried without executing the same operation twice. Useful when a call is interrupted in transit and you don't get a response — for example, a request to create a subscription that drops on a network error can be retried with the same key, guaranteeing that only one subscription is created. ## How to use it[​](#how-to-use-it "Direct link to How to use it") Send the `X-Idempotency-Key: ` header on any `POST`, `PUT` or `PATCH` request. The key is opaque and generated on your side. We recommend `UUID v4` or any random string with enough entropy to avoid collisions. ``` curl -i \ -H "Authorization: Bearer $KOBANA_TOKEN" \ -H 'Content-Type: application/json' \ -H 'X-Idempotency-Key: 8c0f5d6e-3f8b-4cb5-9a47-d8f5b15e9b21' \ -H 'User-Agent: Kevin Mitnick ' \ -d '{ "subscription": { "billing_account_id": "ba_01HXY123", "plan_id": "plan_01HPRO", "billing_cycle": "monthly" } }' \ -X POST 'https://api.billing.sandbox.kobana.com.br/v1/subscriptions' ``` ## How it works[​](#how-it-works "Direct link to How it works") When the server receives a request carrying `X-Idempotency-Key`: 1. **Reserves the key** atomically, scoped to your **organization**. Two different organizations can use the same key without conflict. 2. **Computes a request fingerprint** — SHA-256 of `method + path + raw body`. The hash is stored alongside the key. 3. **Runs the handler**. If it returns a response, the server records `status_code`, body, and relevant headers tied to the key. 4. **Marks the key as completed**. Any subsequent request reusing the key within **24 hours** receives the original response verbatim — same `status_code`, same body, same headers — plus an `X-Idempotent-Replay: true` header that flags it as a replay. The layer records the result **regardless of success or failure**. Retries with the same key return the same result, **including `5xx` errors**. ### Limits[​](#limits "Direct link to Limits") * Maximum key length: **255 characters**. * Retention: keys expire automatically **24 hours** after creation. After expiry, a new request reusing the key yields a fresh result. * Scope: per organization. A key used in one organization does not interfere with another. * Accepted characters: any printable UTF-8 string. ## When the result is **not** recorded[​](#when-the-result-is-not-recorded "Direct link to when-the-result-is-not-recorded") The layer only records the result once the handler started executing. Nothing is stored in the following cases — it is safe to resend the request: * The key is empty or longer than **255 characters** → `400 bad_request`. * The API envelope rejects the request before the handler (invalid JSON, missing authentication, etc.). * The handler **throws an exception** mid-execution — the reservation is released so the next retry can run cleanly. * Another request with the same key is currently executing → `409 conflict` with `details.reason = "idempotency_request_in_progress"`. ## Conflicts[​](#conflicts "Direct link to Conflicts") If the same key is reused with a different request (any change in method, path, or body), the API responds `409 conflict` with `details.reason = "idempotency_key_reused"`. This guards against accidental reuse — for example, persisting the key alongside the operation on your side and then trying to create two different resources under the same identifier. ### Error response[​](#error-response "Direct link to Error response") ``` { "error": { "code": "conflict", "message": "X-Idempotency-Key was already used with different request parameters. Reuse the original parameters or generate a new key.", "details": { "reason": "idempotency_key_reused" } } } ``` ### Other possible responses[​](#other-possible-responses "Direct link to Other possible responses") | Scenario | Status | `error.code` | `details.reason` | | -------------------------------------------- | ------ | ------------- | --------------------------------- | | Another request with the same key is running | `409` | `conflict` | `idempotency_request_in_progress` | | Same key reused with a different payload | `409` | `conflict` | `idempotency_key_reused` | | Key empty or longer than 255 characters | `400` | `bad_request` | `invalid_idempotency_key` | ## Accepted methods[​](#accepted-methods "Direct link to Accepted methods") | Method | Accepts `X-Idempotency-Key`? | | -------- | ---------------------------------------- | | `POST` | ✅ Yes | | `PUT` | ✅ Yes | | `PATCH` | ✅ Yes | | `GET` | ❌ No (already idempotent by definition) | | `DELETE` | ❌ No (already idempotent by definition) | Sending the key on `GET` or `DELETE` has no effect — the API processes the request normally without recording anything. ## Detecting a replay[​](#detecting-a-replay "Direct link to Detecting a replay") Every response served from the recorded result carries the header: ``` X-Idempotent-Replay: true ``` You can use this header on your side to tell the original execution apart from a server-side replay. ## Best practices[​](#best-practices "Direct link to Best practices") * **One key per logical operation.** Don't reuse the same key to create two different resources — you will get `409 conflict`. * **Persist the key alongside the operation state** on your side, so a retry after a crash or restart still uses the same key. * **Pair it with exponential backoff** on `5xx` or timeout responses — the key guarantees the retry doesn't duplicate the resource. Because failures are also recorded, you can stop retrying as soon as the expected status code comes back. * **Drop the key after 24 hours.** No value in keeping it on your side beyond that — the server has already discarded the record. * **Don't send the key on methods that don't accept it.** It is silently ignored on `GET`/`DELETE` — we prefer clients to omit it so the contract is explicit about what's idempotent and what relies on the key. --- # Introduction If you are a dev, have fun! ✨ ## Format[​](#format "Direct link to Format") The API accepts only the `JSON` format. All requests must use `Content-Type: application/json`. All responses use `snake_case`. | Field Type | Format | | ------------ | --------------------------------------------------------------------------------------------------------------------------- | | **DateTime** | [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) format. Examples — Date: `2026-01-24`. Date and time: `2026-01-24T10:07Z` | | **Money** | Decimal number in reais (BRL), with up to 4 decimal places. E.g.: `100.5` = R$ 100.50 | | **UUID** | Resource identifiers in UUID v4 format | ## Conventions[​](#conventions "Direct link to Conventions") Conventions used in this documentation: | Convention | Description | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **`:variable`** | Variable name that must be replaced in a URL. | | **`#{variable}`** | Variable name that must be replaced with values from your account. | | **`...`** | Response content truncated for readability. | | **`$KOBANA_TOKEN`** | Access token. For command-line testing, export it: `export KOBANA_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx` and paste the commands from the documentation into the terminal. | ## Response Codes[​](#response-codes "Direct link to Response Codes") The API returns standard HTTP codes: | | Code | Description | | -- | ----------------------------- | --------------------------------------------------------------------------------- | | ✅ | **200 OK** | Successful request with a response body. | | ✅ | **201 Created** | Resource created successfully. | | ✅ | **204 No Content** | Successful request, with no response body. | | ❌ | **400 Bad Request** | Invalid request, usually malformed content. | | ❌ | **401 Unauthorized** | Access token missing or invalid. | | ❌ | **403 Forbidden** | API access blocked or user without permission. | | ❌ | **404 Not Found** | The address accessed does not exist. | | ❌ | **422 Unprocessable Entity** | Valid request, but the data sent is not. | | ❌ | **429 Too Many Requests** | Request limit reached. | | ❌ | **500 Internal Server Error** | Internal processing error. See the [server status](https://status.kobana.com.br). | ## Request ID[​](#request-id "Direct link to Request ID") Each request has an associated identifier, available in the `Request-Id` response header. This value helps with debugging and auditing — requests and their IDs can be looked up in the system dashboard. The request log is available for **30 days**. When opening a support ticket about a specific request, provide the `Request-Id` to speed up the investigation. ## Security[​](#security "Direct link to Security") The Kobana API uses **2048-bit SSL** certificates. Every request must be made over **HTTPS** — calls on port 80 are redirected to 443. Clients must support `TLSv1.2` or `TLSv1.3` with one of the ciphers: `TLS_AES_128_GCM_SHA256`, `TLS_AES_256_GCM_SHA384`, `TLS_CHACHA20_POLY1305_SHA256`, `ECDHE-RSA-AES128-GCM-SHA256`, `ECDHE-RSA-AES128-SHA256`, `ECDHE-RSA-AES256-GCM-SHA384`, `ECDHE-RSA-CHACHA20-POLY1305`, `ECDHE-RSA-AES256-SHA384`. `TLSv1` and `TLSv1.1` are not supported. ## HTTP Cache[​](#http-cache "Direct link to HTTP Cache") Use the HTTP cache headers to reduce load and gain speed. Most responses include `ETag` and/or `Last-Modified` — store these values and resend them in subsequent requests via `If-None-Match` and `If-Modified-Since`. If the resource has not changed, the response will be `304 Not Modified`, with no body and no reprocessing. More information: [HTTP Cache Docs](http://www.mnot.net/cache_docs/). ## Error Handling[​](#error-handling "Direct link to Error Handling") 5xx errors indicate server failures: **500 Internal Server Error** (application unavailable), **502 Bad Gateway**, **503 Service Unavailable** and **504 Gateway Timeout** (occasional infrastructure failures). Your application should identify these codes and reschedule the request after a few minutes with backoff. Server status: . ## Monetary values[​](#monetary-values "Direct link to Monetary values") Every monetary value — in the request and in the response — is a decimal number in reais (BRL), with up to 4 decimal places. There are no fields in cents: send `100.5` for R$ 100.50 and `0.0125` for R$ 0.0125. Pricing fields accept all 4 decimal places; the others are rounded to 2. ## Next steps[​](#next-steps "Direct link to Next steps") * [Specifications](https://docs.billing.kobana.com.br/en/en/api/overview/openapi.md) — OpenAPI 3.1 in YAML for download. * [Endpoints](https://docs.billing.kobana.com.br/en/en/api/overview/endpoints.md) — Sandbox and Production URLs. * [User-Agent](https://docs.billing.kobana.com.br/en/en/api/overview/user-agent.md) — recommended header to identify your application. * [Rate Limit](https://docs.billing.kobana.com.br/en/en/api/overview/rate-limit.md) — throttling and response headers. * [Idempotency](https://docs.billing.kobana.com.br/en/en/api/overview/idempotency.md) — `X-Idempotency-Key` for safe retries. * [Webhooks](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks.md) — events fired in real time. * [Data Retention](https://docs.billing.kobana.com.br/en/en/api/overview/data-retention.md) — retention policy by resource type. --- # OpenAPI We publicly maintain the Automatic Billing API specification files in an open format so you can download them and use them in the tool of your choice. ## OpenAPI 3.1[​](#openapi-31 "Direct link to OpenAPI 3.1") | Version | Language | File | | ------- | --------- | ------------------------------------------------------------------------------------------------------------------------------- | | v1 | Português | [openapi-v1-pt.yaml](https://docs.billing.kobana.com.br/en/en/assets/files/openapi-v1-pt-c96fdd39d7e5abca6e9821296fdaf848.yaml) | | v1 | English | [openapi-v1-en.yaml](https://docs.billing.kobana.com.br/en/en/assets/files/openapi-v1-en-62097be868d8fc203d6bd3082589d316.yaml) | | v1 | Español | [openapi-v1-es.yaml](https://docs.billing.kobana.com.br/en/en/assets/files/openapi-v1-es-4e3188d5390aab00d50f977b7fc5600a.yaml) | ## Postman Collection[​](#postman-collection "Direct link to Postman Collection") Also available as a ready-to-import Postman collection. Details and files in [Postman](https://docs.billing.kobana.com.br/en/en/api/overview/postman.md). --- # Listing and Pagination All `GET` endpoints that return collections (`/v1/customers`, `/v1/subscriptions`, `/v1/invoices`, etc.) use **page-number** pagination. ## Parameters[​](#parameters "Direct link to Parameters") Sent via query string: | Parameter | Type | Default | Description | | ------------ | --------------- | ------------------ | --------------------------------------------------------------- | | `page` | integer ≥ 1 | `1` | Requested page (starts at 1). | | `per_page` | integer 1–100 | `20` | Number of items per page. Maximum **100**. | | `sort_by` | string | varies by resource | Field used for sorting. Accepts the same names as the response. | | `sort_order` | `asc` or `desc` | `desc` | Sort direction. | Out-of-range values are clamped (e.g.: `per_page=999` becomes `100`; `page=0` becomes `1`). ## Response[​](#response "Direct link to Response") Every listing follows this envelope: ``` { "data": [ { "id": "per_01HPER", "name": "João Silva", "email": "joao@example.com" } ], "meta": { "total": 142, "page": 1, "per_page": 20, "total_pages": 8 } } ``` | Field | Description | | ------------------ | ----------------------------------------------------------- | | `data` | Array with the items of the current page. | | `meta.total` | Total items matching the filters (not just those returned). | | `meta.page` | Current page. | | `meta.per_page` | Items per page actually applied. | | `meta.total_pages` | Total number of pages (`ceil(total / per_page)`). | The last page may contain fewer than `per_page` items. When `page > total_pages`, `data` comes back empty (it is not an error). ## Examples[​](#examples "Direct link to Examples") ### First page, default[​](#first-page-default "Direct link to First page, default") ``` curl -H "Authorization: Bearer $KOBANA_TOKEN" \ 'https://api.billing.sandbox.kobana.com.br/v1/customers' ``` ### Page 3 with 50 items[​](#page-3-with-50-items "Direct link to Page 3 with 50 items") ``` curl -H "Authorization: Bearer $KOBANA_TOKEN" \ 'https://api.billing.sandbox.kobana.com.br/v1/customers?page=3&per_page=50' ``` ### Sorted by `name` ascending[​](#sorted-by-name-ascending "Direct link to sorted-by-name-ascending") ``` curl -H "Authorization: Bearer $KOBANA_TOKEN" \ 'https://api.billing.sandbox.kobana.com.br/v1/customers?sort_by=name&sort_order=asc' ``` ### Filters + pagination[​](#filters--pagination "Direct link to Filters + pagination") Resource-specific filters coexist with `page`/`per_page`: ``` curl -H "Authorization: Bearer $KOBANA_TOKEN" \ 'https://api.billing.sandbox.kobana.com.br/v1/customers?search=joao&page=2&per_page=25' ``` ## Iterating over all pages[​](#iterating-over-all-pages "Direct link to Iterating over all pages") Recommended pattern in pseudo-code: ``` async function fetchAll(url, token) { const out = []; let page = 1; while (true) { const res = await fetch(`${url}?page=${page}&per_page=100`, { headers: { Authorization: `Bearer ${token}` }, }); const { data, meta } = await res.json(); out.push(...data); if (page >= meta.total_pages) break; page += 1; } return out; } ``` ## Best practices[​](#best-practices "Direct link to Best practices") * For incremental synchronization, prefer filtering by `updated_at_gte` (or similar available on the endpoint) instead of sweeping all pages. * `per_page=100` minimizes the number of requests and consumes less of the [rate limit](https://docs.billing.kobana.com.br/en/en/api/overview/rate-limit.md). * **Cache** `meta.total` when rendering paginators; do not recompute it on every navigation. * Avoid assuming a stable order without an explicit `sort_by` — the default order may change between resources. --- # Postman If you prefer testing the API through Postman, download the collection in your preferred language and import it — or open the online version straight from Kobana's public workspace. ## Public workspace[​](#public-workspace "Direct link to Public workspace") The v1 collections of the Automatic Billing API are published in the [**universokobana/kobana-billing-api**](https://www.postman.com/universokobana/kobana-billing-api/overview) workspace, with one collection per language. [![Kobana Billing API workspace on Postman](/en/assets/images/postman-workspace-kobana-billing-api-90ee622934c0c69710b5d26a95ef41c5.png)](https://www.postman.com/universokobana/kobana-billing-api/overview) ## Collection[​](#collection "Direct link to Collection") Open directly in Postman (web or app): [**Automatic Billing API (v1.0.0) — English**](https://www.postman.com/universokobana/kobana-billing-api/collection/6o3qr3u/automated-billing-api-v1-0-0-english). ## Downloadable collections[​](#downloadable-collections "Direct link to Downloadable collections") Prefer to import locally? Download the `.json` file: | Version | Language | File | | ------- | --------- | ------------------------------------------------------------------------------------------------------------------------------- | | v1 | Português | [postman-v1-pt.json](https://docs.billing.kobana.com.br/en/en/assets/files/postman-v1-pt-237ab7a2a047fb07c78b74c423d5230a.json) | | v1 | English | [postman-v1-en.json](https://docs.billing.kobana.com.br/en/en/assets/files/postman-v1-en-68ac75a8e45a054be700f9028be4bf62.json) | | v1 | Español | [postman-v1-es.json](https://docs.billing.kobana.com.br/en/en/assets/files/postman-v1-es-a877a62f36fd3e5dd48fe2d3b6976c8d.json) | ## Usage[​](#usage "Direct link to Usage") 1. Import the downloaded `.json` file in Postman (**File → Import**) — or open the [online collection](#collection) directly. 2. Open the collection's **Variables** tab and fill in: * `baseUrl` — production or sandbox (`https://api.billing.sandbox.kobana.com.br`). * `bearerToken` — your JWT, generated at **Integrations → Kobana API → API Token**. 3. Bearer authentication is already configured at the collection level, pointing to `{{bearerToken}}`. 4. Open any request, adjust parameters if needed, and click **Send**. --- # Rate Limit When a client exceeds the limit associated with it, subsequent requests are blocked. The server responds with information about the limits used and the wait time required before sending a new request, attached to the response headers: | Header | Example | Description | | --------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `ratelimit-limit` | `60` | Request limit for the client. | | `ratelimit-name` | `throttle_authenticated_web` | Name of the throttle used. | | `ratelimit-remaining` | `0` | Number of requests available. | | `ratelimit-reset` | `1609844400` | [Unix time](https://en.wikipedia.org/wiki/Unix_time) — when the count resets. | | `retry-after` | `30` | Seconds until the count resets. See [Retry-After](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After). | There are two kinds of limits: `GET` requests and `POST` requests. In both cases the count is made per **hour**. Maximum limits: * **60 requests/hour** for `GET` * **1000 requests/hour** for `POST` If your operation needs a higher number, contact support or sales. The count is reset in the first minute of each hour. On every request, the server returns `ratelimit-limit` and `ratelimit-remaining`. ### Example of a successful response[​](#example-of-a-successful-response "Direct link to Example of a successful response") ``` Date: Fri, 05 Nov 2010 12:00:00 GMT Content-Type: application/json; charset=utf-8 ratelimit-limit: 1000 ratelimit-remaining: 486 ``` ### Example of a blocked response[​](#example-of-a-blocked-response "Direct link to Example of a blocked response") When the limit is reached, the server returns `HTTP 429 Too Many Requests`. Wait the number of seconds in the `retry-after` header before the next request. ``` HTTP/1.1 429 Too Many Requests Date: Fri, 05 Nov 2010 12:00:00 GMT Content-Type: application/json; charset=utf-8 ratelimit-limit: 1000 ratelimit-remaining: 0 ratelimit-reset: 3600 ratelimit-name: throttle_authenticated_web retry-after: 3600 {"error": "Limite de requisições POST por hora excedido para esse usuário."} ``` Referência: --- # User-Agent You can include the `User-Agent` header with your application's name and a valid email address, so that we can contact you in case: 1. You are doing something wrong, and we can warn you before blocking; 2. You are doing something really cool, and we can congratulate you 🙂 Example: ``` User-Agent: Meu Nome (meunome@example.com) ``` Example of how to pass this header using cURL: ``` curl -i \ -H "Authorization: Bearer <>" \ -H 'Content-Type: application/json' \ -H 'User-Agent: Meu Nome (meunome@example.com)' \ -X GET 'https://api.billing.sandbox.kobana.com.br/v1/me' ``` This header is **optional** on all requests, but recommended. --- # Webhooks Webhooks are HTTP notifications sent by the Automatic Billing API whenever a relevant event occurs in your Organization — subscription created, invoice paid, NF-e issued, etc. Instead of polling, you register a **public HTTP endpoint** and receive a `POST` with the event payload as soon as it happens. ## Registration[​](#registration "Direct link to Registration") Manage endpoints under **Dashboard → Settings → API → Webhooks**. Each endpoint has: * **URL** — the public HTTPS destination on your server. * **Subscribed events** — the list of `event types` you want to receive. If empty, you receive all of them. * **Status** — `active` or `inactive`. * **Secret** — secret string used to sign each delivery (HMAC-SHA256). Generated automatically; it can be rotated. * **Auth headers** — optionally, extra headers (Basic, Bearer, custom) injected into every request. ## Delivery[​](#delivery "Direct link to Delivery") Each event triggers a `POST` request to the registered URL: ``` POST /seu-endpoint HTTP/1.1 Content-Type: application/json User-Agent: Kobana-Webhooks/1.0 X-Kobana-App: billing X-Kobana-Environment: production X-Kobana-Webhook-Id: 7c1e9d2a-3b4f-4c5d-8e6f-0a1b2c3d4e5f X-Kobana-Event: invoice.paid X-Kobana-Event-Id: 3d1f0c9a-5b2e-4c7d-9e1f-8a6b4c2d0e9f X-Kobana-Delivery-Id: 9b2e4a10-7c3f-4d8e-a1b2-c3d4e5f60718 X-Kobana-Timestamp: 1753272000 X-Kobana-Signature: v1,MEUCIQD3… webhook-id: 9b2e4a10-7c3f-4d8e-a1b2-c3d4e5f60718 webhook-timestamp: 1753272000 webhook-signature: v1,MEUCIQD3… {...payload JSON, em snake_case...} ``` The headers are described in [Headers and signature](#headers-and-signature-kobana-standard), below. ### Success[​](#success "Direct link to Success") Any `2xx` response within **30 seconds** marks the delivery as successful. Anything else (timeout, `4xx`, `5xx`) is treated as a failure. ### Retry[​](#retry "Direct link to Retry") Failures are redelivered with exponential backoff: | Attempt | Delay | | ------- | --------- | | 1 | immediate | | 2 | +1 min | | 3 | +5 min | | 4 | +30 min | | 5 | +2 h | | 6 | +6 h | | 7 | +24 h | After **7 attempts**, the delivery is permanently marked as `failed`. Orphaned events remain available in the dashboard for manual resend. ## Headers and signature (Kobana standard)[​](#headers-and-signature-kobana-standard "Direct link to Headers and signature (Kobana standard)") Every delivery is a `POST` with `Content-Type: application/json` and the headers below — **the same across all Kobana products**, so a single receiver can take webhooks from several products and environments and route them safely: | Header | Value | | ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | `X-Kobana-App` | `billing` — the Kobana product that sent the delivery. | | `X-Kobana-Environment` | `development`, `sandbox` or `production`. Never let a `sandbox` delivery touch production data. | | `X-Kobana-Webhook-Id` | Id of the registered endpoint this delivery belongs to. | | `X-Kobana-Event` | Event slug (e.g. `invoice.paid`). | | `X-Kobana-Event-Id` | Event id. Retries of the same event repeat it — use it to deduplicate. | | `X-Kobana-Delivery-Id` | Unique id of this delivery attempt. Part of the signed content. | | `X-Kobana-Timestamp` | Unix time (seconds) when the delivery was signed. Part of the signed content. | | `X-Kobana-Signature` | `v1,` — one or more tokens separated by a space. | | `webhook-id`, `webhook-timestamp`, `webhook-signature` | The same three values, in the [Standard Webhooks](https://www.standardwebhooks.com) layout — verifiable with an off-the-shelf library. | The legacy headers `X-Signature` (`t=,v1=` over `"{t}.{body}"`), `X-Delivery-Id`, `X-Event-Id`, `X-Event-Type`, `X-Timestamp`, `X-App` and `X-Environment` are still sent, **deprecated**, for existing integrations. Migrate to the `X-Kobana-*` headers: they will be removed in a future version of the contract. ### How the signature is computed[​](#how-the-signature-is-computed "Direct link to How the signature is computed") ``` key = base64_decode(secret without the "whsec_" prefix) signed_content = delivery_id + "." + timestamp + "." + raw_body signature = "v1," + base64(HMAC_SHA256(key, signed_content)) ``` * `raw_body` is the request body **exactly as received**, byte for byte. Do not parse and re-serialize it: key order, whitespace or escaping would change and the signature would no longer match. * Binding the `delivery_id` into the signed content means a captured request cannot be replayed under a different id to bypass your deduplication; the timestamp bounds replays in time. * The secret is `whsec_` + base64 of 32 random bytes and is shown **once**. Older secrets (without the prefix, or with hex after it) keep working: the key is the base64-decoded value after the prefix, or the UTF-8 bytes of the secret when there is no prefix. * During a secret rotation the header carries one token per still-valid secret (`v1,AAA… v1,BBB…`). A delivery is valid if **any** token matches **any** secret you hold. ### Verifying a delivery[​](#verifying-a-delivery "Direct link to Verifying a delivery") 1. Read `webhook-id`, `webhook-timestamp` and `webhook-signature` (or the `X-Kobana-*` equivalents). Reject the request if any is missing. 2. Reject if `|now − timestamp| > 300` seconds: five minutes absorb clock skew while bounding replays. 3. Build the signed content from the raw body and compute the expected HMAC for each secret you trust. 4. Compare with each `v1,` token using a **constant-time** comparison — never `==`, which returns at the first differing byte and leaks the digest through timing. 5. Deduplicate by `X-Kobana-Event-Id` to process each event once, or by `webhook-id` to record every attempt. 6. Return `2xx` quickly and do the heavy work asynchronously. Anything else goes into the retry cycle. ``` const crypto = require('node:crypto'); /** * @param headers request headers, lower-cased names * @param rawBody raw body (string or Buffer), BEFORE any JSON.parse * @param secrets current secret (and the previous one during a rotation) */ function verifyKobanaWebhook(headers, rawBody, secrets) { const id = headers['webhook-id']; const timestamp = headers['webhook-timestamp']; const signature = headers['webhook-signature']; if (!id || !timestamp || !signature) throw new Error('missing signature headers'); if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) throw new Error('timestamp out of tolerance'); const content = `${id}.${timestamp}.${rawBody}`; const received = signature.split(' ').filter((t) => t.startsWith('v1,')).map((t) => Buffer.from(t.slice(3), 'base64')); for (const secret of [].concat(secrets)) { const key = secret.startsWith('whsec_') ? Buffer.from(secret.slice(6), 'base64') : Buffer.from(secret, 'utf8'); const expected = crypto.createHmac('sha256', key).update(content).digest(); if (received.some((r) => r.length === expected.length && crypto.timingSafeEqual(r, expected))) return true; } throw new Error('no matching signature'); } ``` ``` import base64, hashlib, hmac, time def verify_kobana_webhook(headers, raw_body: bytes, secrets) -> bool: msg_id = headers.get("webhook-id") timestamp = headers.get("webhook-timestamp") signature = headers.get("webhook-signature") if not (msg_id and timestamp and signature): raise ValueError("missing signature headers") if abs(time.time() - int(timestamp)) > 300: raise ValueError("timestamp out of tolerance") content = f"{msg_id}.{timestamp}.".encode() + raw_body received = [base64.b64decode(t[3:]) for t in signature.split(" ") if t.startswith("v1,")] for secret in ([secrets] if isinstance(secrets, str) else secrets): key = base64.b64decode(secret[6:]) if secret.startswith("whsec_") else secret.encode() expected = hmac.new(key, content, hashlib.sha256).digest() if any(hmac.compare_digest(r, expected) for r in received): return True raise ValueError("no matching signature") ``` With Express, keep the raw body by mounting `express.raw({ type: 'application/json' })` on the webhook route (not `express.json()`), verify, and only then `JSON.parse`. With Django/Flask use `request.body`/`request.get_data()` — never the already-parsed object. ## Payload structure[​](#payload-structure "Direct link to Payload structure") All events share the same envelope: ``` { "id": "evt_01HXYZABC123", "type": "subscription.status_changed", "created_at": "2026-05-20T12:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { /* recurso completo */ }, "changes": { /* opcional, mudanças desde o estado anterior */ } } ``` | Field | Description | | ------------- | -------------------------------------------------------------------------------------------------------------------- | | `id` | Unique event ID. | | `type` | Event type (e.g. `invoice.paid`). | | `created_at` | ISO 8601 timestamp (UTC) of when the event was generated. | | `environment` | `production` or `sandbox`. | | `version` | Payload schema version (`YYYY-MM-DD` string). | | `data` | The full resource in its current state. | | `changes` | For `*.updated` and `*.status_changed` events, a `field: {from, to}` map. May be absent on creation/deletion events. | ## Payload examples by event[​](#payload-examples-by-event "Direct link to Payload examples by event") See the full examples by browsing the pages below: * [`customer.db.created`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/customer-created.md) * [`company.db.updated`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/company-updated.md) * [`billing_account.suspended`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/billing-account-suspended.md) * [`subscription.status_changed`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/subscription-status-changed.md) * [`invoice.paid`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/invoice-paid.md) * [`payment.succeeded`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/payment-succeeded.md) * [`payment_method.expired`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/payment-method-expired.md) * [`nfe.issued`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/nfe-issued.md) * [`credit.applied`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/credit-applied.md) * [`proposal.accepted`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/proposal-accepted.md) * [`plan.db.updated`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/plan-updated.md) * [`product.archived`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/product-archived.md) * [`coupon.redeemed`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/coupon-redeemed.md) * [`service_item.db.updated`](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks/service-item-updated.md) ## Best practices[​](#best-practices "Direct link to Best practices") * **Idempotency**: use `X-Event-Id` to avoid processing duplicates when a delivery is retried. * **Fast response**: reply `2xx` within 30s. Push heavy work onto an asynchronous queue. * **Versioning**: the `version` field indicates the schema. Treat new fields as additive. * **Mandatory validation**: always validate the signature before trusting the payload. * **HTTPS**: use TLS on your endpoint. HTTP endpoints are rejected in production. * **Event list**: prefer subscribing only to the events you process, not `*`. --- # `billing_account.suspended` Fired when a BillingAccount is suspended for delinquency or by a manual operator action. **Group:** Customers ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZBA999", "type": "billing_account.suspended", "created_at": "2026-05-20T14:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "ba_01HXY123", "organization_id": "org_01HORG", "person_id": "per_01HPER", "external_id": "customer-42", "currency": "BRL", "billing_email": "cobranca@cliente.com.br", "payment_terms_days": 5, "auto_collection": true, "balance": -198.0, "allowed_negative_balance": 0.0, "status": "suspended", "suspended_at": "2026-05-20T14:00:00.000Z", "suspension_reason": "unpaid_invoices", "tax_exempt": false, "settings": {}, "created_at": "2026-01-15T10:00:00.000Z", "updated_at": "2026-05-20T14:00:00.000Z" } } ``` --- # `company.db.updated` Fired on every update to any field of a company (Company). **Group:** Customers ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZCMP111", "type": "company.db.updated", "created_at": "2026-05-20T15:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "cmp_01HZZ987", "public_id": "cmp_kobana", "organization_id": "org_01HORG", "person_id": "per_01HCMPER", "parent_company_id": null, "is_default": true, "status": "active", "metadata": {}, "created_at": "2026-01-01T00:00:00.000Z", "updated_at": "2026-05-20T15:00:00.000Z", "deleted_at": null }, "changes": { "is_default": { "from": false, "to": true } } } ``` --- # `coupon.redeemed` Fired when a coupon is redeemed on a subscription or invoice. **Group:** Catalog ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZCPN666", "type": "coupon.redeemed", "created_at": "2026-05-20T19:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "cpn_01HCPN", "organization_id": "org_01HORG", "code": "WELCOME10", "name": "Boas-vindas 10%", "type": "percentage", "percent_off": 10, "amount_off": null, "currency": "BRL", "duration": "once", "duration_in_months": null, "max_redemptions": 1000, "times_redeemed": 142, "valid_from": "2026-01-01T00:00:00.000Z", "valid_until": "2026-12-31T23:59:59.000Z", "status": "active", "applies_to": "all_plans", "metadata": {}, "created_at": "2026-01-01T00:00:00.000Z", "updated_at": "2026-05-20T19:00:00.000Z" }, "redemption": { "id": "red_01HRED", "billing_account_id": "ba_01HXY123", "subscription_id": "sub_01HABCDEF", "invoice_id": "inv_01HINV", "discount": 9.9, "redeemed_at": "2026-05-20T19:00:00.000Z" } } ``` --- # `credit.applied` Fired when an existing credit is applied to an invoice, reducing the amount due. **Group:** Billing ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZCRD444", "type": "credit.applied", "created_at": "2026-05-20T17:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "cre_01HCRE", "organization_id": "org_01HORG", "billing_account_id": "ba_01HXY123", "invoice_id": "inv_01HINV", "type": "manual", "status": "applied", "amount": 50.0, "balance": 0.0, "currency": "BRL", "reason": "goodwill", "description": "Crédito concedido por atraso na entrega", "expires_at": "2026-12-31T23:59:59.000Z", "applied_at": "2026-05-20T17:00:00.000Z", "metadata": {}, "created_at": "2026-05-10T10:00:00.000Z", "updated_at": "2026-05-20T17:00:00.000Z" } } ``` --- # `customer.db.created` Fired when a new customer (individual or legal entity) is registered in the Organization. **Group:** Customers ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZCUS222", "type": "customer.db.created", "created_at": "2026-05-20T15:30:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "per_01HPER", "organization_id": "org_01HORG", "type": "individual", "name": "João Silva", "email": "joao@example.com", "document_type": "cpf", "document_number": "12345678900", "phone": "+5511999999999", "address": { "street": "Av. Paulista", "number": "1000", "city": "São Paulo", "state": "SP", "zip_code": "01310-000", "country": "BR" }, "metadata": {}, "created_at": "2026-05-20T15:30:00.000Z", "updated_at": "2026-05-20T15:30:00.000Z" } } ``` --- # `invoice.paid` Fired when an invoice has its payment confirmed and its status changes to `paid`. **Group:** Billing ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZINV456", "type": "invoice.paid", "created_at": "2026-05-20T12:05:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "inv_01HINV", "public_id": "inv_2a9c1f4e", "organization_id": "org_01HORG", "number": "INV-2026-0042", "billing_account_id": "ba_01HXY123", "billing_account_public_id": "8f2b1c04-9d3e-4a71-bc55-1f0a2d6e7b48", "company_id": "cmp_01HZZ987", "subscription_id": "sub_01HABCDEF", "status": "paid", "collection_method": "charge_automatically", "currency": "BRL", "subtotal": 99.0, "discount": 0.0, "tax": 0.0, "total": 99.0, "amount_due": 99.0, "amount_paid": 99.0, "amount_remaining": 0.0, "period_start": "2026-05-01T00:00:00.000Z", "period_end": "2026-06-01T00:00:00.000Z", "due_date": "2026-05-05T00:00:00.000Z", "paid_at": "2026-05-20T12:05:00.000Z", "finalized_at": "2026-05-01T00:00:00.000Z", "billing_reason": "subscription_cycle", "hosted_invoice_url": "https://billing.kobana.com.br/invoices/inv_2a9c1f4e", "invoice_pdf_url": "https://billing.kobana.com.br/invoices/inv_2a9c1f4e.pdf", "payment_attempts": 1, "metadata": {}, "created_at": "2026-05-01T00:00:00.000Z", "updated_at": "2026-05-20T12:05:00.000Z", "line_items": [ { "id": "ili_01HLI001", "invoice_id": "inv_01HINV", "product_id": "prod_01HPROD", "product_slug": "plano-mensal", "type": "subscription", "description": "Plano Mensal", "quantity": 1, "unit_amount": 99.0, "amount": 99.0, "period_start": "2026-05-01T00:00:00.000Z", "period_end": "2026-06-01T00:00:00.000Z", "metadata": {} } ] } } ``` ## Identifying the account and the product[​](#identifying-the-account-and-the-product "Direct link to Identifying the account and the product") The payload carries **internal and public identifiers side by side**: | Field | Use when | | --------------------------- | ---------------------------------------------------------------------------------------------------------- | | `billing_account_id` | you store Kobana's internal id | | `billing_account_public_id` | you identify the account by its **public uid** — the same one the API accepts to resolve a billing account | | `line_items[].product_id` | internal product id | | `line_items[].product_slug` | the product **slug**, stable and readable — the recommended way to recognize *what* was purchased | An external subscriber normally routes by `billing_account_public_id` and recognizes the product by `product_slug`: those are the two values that exist outside this codebase. `product_slug` comes as `null` when the product relation was not loaded at the time of issue — `null` means *"I don't know"*, never *"another product"*. --- # `nfe.issued` Fired when the NF-e (Brazilian electronic invoice) is successfully issued by the integrated tax provider. **Group:** Billing ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZNFE333", "type": "nfe.issued", "created_at": "2026-05-20T16:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "nfe_01HNFE", "organization_id": "org_01HORG", "company_id": "cmp_01HZZ987", "invoice_id": "inv_01HINV", "billing_account_id": "ba_01HXY123", "status": "issued", "provider": "nfeio", "nfe_type": "nfse", "series": "A", "number": "2026000042", "rps_number": "42", "rps_series": "RPS", "issue_date": "2026-05-20T16:00:00.000Z", "verification_code": "ABC123XYZ", "external_id": "nfeio_01HEXT", "pdf_url": "https://billing.kobana.com.br/nfes/nfe_01HNFE.pdf", "xml_url": "https://billing.kobana.com.br/nfes/nfe_01HNFE.xml", "amount": 99.0, "tax": 4.95, "service_code": "01.01", "cnae_code": "6201500", "description": "Plataforma de cobrança recorrente", "metadata": {}, "created_at": "2026-05-20T15:59:30.000Z", "updated_at": "2026-05-20T16:00:00.000Z" } } ``` --- # `payment_method.expired` Fired when a payment method expires (expired card, canceled mandate, etc.). **Group:** Billing ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZPM321", "type": "payment_method.expired", "created_at": "2026-05-20T12:10:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "pm_01HPM", "organization_id": "org_01HORG", "billing_account_id": "ba_01HXY123", "credit_card_id": "cc_01HCC", "type": "card", "status": "expired", "is_default": true, "is_backup": false, "bank_account": null, "billing_details": { "name": "João Silva", "email": "joao@example.com" }, "created_at": "2026-01-15T10:00:00.000Z", "updated_at": "2026-05-20T12:10:00.000Z" } } ``` --- # `payment.succeeded` Fired when a payment is confirmed by the gateway with status `succeeded`. **Group:** Billing ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZPAY789", "type": "payment.succeeded", "created_at": "2026-05-20T12:05:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "pay_01HPAY", "public_id": "pay_4b8e2c7a", "organization_id": "org_01HORG", "invoice_id": "inv_01HINV", "company_id": "cmp_01HZZ987", "payment_method_id": "pm_01HPM", "gateway_id": "gw_01HGW", "payment_method_type": "card", "amount": 99.0, "paid_amount": 99.0, "currency": "BRL", "status": "succeeded", "payment_gateway": "kobana", "gateway_payment_id": "kbn_charge_abc123", "failure_code": null, "failure_message": null, "paid_at": "2026-05-20T12:05:00.000Z", "metadata": {}, "created_at": "2026-05-20T12:04:55.000Z", "updated_at": "2026-05-20T12:05:00.000Z" } } ``` --- # `plan.db.updated` Fired on every update to any field of a Plan. **Group:** Catalog ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZPLAN555", "type": "plan.db.updated", "created_at": "2026-05-20T13:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "plan_01HPRO", "public_id": "plan_pro_monthly", "organization_id": "org_01HORG", "name": "Pro Mensal", "slug": "pro-monthly", "description": "Plano Pro com cobrança mensal", "status": "active", "plan_type": "recurring", "visibility": "public", "trial_period_days": 14, "default_billing_cycle": "monthly", "available_billing_cycles": [ "monthly", "annual" ], "features": [ "unlimited_invoices", "priority_support" ], "limits": { "users": 10 }, "metadata": {}, "created_at": "2026-01-01T00:00:00.000Z", "updated_at": "2026-05-20T13:00:00.000Z" }, "changes": { "description": { "from": "Plano Pro", "to": "Plano Pro com cobrança mensal" } } } ``` --- # `product.archived` Fired when a product is archived and removed from the active catalog. **Group:** Catalog ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZPROD777", "type": "product.archived", "created_at": "2026-05-20T13:30:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "prod_01HPROD", "public_id": "prod_setup_fee", "organization_id": "org_01HORG", "company_id": "cmp_01HZZ987", "name": "Taxa de Setup", "slug": "setup-fee", "description": "Taxa única de configuração", "status": "archived", "visibility": "private", "product_type": "service", "unit_label": "unit", "increment": 1, "is_required": false, "metadata": {}, "created_at": "2026-01-10T00:00:00.000Z", "updated_at": "2026-05-20T13:30:00.000Z" } } ``` --- # `proposal.accepted` Fired when the customer accepts a commercial proposal that was sent. **Group:** Commercial ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZPRO555", "type": "proposal.accepted", "created_at": "2026-05-20T18:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "prp_01HPROP", "public_id": "prp_a1b2c3d4", "organization_id": "org_01HORG", "company_id": "cmp_01HZZ987", "code": "P-ABCD1234", "title": "Proposta Pro Mensal", "description": null, "billing_account_id": "ba_01HXY123", "prospect_id": null, "coupon_id": null, "template_id": "tpl_01HTPL", "document_google_id": null, "document_url": "https://docs.google.com/document/d/abc123", "pdf_url": "https://billing.kobana.com.br/proposals/prp_a1b2c3d4.pdf", "generated_at": "2026-05-18T10:00:00.000Z", "pdf_outdated_at": null, "expires_at": "2026-06-20T23:59:59.000Z", "status": "accepted", "rejection_reason": null, "metadata": {}, "notes": null, "created_at": "2026-05-18T09:55:00.000Z", "updated_at": "2026-05-20T18:00:00.000Z", "sent_at": "2026-05-18T10:00:00.000Z", "viewed_at": "2026-05-19T14:30:00.000Z", "accepted_at": "2026-05-20T18:00:00.000Z", "rejected_at": null, "items": [ { "id": "pitem_01HITEM", "proposal_id": "prp_01HPROP", "product_id": "prod_01HPROD", "price_id": "price_01HPRC", "quantity": 1, "unit_amount": 99.0, "metadata": {}, "created_at": "2026-05-18T09:55:00.000Z", "updated_at": "2026-05-18T09:55:00.000Z" } ], "subscription_id": "sub_01HABCDEF", "invoice_id": "inv_01HINV" }, "changes": { "status": { "from": "viewed", "to": "accepted" } } } ``` --- # `service_item.db.updated` Fired on every update to service items (CNAE codes, ISS, tax description). **Group:** Catalog ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZSVC777", "type": "service_item.db.updated", "created_at": "2026-05-20T20:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "svc_01HSVC", "organization_id": "org_01HORG", "company_id": "cmp_01HZZ987", "code": "01.01", "description": "Análise e desenvolvimento de sistemas", "cnae": "6201500", "municipal_service_code": "0101", "federal_service_code": "01.01", "tax_rate": 5, "iss_withholding": false, "is_default": true, "status": "active", "metadata": {}, "created_at": "2026-01-15T10:00:00.000Z", "updated_at": "2026-05-20T20:00:00.000Z" }, "changes": { "tax_rate": { "from": 3, "to": 5 } } } ``` --- # `subscription.status_changed` Fired whenever a subscription's `status` changes (`active`, `trialing`, `past_due`, `paused`, `canceled`). **Group:** Billing ## Payload[​](#payload "Direct link to Payload") ``` { "id": "evt_01HXYZABC123", "type": "subscription.status_changed", "created_at": "2026-05-20T12:00:00.000Z", "environment": "production", "version": "2026-03-01", "data": { "id": "sub_01HABCDEF", "public_id": "sub_8f3d2a1b", "organization_id": "org_01HORG", "billing_account_id": "ba_01HXY123", "company_id": "cmp_01HZZ987", "plan_id": "plan_01HPRO", "status": "active", "billing_cycle": "monthly", "billing_cycle_anchor": "2026-05-01T00:00:00.000Z", "current_period_start": "2026-05-01T00:00:00.000Z", "current_period_end": "2026-06-01T00:00:00.000Z", "trial_start": null, "trial_end": null, "activated_at": "2026-04-01T12:00:00.000Z", "cancel_at_period_end": false, "canceled_at": null, "cancellation_reason": null, "recurring_amount": 99.0, "collection_method": "charge_automatically", "proration_behavior": "create_prorations", "metadata": {}, "created_at": "2026-04-01T12:00:00.000Z", "updated_at": "2026-05-20T12:00:00.000Z", "items": [ { "id": "sitem_01HSITEM", "subscription_id": "sub_01HABCDEF", "product_id": "prod_01HPROD", "price_id": "price_01HPRC", "quantity": 1, "unit_amount": 99.0, "metadata": {}, "created_at": "2026-04-01T12:00:00.000Z", "updated_at": "2026-04-01T12:00:00.000Z" } ] }, "changes": { "status": { "from": "past_due", "to": "active" } } } ``` --- ## [📄️Subscription Lifecycle](https://docs.billing.kobana.com.br/en/en/assinaturas/ciclo-de-vida/.md) [States](https://docs.billing.kobana.com.br/en/en/assinaturas/ciclo-de-vida/.md) --- ## [📄️Subscription Lifecycle](https://docs.billing.kobana.com.br/en/en/assinaturas/ciclo-de-vida/.md) [States](https://docs.billing.kobana.com.br/en/en/assinaturas/ciclo-de-vida/.md) --- # Subscription Lifecycle ## States[​](#states "Direct link to States") ``` draft → confirmed → trialing → active ↔ past_due → canceled ↕ paused ``` | State | Description | | ------------- | ----------------------------------------------- | | **draft** | Draft. Can be freely edited before confirmation | | **confirmed** | Confirmed, awaiting activation | | **trialing** | In a free trial period | | **active** | Active, generating recurring charges | | **past\_due** | Has overdue payments | | **paused** | Temporarily paused (no charges) | | **canceled** | Canceled (terminal state) | ## Creating a Subscription[​](#creating-a-subscription "Direct link to Creating a Subscription") To create a subscription, provide: | Field | Required | Description | | --------------------- | -------- | ------------------------------------------------------------ | | **Billing account** | Yes | The customer account to be charged | | **Plan** | No | Pre-configured plan (or individual items) | | **Billing cycle** | Yes | `monthly`, `quarterly`, `semiannual`, or `annual` | | **Collection method** | Yes | `charge_automatically`, `manual_charge`, or `manual_invoice` | | **Trial period** | No | 0 to 90 days of free trial | | **Discount code** | No | Discount to be applied | | **Items** | No | Products, prices, and quantities (if not using a plan) | | **Company** | No | Issuing company (for multi-company setups) | ### Creation Flow[​](#creation-flow "Direct link to Creation Flow") 1. The subscription is created with `draft` status 2. Items are created from the provided items or from the plan items 3. The discount code usage is incremented (if provided) 4. A `subscription.db.created` event is emitted ## Confirmation and Activation[​](#confirmation-and-activation "Direct link to Confirmation and Activation") ### Confirm (`draft` → `confirmed`)[​](#confirm-draft--confirmed "Direct link to confirm-draft--confirmed") Confirms the subscription, optionally creating the first invoice. ### Activate (`draft`/`confirmed` → `trialing`/`active`)[​](#activate-draftconfirmed--trialingactive "Direct link to activate-draftconfirmed--trialingactive") * If it has a trial period: status changes to `trialing`, with `trial_start` and `trial_end` set * If there is no trial: status changes directly to `active` * Sets the billing period dates (`current_period_start`, `current_period_end`) ### Activation Preview[​](#activation-preview "Direct link to Activation Preview") Before activating, you can preview: * Start date, whether there will be a trial, trial duration * Billing period dates * First invoice date * Setup and recurring totals ## Renewal[​](#renewal "Direct link to Renewal") Renewal is automatic via a daily worker (00:00 UTC): 1. Finds active subscriptions with `currentPeriodEnd ≤ now` 2. If `cancelAtPeriodEnd = true`: cancels the subscription 3. Otherwise: advances to the next billing period 4. Uses optimistic locking to prevent duplicate renewals ### Period Calculation[​](#period-calculation "Direct link to Period Calculation") | Cycle | Duration | | ------------ | --------- | | `monthly` | +1 month | | `quarterly` | +3 months | | `semiannual` | +6 months | | `annual` | +1 year | ## Cancellation[​](#cancellation "Direct link to Cancellation") ### Cancel at End of Period (`cancelAtPeriodEnd: true`)[​](#cancel-at-end-of-period-cancelatperiodend-true "Direct link to cancel-at-end-of-period-cancelatperiodend-true") * Sets the `cancel_at_period_end` flag * The subscription remains active until the end of the current period * On renewal, the status changes to `canceled` * Can be reversed before the cancellation date ### Cancel Immediately (`cancelAtPeriodEnd: false`)[​](#cancel-immediately-cancelatperiodend-false "Direct link to cancel-immediately-cancelatperiodend-false") * Status changes to `canceled` immediately * The cancellation date is recorded * The cancellation reason is stored ## Revert to Confirmed[​](#revert-to-confirmed "Direct link to Revert to Confirmed") Active subscriptions can be reverted to `confirmed` to allow editing before reactivating. Useful for correcting errors before the next renewal. ## Deletion[​](#deletion "Direct link to Deletion") Only subscriptions in `draft`, `confirmed`, or `canceled` status can be deleted, and only if there are no invoices with payments. ## MRR Calculation[​](#mrr-calculation "Direct link to MRR Calculation") MRR (Monthly Recurring Revenue) is calculated by normalizing the total value to a monthly basis: | Cycle | Formula | | ------------ | -------------- | | `monthly` | Total of items | | `quarterly` | Total / 3 | | `semiannual` | Total / 6 | | `annual` | Total / 12 | ## Emitted Events[​](#emitted-events "Direct link to Emitted Events") | Event | When | | ----------------------------------- | ---------------------------------------- | | `subscription.db.created` | Subscription created | | `subscription.confirmed` | Confirmed | | `subscription.activated` | Activated | | `subscription.renewed` | Renewed | | `subscription.paused` | Paused | | `subscription.resumed` | Resumed | | `subscription.canceled` | Canceled | | `subscription.pending_cancellation` | Marked for cancellation at end of period | | `subscription.plan_changed` | Plan changed | | `subscription_status_changed` | Any status change | --- # Plan Change (Upgrade/Downgrade) The system allows customers to change their subscription plan with automatic proration calculation. ## Change Types[​](#change-types "Direct link to Change Types") | Type | Description | | ------------- | ----------------------------------------------- | | **upgrade** | New plan is more expensive than the current one | | **downgrade** | New plan is cheaper than the current one | | **lateral** | Same value (feature change) | ## Change Timing[​](#change-timing "Direct link to Change Timing") | Timing | Description | | ------------------- | ------------------------------------------------------------ | | **immediate** | Applies immediately, charges/credits the prorated difference | | **end\_of\_period** | Schedules the change for the start of the next period | ## Proration[​](#proration "Direct link to Proration") ### Proration Methods[​](#proration-methods "Direct link to Proration Methods") | Method | Description | | ------------------- | -------------------------------------------------------------------- | | `full_proration` | Credits the old plan and charges the new plan for the remaining time | | `partial_proration` | Charges only the difference (upgrade only) | | `no_proration` | No mid-cycle value adjustment | ### Calculation Formula[​](#calculation-formula "Direct link to Calculation Formula") ``` remaining_days = max(0, ceil((period_end - now) / 86400000)) total_period_days = ceil((period_end - period_start) / 86400000)) Full proration: credit = (old_price x remaining_days) / total_period_days charge = (new_price x remaining_days) / total_period_days Partial proration (upgrade only): difference = new_price - old_price charge = (difference x remaining_days) / total_period_days Net charge = charge - credit ``` ## Default Configuration[​](#default-configuration "Direct link to Default Configuration") The plan change configuration defines the default behavior: | Setting | Default | | ------------------------ | ---------------- | | Allow upgrade | Yes | | Allow downgrade | Yes | | Proration on upgrade | `full_proration` | | Proration on downgrade | `no_proration` | | Upgrade timing | `immediate` | | Downgrade timing | `end_of_period` | | Refund on downgrade | No | | Credit on downgrade | Yes | | Apply discount on change | Yes | ## Plan Change Rules[​](#plan-change-rules "Direct link to Plan Change Rules") You can create specific rules to control transitions between plans: | Field | Description | | -------------------- | --------------------------------- | | **Source plan** | Current plan (null = any) | | **Target plan** | New plan (null = any) | | **Change type** | upgrade, downgrade, or lateral | | **Allowed** | Whether the transition is allowed | | **Timing** | Overrides the default timing | | **Proration method** | Overrides the default method | | **Discount (%)** | Percentage discount on the charge | | **Bonus days** | Trial extension | | **Message** | Reason if not allowed | | **Priority** | Higher priority takes precedence | ### Rule Priority Order[​](#rule-priority-order "Direct link to Rule Priority Order") 1. Rule with source plan **AND** target plan (most specific) 2. Rule with only source plan 3. Rule with only target plan 4. Global rule (both null) ## Change Preview[​](#change-preview "Direct link to Change Preview") Before executing, you can preview: * Whether the change is allowed * Type (upgrade/downgrade/lateral) * Prorated credit and charge amounts * Final net charge * Effective date * Remaining days in the period ## Executing the Change[​](#executing-the-change "Direct link to Executing the Change") ### Immediate Change[​](#immediate-change "Direct link to Immediate Change") 1. Validation and preview are calculated 2. A PlanChange record is created (status: `pending`) 3. Credit generated if `prorationCreditSubcents > 0` 4. Invoice generated if `netChargeSubcents > 0` 5. Subscription updated with the new plan 6. PlanChange marked as `completed` ### Scheduled Change[​](#scheduled-change "Direct link to Scheduled Change") 1. A PlanChange record is created (status: `scheduled`) 2. On the effective date, the worker processes the change 3. Subscription updated with the new plan 4. PlanChange marked as `completed` > **Limitation**: The system keeps only **one scheduled change** at a time. A new scheduled change cancels the previous one. ## Cancel Scheduled Change[​](#cancel-scheduled-change "Direct link to Cancel Scheduled Change") Scheduled changes can be canceled before the effective date. The status changes to `canceled` and the reason is recorded. ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/plan-changes` screen shows the organization's plan change history, with filters by status, type (upgrade/downgrade/lateral), source plan and target plan. The settings tab centralizes the default proration behavior and the rules per plan pair. ![Plan change history and settings](/en/assets/images/mudancas-de-plano-804d952d338a99fee9eef325b55d301e.png) --- # Subscription Item Changes Besides plan changes (upgrade/downgrade), Automatic Billing supports **changes to the individual items** of a subscription — changing quantities, adding add-ons, swapping a one-off product or a metered item without having to change the main plan. The `/dashboard/subscription-changes` screen groups the history of these changes and the default proration settings. ## History tab[​](#history-tab "Direct link to History tab") Shows every item change recorded in the organization. Each row corresponds to a `SubscriptionItemChange` record and displays: * **ID of the affected subscription** * **Status**: `pending`, `scheduled`, `completed`, `canceled` or `failed` * **Timing**: `immediate` (applies now) or `end_of_period` (applies on the next cycle) * **Changes**: items added, removed or changed (with quantity and price) * **Credit generated** (`proration_credit`) and **charge generated** (`proration_charge`) * **Effective date** and **creation date** `completed` changes have already been processed; `scheduled` ones wait for the renewal worker to run them at the cycle turnover. ## Settings tab[​](#settings-tab "Direct link to Settings tab") Defines the default behavior when an item is added, removed or has its quantity changed: * **Allow quantity increase** and **allow reduction** — controls who can change what. * **Default timing** — when the change is applied (immediately or at the end of the period). * **Proration method** — `full_proration`, `partial_proration` or `no_proration`. * **Credit on reduction** — whether reducing the quantity creates a balance on the customer's account. * **Refund on reduction** — whether it refunds through the gateway instead of creating a credit. The settings are resolved per organization and can be overridden by specific rules at the time of the change via the API. ## Item change vs. plan change[​](#item-change-vs-plan-change "Direct link to Item change vs. plan change") | Scenario | Screen | | ----------------------------------------------------- | ---------------------------------------------------------------------------------------- | | Switch from **Starter** to **Growth** | [Plan Change](https://docs.billing.kobana.com.br/en/en/assinaturas/mudanca-de-plano/.md) | | Add 10 extra users to the current plan | Item Changes | | Swap the `Email Premium` add-on for `SMS Premium` | Item Changes | | Reduce the number of licenses at the end of the cycle | Item Changes | Both flows generate proration when applicable, and both trigger events and webhooks (`subscription.updated`, `subscription_item.changed`). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![History and settings of subscription item changes](/en/assets/images/mudancas-de-itens-66db1ae7c7fbd472ad110257030edf90.png) --- # Pause Subscription The pause subscription feature allows you to temporarily suspend billing for a customer without canceling the subscription. It is a strategic retention tool. ## Benefits[​](#benefits "Direct link to Benefits") * **Reduce churn**: Prevents cancellations by offering a temporary alternative * **Preserve revenue**: The service remains active for the already-paid period * **Flexibility**: Accommodates situations such as vacations, budget constraints, or seasonal usage * **Customer experience**: Demonstrates commitment to the subscriber's needs ## Prerequisites[​](#prerequisites "Direct link to Prerequisites") To pause a subscription, it must: * Have a status of `active` or `past_due` * Cannot be a future subscription, in trial, or canceled ## Pause Behavior[​](#pause-behavior "Direct link to Pause Behavior") When pausing a subscription, you configure: | Field | Description | | ------------- | -------------------------------------- | | **Behavior** | How to handle pending invoices | | **Resume on** | Optional date for automatic resumption | ### Behavior for Pending Invoices[​](#behavior-for-pending-invoices "Direct link to Behavior for Pending Invoices") | Behavior | Description | | -------------------- | --------------------------------------- | | `mark_uncollectible` | Marks pending invoices as uncollectible | | `keep_as_draft` | Keeps future invoices as drafts | | `void` | Voids pending invoices | ## Effects of Pausing[​](#effects-of-pausing "Direct link to Effects of Pausing") * Status changes to `paused` * **No invoices are generated** during the pause * **No charges** are made * The current period is not altered * **Coupons continue to expire** normally (they do not pause along with the subscription) * **MRR**: Zero contribution during the pause * **Analytics**: Paused subscriptions count as "active" (not as churn) ## Resuming[​](#resuming "Direct link to Resuming") ### Manual Resumption[​](#manual-resumption "Direct link to Manual Resumption") 1. Navigate to the subscription in the dashboard 2. Click "Resume" 3. The status returns to `active` 4. The pause field is cleared 5. A new billing cycle begins ### Automatic Resumption[​](#automatic-resumption "Direct link to Automatic Resumption") If a resumption date (`pause_collection.resumes_at`) was set, the subscription is automatically resumed on that date. ## Events[​](#events "Direct link to Events") | Event | Description | | ---------------------- | -------------------- | | `subscription.paused` | Subscription paused | | `subscription.resumed` | Subscription resumed | ## Considerations[​](#considerations "Direct link to Considerations") * Each pause must be completed before starting another * Changes to the subscription during the pause cancel the scheduled pause * Closing the customer's account immediately terminates all paused subscriptions * Paused subscriptions do not appear in the "pending billing" list --- # Billing Terms Billing terms define how and when the customer is charged for the subscription. ## Billing Cycles[​](#billing-cycles "Direct link to Billing Cycles") | Cycle | Frequency | Duration | | ------------ | ----------- | --------- | | `monthly` | Monthly | 1 month | | `quarterly` | Quarterly | 3 months | | `semiannual` | Semi-annual | 6 months | | `annual` | Annual | 12 months | ### Billing Anchor[​](#billing-anchor "Direct link to Billing Anchor") Billing periods are calculated entirely from `current_period_start` and `current_period_end`, which advance on every renewal. The cycle billing day lives in `cycle_billing_date`, set when the subscription is activated. ### Current Period[​](#current-period "Direct link to Current Period") * `current_period_start`: Start of the current billing period * `current_period_end`: End of the current billing period ## Collection Methods[​](#collection-methods "Direct link to Collection Methods") | Method | Invoice Generation | Charge | | ---------------------- | ------------------ | --------- | | `charge_automatically` | Automatic | Automatic | | `manual_charge` | Automatic | Manual | | `manual_invoice` | Manual | Manual | ### Automatic Charge (`charge_automatically`)[​](#automatic-charge-charge_automatically "Direct link to automatic-charge-charge_automatically") * The invoice is generated automatically by the worker * Upon finalization, the system attempts to charge automatically using the customer's default payment method * For card: immediate charge * For boleto (bank slip) / PIX (instant payment): generates the charge and awaits confirmation via webhook * On failure: schedules retry attempts (dunning) ### Manual Charge with Automatic Invoice (`manual_charge`)[​](#manual-charge-with-automatic-invoice-manual_charge "Direct link to manual-charge-with-automatic-invoice-manual_charge") * The invoice is created automatically by the worker * The customer receives the invoice by email * Payment is made manually (boleto, PIX) or the operator triggers the charge ### Manual Invoice and Manual Charge (`manual_invoice`)[​](#manual-invoice-and-manual-charge-manual_invoice "Direct link to manual-invoice-and-manual-charge-manual_invoice") * No invoices are generated automatically * The operator creates invoices manually as needed * Useful for one-time charges or irregular billing ## Proration Behavior[​](#proration-behavior "Direct link to Proration Behavior") Configures how mid-cycle plan changes are handled: | Behavior | Description | | ------------------- | -------------------------------------------------- | | `create_prorations` | Creates proportional credits and charges (default) | | `none` | No proportional adjustment | | `always_invoice` | Always generates an invoice for the difference | ## Trial Period[​](#trial-period "Direct link to Trial Period") * Configurable from 0 to 90 days * During the trial, the subscription has `trialing` status * At the end of the trial, the subscription changes to `active` and the billing period begins ## Subscription Permissions[​](#subscription-permissions "Direct link to Subscription Permissions") | Setting | Description | | -------------- | ------------------------------------------------ | | `allow_pause` | Whether the customer can pause the subscription | | `allow_cancel` | Whether the customer can cancel the subscription | These settings can be defined per subscription and control the options available in the customer portal. --- # Authentication :::caution Products do not share credentials `KOBANA_TOKEN` holds **one product's credential at a time**. A Automatic Billing token does not authenticate against any other Kobana product, and vice versa. ::: ## The token[​](#the-token "Direct link to The token") Automatic Billing authenticates with a **JWT signed in RS256** by Kobana's authorization server, sent as `Authorization: Bearer `. See [API Authentication](https://docs.billing.kobana.com.br/en/en/api/overview/authentication.md) for how that token is issued and which scopes it carries — `kobana auth login`, which belongs to the Banking Gateway, does **not** produce it. Put the JWT in `KOBANA_TOKEN` before calling the product: ``` export KOBANA_TOKEN=$JWT_BILLING kobana billing subscriptions list --fields "id,status,plan_id" ``` Since the variable is the same for every product, export it per command (or use a per-project `.env`) if you switch products in the same session: ``` KOBANA_TOKEN=$JWT_BILLING kobana billing subscriptions list --fields "id,status,plan_id" ``` ## Scopes[​](#scopes "Direct link to Scopes") Each command requires of the token the same access level as the endpoint behind it — one level per command, and none stands in for another: | Command | Level | | ------------------------------------------------------------------------------ | -------- | | `list`, `get` and the other reads | `read` | | `create`, `update` and the other actions (`archive`, `unarchive`, `cancel`, …) | `write` | | `delete` and `bulk delete` | `delete` | | `nfes import-barueri create` | `import` | `all` stands for every level. A token with only `write` gets `403 insufficient_scope` on `delete`: also ask for the `delete` level in your Kobana account if your automation deletes. See [API Authentication](https://docs.billing.kobana.com.br/en/en/api/overview/authentication.md) for the six levels and the endpoints whose method changed — bulk deletions, for instance, became `bulk delete` (`DELETE /v1/{resource}/bulk`). ## Resolution priority[​](#resolution-priority "Direct link to Resolution priority") | Priority | Method | Configuration | | -------- | ----------------- | ------------------------------------------ | | 1 | Direct token | `KOBANA_TOKEN` | | 2 | Credentials file | `KOBANA_CREDENTIALS_FILE` | | 3 | Saved credentials | `kobana auth login` (Banking Gateway only) | ## Environments[​](#environments "Direct link to Environments") The CLI operates in three environments, and each product has its own hosts. **Production is the default.** | Environment | API | `--env` | | ----------- | ----------------------------------- | ---------------------- | | Production | `api.billing.kobana.com.br` | `production` (default) | | Sandbox | `api.billing.sandbox.kobana.com.br` | `sandbox` | Automatic Billing has no development host of its own: with `--env development` the CLI falls back to production. ``` # Production (default — no flag needed) kobana billing subscriptions list # Sandbox kobana billing subscriptions list --env sandbox # Via environment variable export KOBANA_ENVIRONMENT=sandbox kobana billing subscriptions list ``` Tokens are **different across environments** — a sandbox token does not work in production and vice versa. ## Next steps[​](#next-steps "Direct link to Next steps") * [Usage](https://docs.billing.kobana.com.br/en/en/cli/usage/overview.md) — syntax, resources, examples. * [Environment variables](https://docs.billing.kobana.com.br/en/en/cli/overview/environment-variables.md) — the full reference, including config and logging. --- # Environment variables Every variable can also be set in a `.env` file (loaded via `dotenvy`). ## Authentication[​](#authentication "Direct link to Authentication") | Variable | Description | | -------------------------- | ------------------------------------------------------------------------ | | `KOBANA_TOKEN` | Bearer token for the product you are calling. Not shared across products | | `KOBANA_CREDENTIALS_FILE` | Path to an OAuth credentials JSON file | | `KOBANA_CLIENT_ID` | OAuth client ID (Banking Gateway) | | `KOBANA_CLIENT_SECRET` | OAuth client secret (Banking Gateway) | | `KOBANA_INBOX_CLIENT_CERT` | Path to the PEM (certificate + key) used for the `inbox` product's mTLS | ## Configuration[​](#configuration "Direct link to Configuration") | Variable | Description | | -------------------- | ----------------------------------------------------------- | | `KOBANA_CONFIG_DIR` | Override the config directory (default: `~/.config/kobana`) | | `KOBANA_ENVIRONMENT` | `production` (default), `sandbox` or `development` | ## Logging[​](#logging "Direct link to Logging") | Variable | Description | | ----------------- | ------------------------------------------------------------------ | | `KOBANA_LOG` | Log level filter for stderr (e.g. `kobana=debug`). Off by default. | | `KOBANA_LOG_FILE` | Directory for JSON log files with daily rotation. Off by default. | ## Next steps[​](#next-steps "Direct link to Next steps") * [Authentication](https://docs.billing.kobana.com.br/en/en/cli/overview/authentication.md) — resolution priority and per-product credentials. * [Exit codes](https://docs.billing.kobana.com.br/en/en/cli/overview/exit-codes.md) — process exit codes for scripting. --- # Exit codes Every `kobana` invocation exits with one of these codes, so a script can branch on failure class without parsing the JSON error body. | Code | Meaning | | ---- | -------------------- | | `0` | Success | | `1` | API error (4xx/5xx) | | `2` | Authentication error | | `3` | Validation error | | `4` | Schema error | | `5` | Internal error | ## Next steps[​](#next-steps "Direct link to Next steps") * [Usage](https://docs.billing.kobana.com.br/en/en/cli/usage/overview.md) — syntax, resources, examples. * [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) — `--dry-run`, `--output-format` and the rest. --- # Installation ### Homebrew (macOS and Linux)[​](#homebrew-macos-and-linux "Direct link to Homebrew (macOS and Linux)") ``` brew tap universokobana/tap brew install kobana ``` To update: ``` brew update && brew upgrade kobana ``` ### Prebuilt binaries[​](#prebuilt-binaries "Direct link to Prebuilt binaries") Download the binary for your platform from the [Releases page](https://github.com/universokobana/kobana-cli/releases/latest) and put it on your `PATH`. | Platform | File | | ------------------- | -------------------------- | | Linux x86\_64 | `kobana-linux-amd64` | | Linux ARM64 | `kobana-linux-arm64` | | macOS Intel | `kobana-darwin-amd64` | | macOS Apple Silicon | `kobana-darwin-arm64` | | Windows x86\_64 | `kobana-windows-amd64.exe` | ### Nix[​](#nix "Direct link to Nix") ``` # Run straight from GitHub nix run github:universokobana/kobana-cli # Install into the profile nix profile install github:universokobana/kobana-cli ``` ### Build from source[​](#build-from-source "Direct link to Build from source") ``` git clone https://github.com/universokobana/kobana-cli.git cd kobana-cli cargo install --path crates/kobana-cli ``` Requires [Rust](https://rustup.rs/) 1.70+. ## Shell completions[​](#shell-completions "Direct link to Shell completions") ``` # Bash kobana completions bash > /etc/bash_completion.d/kobana # Zsh kobana completions zsh > ~/.zfunc/_kobana # Fish kobana completions fish > ~/.config/fish/completions/kobana.fish # PowerShell kobana completions powershell > kobana.ps1 ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Authentication](https://docs.billing.kobana.com.br/en/en/cli/overview/authentication.md) — tokens and environments. * [Usage](https://docs.billing.kobana.com.br/en/en/cli/usage/overview.md) — syntax, resources, examples. --- # Introduction **`kobana`** is a single command-line tool for every Kobana product's API — Automatic Billing included. It is built and maintained in its own repository ([`kobana-cli`](https://github.com/universokobana/kobana-cli)), not by this product, and it does not hardcode endpoints: at startup it parses the OpenAPI 3.1 specs embedded in the binary and builds its command tree from them. Updating the API surface is a matter of refreshing the embedded spec and shipping a new build — no per-endpoint code. ``` kobana [flags] ``` Designed for both humans and AI agents: structured JSON output by default, schema introspection, `--dry-run` and automatic pagination. ## Products[​](#products "Direct link to Products") | Product | Description | | ------------ | -------------------------------------------------------------------------------- | | `banking` | Banking Gateway — charges, payments, transfers (API v1 and v2) | | `finance` | Smart Finance — payables and receivables, transactions, cash flow | | `billing` | Automatic Billing — subscriptions, plans, invoices, tax documents | | `inbox` | Autonomous Inbox — inboxes, agents, e-mails, webhooks | | `dunning` | Dunning — debtors, charges, collection rules, agreements, credit bureau listings | | `dashboards` | Magic Dashboard — data sources, entities, portal, workspaces | The `billing` product talks to the same API documented on this site. Its resources — see the [full catalogue](https://docs.billing.kobana.com.br/en/en/cli/resources/overview.md) — point at the same endpoints as the [API Reference](https://docs.billing.kobana.com.br/en/en/api/v1); the CLI is just another way to call it. It does not share credentials with the other products: see [Authentication](https://docs.billing.kobana.com.br/en/en/cli/overview/authentication.md). ## Getting started[​](#getting-started "Direct link to Getting started") 1. **Install** it — see [Installation](https://docs.billing.kobana.com.br/en/en/cli/overview/installation.md). 2. **Authenticate** for the product you are going to use. See [Authentication](https://docs.billing.kobana.com.br/en/en/cli/overview/authentication.md). 3. **Make your first call**: ``` kobana billing subscriptions list --fields "id,status,plan_id" ``` 4. **Explore the surface** — every command supports `--help`, and `kobana schema` introspects any endpoint's parameters and body without leaving the terminal. ## Next steps[​](#next-steps "Direct link to Next steps") * [Installation](https://docs.billing.kobana.com.br/en/en/cli/overview/installation.md) — Homebrew, prebuilt binaries, Nix, building from source. * [Authentication](https://docs.billing.kobana.com.br/en/en/cli/overview/authentication.md) — tokens, environments and the `billing` product's own credentials. * [Usage](https://docs.billing.kobana.com.br/en/en/cli/usage/overview.md) — syntax, resources, examples. * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — `kobana schema` for parameters and request/response shapes. * [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) — the flags every command accepts. * [Helpers](https://docs.billing.kobana.com.br/en/en/cli/usage/helpers.md) — `+verb` shortcuts for common workflows. * [Environment variables](https://docs.billing.kobana.com.br/en/en/cli/overview/environment-variables.md) — auth, config and logging. * [Exit codes](https://docs.billing.kobana.com.br/en/en/cli/overview/exit-codes.md) — process exit codes for scripting. --- # Billing accounts The account that accumulates a customer's subscriptions, invoices and credits. Suspending halts billing without ending the relationship; closing ends it. | Command | HTTP | Description | | -------------------------------- | --------------------------------------------- | -------------------------------------- | | `billing-accounts list` | `GET /v1/billing_accounts` | List billing accounts | | `billing-accounts create` | `POST /v1/billing_accounts` | Create a billing account | | `billing-accounts get` | `GET /v1/billing_accounts/{id}` | Get a billing account | | `billing-accounts update` | `PATCH /v1/billing_accounts/{id}` | Update a billing account | | `billing-accounts delete` | `DELETE /v1/billing_accounts/{id}` | Delete a billing account (soft delete) | | `billing-accounts close` | `POST /v1/billing_accounts/{id}/close` | Close a billing account (POST /close) | | `billing-accounts credits` | `GET /v1/billing_accounts/{id}/credits` | List the account's credits | | `billing-accounts entitlements` | `GET /v1/billing_accounts/{id}/entitlements` | List the account's entitlements | | `billing-accounts invoices` | `GET /v1/billing_accounts/{id}/invoices` | List the account's invoices | | `billing-accounts reactivate` | `POST /v1/billing_accounts/{id}/reactivate` | Reactivate a billing account | | `billing-accounts subscriptions` | `GET /v1/billing_accounts/{id}/subscriptions` | List the account's subscriptions | | `billing-accounts suspend` | `POST /v1/billing_accounts/{id}/suspend` | Suspend a billing account | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List billing accounts kobana billing billing-accounts list \ --fields "id,public_id,external_id,currency,billing_email" # Get a billing account kobana billing billing-accounts get --params '{"id": "BILLING_ACCOUNT_ID"}' # Create a billing account kobana billing billing-accounts create --json '{"customer": "CUSTOMER"}' # Update a billing account kobana billing billing-accounts update \ --params '{"id": "BILLING_ACCOUNT_ID"}' \ --json '{"external_id": "EXTERNAL_ID", "name": "NAME", "email": "EMAIL"}' # Close a billing account (POST /close) kobana billing billing-accounts close \ --params '{"id": "BILLING_ACCOUNT_ID"}' \ --json '{"reason": "REASON"}' # Delete a billing account (soft delete) kobana billing billing-accounts delete \ --params '{"id": "BILLING_ACCOUNT_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Invoices](https://docs.billing.kobana.com.br/en/en/cli/resources/invoices.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Digital certificates The A1 certificates used to sign tax documents. The file is uploaded once and never comes back in a response. | Command | HTTP | Description | | --------------------- | ------------------------------ | ---------------------------- | | `certificates list` | `GET /v1/certificates` | List digital certificates | | `certificates create` | `POST /v1/certificates` | Upload a digital certificate | | `certificates get` | `GET /v1/certificates/{id}` | Get a certificate | | `certificates delete` | `DELETE /v1/certificates/{id}` | Remove a certificate | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List digital certificates kobana billing certificates list \ --fields "id,public_id,external_id,person_id,name" # Get a certificate kobana billing certificates get --params '{"id": "CERTIFICATE_ID"}' # Upload a digital certificate kobana billing certificates create # Remove a certificate kobana billing certificates delete \ --params '{"id": "CERTIFICATE_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Usage](https://docs.billing.kobana.com.br/en/en/cli/resources/usage.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Companies The issuing companies — who is charging. They carry the fiscal profile used when issuing invoices, and one of them is the default. | Command | HTTP | Description | | --------------------------------- | ----------------------------------------- | --------------------------------------- | | `companies list` | `GET /v1/companies` | List companies | | `companies create` | `POST /v1/companies` | Create a company | | `companies get` | `GET /v1/companies/{id}` | Get a company by ID | | `companies update` | `PATCH /v1/companies/{id}` | Update a company | | `companies delete` | `DELETE /v1/companies/{id}` | Delete a company (soft delete) | | `companies deactivate` | `POST /v1/companies/{id}/deactivate` | Deactivate a company (POST /deactivate) | | `companies reactivate` | `POST /v1/companies/{id}/reactivate` | Reactivate a company | | `companies set-default` | `POST /v1/companies/{id}/set-default` | Set the default company | | `companies fiscal get` | `GET /v1/companies/{id}/fiscal` | Get the fiscal profile | | `companies fiscal update` | `PATCH /v1/companies/{id}/fiscal` | Update the fiscal profile | | `companies fiscal-profile get` | `GET /v1/companies/{id}/fiscal-profile` | Get the fiscal profile (alias) | | `companies fiscal-profile update` | `PATCH /v1/companies/{id}/fiscal-profile` | Update the fiscal profile (alias) | | `companies matriz list` | `GET /v1/companies/matriz` | List head offices | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List companies kobana billing companies list \ --fields "id,public_id,external_id,organization_id,person_id" # Get a company by ID kobana billing companies get --params '{"id": "COMPANIE_ID"}' # Create a company kobana billing companies create \ --json '{"name": "NAME", "document_type": "cpf", "document_number": "DOCUMENT_NUMBER", "email": "EMAIL"}' # Update a company kobana billing companies update \ --params '{"id": "COMPANIE_ID"}' \ --json '{"name": "NAME", "external_id": "EXTERNAL_ID", "legal_name": "LEGAL_NAME"}' # Deactivate a company (POST /deactivate) kobana billing companies deactivate --params '{"id": "COMPANIE_ID"}' # Delete a company kobana billing companies delete --params '{"id": "COMPANIE_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Organization](https://docs.billing.kobana.com.br/en/en/cli/resources/organization.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Coupons Discounts with validity rules and usage limits. `redemptions` shows where each coupon was actually applied. | Command | HTTP | Description | | --------------------- | ---------------------------------- | ----------------------------- | | `coupons list` | `GET /v1/coupons` | List coupons | | `coupons create` | `POST /v1/coupons` | Create a coupon | | `coupons get` | `GET /v1/coupons/{id}` | Get a coupon | | `coupons update` | `PATCH /v1/coupons/{id}` | Update a coupon | | `coupons delete` | `DELETE /v1/coupons/{id}` | Delete a coupon | | `coupons deactivate` | `POST /v1/coupons/{id}/deactivate` | Deactivate a coupon | | `coupons redemptions` | `GET /v1/coupons/{id}/redemptions` | List the coupon's redemptions | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List coupons kobana billing coupons list --fields "id,public_id,external_id,code,name" # Get a coupon kobana billing coupons get --params '{"id": "COUPON_ID"}' # Create a coupon kobana billing coupons create \ --json '{"code": "CODE", "name": "NAME", "discount_type": "percentage", "discount_value": 0}' # Update a coupon kobana billing coupons update \ --params '{"id": "COUPON_ID"}' \ --json '{"name": "NAME", "external_id": "EXTERNAL_ID", "description": "DESCRIPTION"}' # Deactivate a coupon kobana billing coupons deactivate --params '{"id": "COUPON_ID"}' # Delete a coupon kobana billing coupons delete --params '{"id": "COUPON_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Customers](https://docs.billing.kobana.com.br/en/en/cli/resources/customers.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Credits Balance in the customer's favour, applicable to future invoices. Applying and removing credits are commands on the invoice itself. | Command | HTTP | Description | | ---------------- | ------------------------- | --------------- | | `credits list` | `GET /v1/credits` | List credits | | `credits create` | `POST /v1/credits` | Add a credit | | `credits get` | `GET /v1/credits/{id}` | Get a credit | | `credits update` | `PATCH /v1/credits/{id}` | Update a credit | | `credits delete` | `DELETE /v1/credits/{id}` | Delete a credit | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List credits kobana billing credits list \ --fields "id,public_id,external_id,billing_account_id,organization_id" # Get a credit kobana billing credits get --params '{"id": "CREDIT_ID"}' # Add a credit kobana billing credits create \ --json '{"billing_account_id": "BILLING_ACCOUNT_ID", "type": "promotional", "amount_cents": 10000}' # Update a credit kobana billing credits update \ --params '{"id": "CREDIT_ID"}' \ --json '{"external_id": "EXTERNAL_ID", "type": "promotional", "amount_cents": 100}' # Delete a credit kobana billing credits delete --params '{"id": "CREDIT_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Withholdings](https://docs.billing.kobana.com.br/en/en/cli/resources/withholdings.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Customers Who gets billed, their portal users and the consolidated statement. `recalculate-mrr` recomputes the customer's recurring revenue. | Command | HTTP | Description | | --------------------------------- | ------------------------------------------------------ | --------------------------------------------- | | `customers list` | `GET /v1/customers` | List customers | | `customers create` | `POST /v1/customers` | Create a customer | | `customers get` | `GET /v1/customers/{id}` | Get a customer | | `customers update` | `PATCH /v1/customers/{id}` | Update a customer | | `customers delete` | `DELETE /v1/customers/{id}` | Remove a customer (soft delete) | | `customers recalculate-mrr` | `POST /v1/customers/{id}/recalculate-mrr` | Recalculate the customer's MRR | | `customers statement list` | `GET /v1/customers/{id}/statement` | List the customer's financial statement | | `customers statement sync create` | `POST /v1/customers/{id}/statement/sync` | Rebuild the statement from history | | `customers users list` | `GET /v1/customers/{id}/users` | List the customer portal's users | | `customers users get` | `GET /v1/customers/{id}/users/{user_id}` | Get portal user | | `customers users create` | `POST /v1/customers/{id}/users` | Invite a portal user | | `customers users update` | `PATCH /v1/customers/{id}/users/{user_id}` | Update a portal user | | `customers users delete` | `DELETE /v1/customers/{id}/users/{user_id}` | Delete a portal user (soft delete) | | `customers users email-preview` | `GET /v1/customers/{id}/users/{user_id}/email-preview` | Preview the portal user's e-mail | | `customers users resend` | `POST /v1/customers/{id}/users/{user_id}/resend` | Re-send the invitation or verification e-mail | | `customers users invite create` | `POST /v1/customers/{id}/users/invite` | Invite a portal user (verb) | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List customers kobana billing customers list \ --fields "id,public_id,external_id,name,nickname" # Get a customer kobana billing customers get --params '{"id": "CUSTOMER_ID"}' # Create a customer kobana billing customers create --json '{"name": "NAME"}' # Update a customer kobana billing customers update \ --params '{"id": "CUSTOMER_ID"}' \ --json '{"name": "NAME", "external_id": "EXTERNAL_ID", "nickname": "NICKNAME"}' # Recalculate the customer's MRR kobana billing customers recalculate-mrr --params '{"id": "CUSTOMER_ID"}' # Remove a customer (soft delete) kobana billing customers delete --params '{"id": "CUSTOMER_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Companies](https://docs.billing.kobana.com.br/en/en/cli/resources/companies.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Dashboard users Who has access to your organization's dashboard — the operators, not the customers. | Command | HTTP | Description | | ------------------------ | --------------------------------- | ----------------------- | | `dashboard-users list` | `GET /v1/dashboard_users` | List dashboard users | | `dashboard-users create` | `POST /v1/dashboard_users` | Invite a dashboard user | | `dashboard-users get` | `GET /v1/dashboard_users/{id}` | Get a dashboard user | | `dashboard-users update` | `PATCH /v1/dashboard_users/{id}` | Update a dashboard user | | `dashboard-users delete` | `DELETE /v1/dashboard_users/{id}` | Remove a dashboard user | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List dashboard users kobana billing dashboard-users list \ --fields "id,public_id,organization_id,person_id,external_id" # Get a dashboard user kobana billing dashboard-users get --params '{"id": "DASHBOARD_USER_ID"}' # Invite a dashboard user kobana billing dashboard-users create \ --json '{"email": "EMAIL", "role_ids": []}' # Update a dashboard user kobana billing dashboard-users update \ --params '{"id": "DASHBOARD_USER_ID"}' \ --json '{"name": "NAME", "picture": "PICTURE", "status": "active"}' # Remove a dashboard user kobana billing dashboard-users delete \ --params '{"id": "DASHBOARD_USER_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Team roles](https://docs.billing.kobana.com.br/en/en/cli/resources/team-roles.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Invoices The document to be charged, from draft to paid. `finalize` seals the draft, `pay` records settlement, `void` cancels it, and instalments live under `installments`. | Command | HTTP | Description | | --------------------------------- | --------------------------------------------------------------- | ------------------------------------ | | `invoices list` | `GET /v1/invoices` | List invoices | | `invoices create` | `POST /v1/invoices` | Create an invoice | | `invoices get` | `GET /v1/invoices/{id}` | Get an invoice | | `invoices update` | `PATCH /v1/invoices/{id}` | Update an invoice | | `invoices delete` | `DELETE /v1/invoices/{id}` | Delete an invoice | | `invoices apply-credits` | `POST /v1/invoices/{id}/apply-credits` | Apply credits to an invoice | | `invoices finalize` | `POST /v1/invoices/{id}/finalize` | Finalize an invoice | | `invoices issue-nfe` | `POST /v1/invoices/{id}/issue-nfe` | Issue an NF-e for an invoice | | `invoices pay` | `POST /v1/invoices/{id}/pay` | Pay an invoice | | `invoices payment-methods` | `GET /v1/invoices/{id}/payment-methods` | List available payment methods | | `invoices pdf` | `GET /v1/invoices/{id}/pdf` | Download the invoice PDF | | `invoices remove-credits` | `POST /v1/invoices/{id}/remove-credits` | Remove applied credits | | `invoices send-reminder` | `POST /v1/invoices/{id}/send-reminder` | Send a billing reminder | | `invoices undo-payment` | `POST /v1/invoices/{id}/undo-payment` | Undo the invoice's payment | | `invoices void` | `POST /v1/invoices/{id}/void` | Void an invoice | | `invoices installments get` | `GET /v1/invoices/{id}/installments` | List the invoice's instalments | | `invoices installments create` | `POST /v1/invoices/{id}/installments` | Create/update an instalment plan | | `invoices installments mark-paid` | `POST /v1/invoices/{id}/installments/{installmentId}/mark-paid` | Mark an instalment as paid | | `invoices installments pay` | `POST /v1/invoices/{id}/installments/{installmentId}/pay` | Pay an instalment | | `invoices pending-nfe list` | `GET /v1/invoices/pending-nfe` | List invoices with a pending NF-e | | `invoices pending-payment list` | `GET /v1/invoices/pending-payment` | List invoices with a pending payment | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List invoices kobana billing invoices list \ --fields "id,public_id,external_id,number,billing_account_id" # Get an invoice kobana billing invoices get --params '{"id": "INVOICE_ID"}' # Create an invoice kobana billing invoices create \ --json '{"billing_account_id": "BILLING_ACCOUNT_ID", "line_items": []}' # Update an invoice kobana billing invoices update \ --params '{"id": "INVOICE_ID"}' \ --json '{"external_id": "EXTERNAL_ID", "company_id": "COMPANY_ID", "collection_method": "charge_automatically"}' # Apply credits to an invoice kobana billing invoices apply-credits \ --params '{"id": "INVOICE_ID"}' \ --json '{"credit_ids": []}' # Delete an invoice kobana billing invoices delete --params '{"id": "INVOICE_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Payments](https://docs.billing.kobana.com.br/en/en/cli/resources/payments.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Invoices (NF-e) The tax document behind an invoice: issue, cancel, download PDF and XML, and follow every attempt at the city hall. Barueri has commands of its own. | Command | HTTP | Description | | ------------------------------ | ---------------------------------------- | ------------------------------------ | | `nfes list` | `GET /v1/nfes` | List NF-es | | `nfes create` | `POST /v1/nfes` | Create an NF-e (draft) | | `nfes get` | `GET /v1/nfes/{id}` | Get an NF-e | | `nfes update` | `PATCH /v1/nfes/{id}` | Update an NF-e (draft) | | `nfes delete` | `DELETE /v1/nfes/{id}` | Delete an NF-e | | `nfes cancel` | `POST /v1/nfes/{id}/cancel` | Cancel an NF-e | | `nfes issue` | `POST /v1/nfes/{id}/issue` | Issue an NF-e | | `nfes pdf` | `GET /v1/nfes/{id}/pdf` | Download the NF-e PDF | | `nfes retry-cancel` | `POST /v1/nfes/{id}/retry-cancel` | Retry the NF-e cancellation | | `nfes validate-barueri` | `POST /v1/nfes/{id}/validate-barueri` | Validate a Barueri NFS-e | | `nfes xml` | `GET /v1/nfes/{id}/xml` | Download the NF-e XML | | `nfes bulk create` | `POST /v1/nfes/bulk` | Update NF-es in bulk | | `nfes bulk delete` | `DELETE /v1/nfes/bulk` | Delete NF-es in bulk | | `nfes fetch-barueri create` | `POST /v1/nfes/fetch-barueri` | Fetch an NFS-e from Barueri | | `nfes fetch-from-sefaz create` | `POST /v1/nfes/fetch-from-sefaz` | Fetch an NFS-e from the ADN (SEFAZ) | | `nfes import-barueri create` | `POST /v1/nfes/import-barueri` | Import a Barueri NFS-e | | `nfes request-tries list` | `GET /v1/nfes/request-tries` | List request attempts (organization) | | `nfes request-tries get` | `GET /v1/nfes/{id}/request-tries` | List the NF-e's request attempts | | `nfes requests list` | `GET /v1/nfes/{id}/requests` | List NF-e external requests | | `nfes requests get` | `GET /v1/nfes/{id}/requests/{requestId}` | Get an external request | | `nfes sync create` | `POST /v1/nfes/sync` | Sync the organization's NF-es | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List NF-es kobana billing nfes list \ --fields "id,public_id,external_id,invoice_id,transaction_id" # Get an NF-e kobana billing nfes get --params '{"id": "NFE_ID"}' # Create an NF-e (draft) kobana billing nfes create \ --json '{"billing_account_id": "BILLING_ACCOUNT_ID", "amount_cents": 100, "customer": {}}' # Update an NF-e (draft) kobana billing nfes update \ --params '{"id": "NFE_ID"}' \ --json '{"external_id": "EXTERNAL_ID", "service_code": "SERVICE_CODE", "service_description": "SERVICE_DESCRIPTION"}' # Cancel an NF-e kobana billing nfes cancel \ --params '{"id": "NFE_ID"}' \ --json '{"reason": "REASON"}' # Delete an NF-e kobana billing nfes delete --params '{"id": "NFE_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Tax rules](https://docs.billing.kobana.com.br/en/en/cli/resources/tax-rules.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Organization The settings at the top of the hierarchy, shared by every company in the account. | Command | HTTP | Description | | --------------------- | ------------------------ | ------------------------------- | | `organization list` | `GET /v1/organization` | Get the current organization | | `organization update` | `PATCH /v1/organization` | Update the current organization | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # Get the current organization kobana billing organization list \ --fields "id,public_id,external_id,status,created_at" # Update the current organization kobana billing organization update \ --json '{"name": "NAME", "email": "EMAIL", "phone": "PHONE"}' ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Proposals](https://docs.billing.kobana.com.br/en/en/cli/resources/proposals.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Resources Every `billing` resource below is generated from the same OpenAPI spec documented in the [API Reference](https://docs.billing.kobana.com.br/en/en/api/v1) — the CLI dispatches to the exact same endpoints, so filters, validation and delete behaviour are identical. Reach for [schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) whenever a command's exact parameters aren't obvious from the examples here. ``` kobana billing [flags] ``` ## How to read these pages[​](#how-to-read-these-pages "Direct link to How to read these pages") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. See [Authentication](https://docs.billing.kobana.com.br/en/en/cli/overview/authentication.md) for the `billing` product's own credentials. ## The catalogue[​](#the-catalogue "Direct link to The catalogue") | Resource | Command | Methods | | ---------------------------------------------------------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [Plans](https://docs.billing.kobana.com.br/en/en/cli/resources/plans.md) | `plans` | list, create, get, update, delete, archive, duplicate, bulk-archive create, bulk delete, bulk-move-group create, items get, items update | | [Plan groups](https://docs.billing.kobana.com.br/en/en/cli/resources/plan-groups.md) | `plan-groups` | list, create, get, update, delete, archive, reorder create | | [Products](https://docs.billing.kobana.com.br/en/en/cli/resources/products.md) | `products` | list, create, get, update, delete, archive, publish, restore, bulk-archive create, bulk-change-company create, bulk delete, bulk-move-group create, bulk-visibility create, reorder create, reorder update | | [Product groups](https://docs.billing.kobana.com.br/en/en/cli/resources/product-groups.md) | `product-groups` | list, create, get, update, delete, archive, unarchive, reorder create, reorder update | | [Service items](https://docs.billing.kobana.com.br/en/en/cli/resources/service-items.md) | `service-items` | list, create, get, update, delete | | [Subscriptions](https://docs.billing.kobana.com.br/en/en/cli/resources/subscriptions.md) | `subscriptions` | list, create, get, update, delete, activate, cancel, change-plan, create-invoice, items get, pause, resume, revert-to-confirmed, sync-plan-items | | [Subscription changes](https://docs.billing.kobana.com.br/en/en/cli/resources/subscription-changes.md) | `subscription-changes` | config list, config update | | [Subscription item changes](https://docs.billing.kobana.com.br/en/en/cli/resources/subscription-item-changes.md) | `subscription-item-changes` | list, get, cancel | | [Plan changes](https://docs.billing.kobana.com.br/en/en/cli/resources/plan-changes.md) | `plan-changes` | list, create, get, config list, config update, rules list, rules create, rules get, rules update, rules delete, stats list | | [Billing accounts](https://docs.billing.kobana.com.br/en/en/cli/resources/billing-accounts.md) | `billing-accounts` | list, create, get, update, delete, close, credits, entitlements, invoices, reactivate, subscriptions, suspend | | [Invoices](https://docs.billing.kobana.com.br/en/en/cli/resources/invoices.md) | `invoices` | list, create, get, update, delete, apply-credits, finalize, issue-nfe, pay, payment-methods, pdf, remove-credits, send-reminder, undo-payment, void, installments get, installments create, installments mark-paid, installments pay, pending-nfe list, pending-payment list | | [Payments](https://docs.billing.kobana.com.br/en/en/cli/resources/payments.md) | `payments` | list, create, get, delete, cancel, change-card, change-due-date, refund, retry, send-email, sync, bulk-update-invoice create | | [Payment methods](https://docs.billing.kobana.com.br/en/en/cli/resources/payment-methods.md) | `payment-methods` | list, create, get, update, delete, set-default | | [Credits](https://docs.billing.kobana.com.br/en/en/cli/resources/credits.md) | `credits` | list, create, get, update, delete | | [Withholdings](https://docs.billing.kobana.com.br/en/en/cli/resources/withholdings.md) | `withholdings` | list, get, convert-to-credit, convert-to-credits create | | [Coupons](https://docs.billing.kobana.com.br/en/en/cli/resources/coupons.md) | `coupons` | list, create, get, update, delete, deactivate, redemptions | | [Customers](https://docs.billing.kobana.com.br/en/en/cli/resources/customers.md) | `customers` | list, create, get, update, delete, recalculate-mrr, statement list, statement sync create, users list, users get, users create, users update, users delete, users email-preview, users resend, users invite create | | [Companies](https://docs.billing.kobana.com.br/en/en/cli/resources/companies.md) | `companies` | list, create, get, update, delete, deactivate, reactivate, set-default, fiscal get, fiscal update, fiscal-profile get, fiscal-profile update, matriz list | | [Organization](https://docs.billing.kobana.com.br/en/en/cli/resources/organization.md) | `organization` | list, update | | [Proposals](https://docs.billing.kobana.com.br/en/en/cli/resources/proposals.md) | `proposals` | list, create, get, update, delete, accept, cancel, duplicate, generate-pdf, json, pricing, publish, send, undo-accept, unpublish, bulk-cancel create, bulk delete, bulk-send create, items get, items create, items update, items delete, stats list | | [Proposal templates](https://docs.billing.kobana.com.br/en/en/cli/resources/proposal-templates.md) | `proposal-templates` | list, create, get, update, delete, activate, deactivate, duplicate | | [Invoices (NF-e)](https://docs.billing.kobana.com.br/en/en/cli/resources/nfes.md) | `nfes` | list, create, get, update, delete, cancel, issue, pdf, retry-cancel, validate-barueri, xml, bulk create, bulk delete, fetch-barueri create, fetch-from-sefaz create, import-barueri create, request-tries list, request-tries get, requests list, requests get, sync create | | [Tax rules](https://docs.billing.kobana.com.br/en/en/cli/resources/tax-rules.md) | `tax-rules` | list, create, get, update, delete | | [Tax periods](https://docs.billing.kobana.com.br/en/en/cli/resources/tax-periods.md) | `tax-periods` | list, create, get, update, delete | | [Digital certificates](https://docs.billing.kobana.com.br/en/en/cli/resources/certificates.md) | `certificates` | list, create, get, delete | | [Usage](https://docs.billing.kobana.com.br/en/en/cli/resources/usage.md) | `usage` | list, create, snapshots daily list, snapshots daily create, snapshots monthly list, snapshots monthly create, summary list | | [Dashboard users](https://docs.billing.kobana.com.br/en/en/cli/resources/dashboard-users.md) | `dashboard-users` | list, create, get, update, delete | | [Team roles](https://docs.billing.kobana.com.br/en/en/cli/resources/team-roles.md) | `team-roles` | list, create, get, update, delete | --- # Payment methods A customer's saved cards and other methods, and which one is the default. | Command | HTTP | Description | | ----------------------------- | ------------------------------------------- | ------------------------------------- | | `payment-methods list` | `GET /v1/payment_methods` | List payment methods | | `payment-methods create` | `POST /v1/payment_methods` | Create a payment method | | `payment-methods get` | `GET /v1/payment_methods/{id}` | Get a payment method | | `payment-methods update` | `PATCH /v1/payment_methods/{id}` | Update the card's expiry | | `payment-methods delete` | `DELETE /v1/payment_methods/{id}` | Delete a payment method (soft delete) | | `payment-methods set-default` | `POST /v1/payment_methods/{id}/set-default` | Set the method as default | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List payment methods kobana billing payment-methods list \ --fields "id,public_id,external_id,billing_account_id,credit_card_id" # Get a payment method kobana billing payment-methods get --params '{"id": "PAYMENT_METHOD_ID"}' # Create a payment method kobana billing payment-methods create \ --json '{"billingAccountId": "BILLINGACCOUNTID", "type": "card"}' # Update the card's expiry kobana billing payment-methods update \ --params '{"id": "PAYMENT_METHOD_ID"}' \ --json '{"exp_month": 0, "exp_year": 0}' # Set the method as default kobana billing payment-methods set-default \ --params '{"id": "PAYMENT_METHOD_ID"}' # Remove a payment method kobana billing payment-methods delete \ --params '{"id": "PAYMENT_METHOD_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Credits](https://docs.billing.kobana.com.br/en/en/cli/resources/credits.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Payments The settlement attempts on an invoice: retry, card swap, due-date change, refund and re-sending the billing e-mail. | Command | HTTP | Description | | ------------------------------------- | ---------------------------------------- | ------------------------------------ | | `payments list` | `GET /v1/payments` | List payments | | `payments create` | `POST /v1/payments` | Process a payment | | `payments get` | `GET /v1/payments/{id}` | Get a payment | | `payments delete` | `DELETE /v1/payments/{id}` | Delete a payment | | `payments cancel` | `POST /v1/payments/{id}/cancel` | Cancel a payment | | `payments change-card` | `POST /v1/payments/{id}/change-card` | Swap the payment's card | | `payments change-due-date` | `POST /v1/payments/{id}/change-due-date` | Change the billet's due date | | `payments refund` | `POST /v1/payments/{id}/refund` | Refund a payment | | `payments retry` | `POST /v1/payments/{id}/retry` | Retry a payment | | `payments send-email` | `POST /v1/payments/{id}/send-email` | Send the billet by e-mail | | `payments sync` | `POST /v1/payments/{id}/sync` | Sync a payment with the gateway | | `payments bulk-update-invoice create` | `POST /v1/payments/bulk-update-invoice` | Reassign payments to another invoice | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List payments kobana billing payments list \ --fields "id,public_id,external_id,invoice_id,billing_account_id" # Get a payment kobana billing payments get --params '{"id": "PAYMENT_ID"}' # Process a payment kobana billing payments create --json '{"invoiceId": "INVOICEID"}' # Cancel a payment kobana billing payments cancel \ --params '{"id": "PAYMENT_ID"}' \ --json '{"reason": "REASON", "cancel_on_gateway": true}' # Delete a payment kobana billing payments delete --params '{"id": "PAYMENT_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Payment methods](https://docs.billing.kobana.com.br/en/en/cli/resources/payment-methods.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Plan changes Upgrades and downgrades: the rules for what can become what, the proration configuration and the statistics of what actually changed. | Command | HTTP | Description | | ---------------------------- | ------------------------------------ | ------------------------------------ | | `plan-changes list` | `GET /v1/plan_changes` | List plan changes | | `plan-changes create` | `POST /v1/plan_changes` | Run a plan change | | `plan-changes get` | `GET /v1/plan_changes/{id}` | Get a plan change | | `plan-changes config list` | `GET /v1/plan_changes/config` | Get the plan-change configuration | | `plan-changes config update` | `PATCH /v1/plan_changes/config` | Update the plan-change configuration | | `plan-changes rules list` | `GET /v1/plan_changes/rules` | List plan-change rules | | `plan-changes rules create` | `POST /v1/plan_changes/rules` | Create a plan-change rule | | `plan-changes rules get` | `GET /v1/plan_changes/rules/{id}` | Get a plan-change rule | | `plan-changes rules update` | `PATCH /v1/plan_changes/rules/{id}` | Update a plan-change rule | | `plan-changes rules delete` | `DELETE /v1/plan_changes/rules/{id}` | Delete a plan-change rule | | `plan-changes stats list` | `GET /v1/plan_changes/stats` | Plan-change statistics | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List plan changes kobana billing plan-changes list \ --fields "id,public_id,external_id,subscription_id,billing_account_id" # Get a plan change kobana billing plan-changes get --params '{"id": "PLAN_CHANGE_ID"}' # Run a plan change kobana billing plan-changes create \ --json '{"subscription_id": "SUBSCRIPTION_ID", "to_plan_id": "TO_PLAN_ID"}' # Update the plan-change configuration kobana billing plan-changes config update \ --json '{"allow_upgrade": true, "allow_downgrade": true, "upgrade_proration": "full_proration"}' # Delete a plan-change rule kobana billing plan-changes rules delete \ --params '{"id": "RULE_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Billing accounts](https://docs.billing.kobana.com.br/en/en/cli/resources/billing-accounts.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Plan groups The shelf plans are displayed and ordered on. `reorder` changes the order; `archive` takes the group out of circulation without deleting it. | Command | HTTP | Description | | ---------------------------- | ----------------------------------- | -------------------- | | `plan-groups list` | `GET /v1/plan_groups` | List plan groups | | `plan-groups create` | `POST /v1/plan_groups` | Create a plan group | | `plan-groups get` | `GET /v1/plan_groups/{id}` | Get a plan group | | `plan-groups update` | `PATCH /v1/plan_groups/{id}` | Update a plan group | | `plan-groups delete` | `DELETE /v1/plan_groups/{id}` | Remove a plan group | | `plan-groups archive` | `POST /v1/plan_groups/{id}/archive` | Archive a plan group | | `plan-groups reorder create` | `POST /v1/plan_groups/reorder` | Reorder plan groups | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List plan groups kobana billing plan-groups list \ --fields "id,public_id,external_id,organization_id,company_id" # Get a plan group kobana billing plan-groups get --params '{"id": "PLAN_GROUP_ID"}' # Create a plan group kobana billing plan-groups create --json '{"name": "NAME"}' # Update a plan group kobana billing plan-groups update \ --params '{"id": "PLAN_GROUP_ID"}' \ --json '{"name": "NAME", "slug": "SLUG", "external_id": "EXTERNAL_ID"}' # Archive a plan group kobana billing plan-groups archive --params '{"id": "PLAN_GROUP_ID"}' # Remove a plan group kobana billing plan-groups delete --params '{"id": "PLAN_GROUP_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Products](https://docs.billing.kobana.com.br/en/en/cli/resources/products.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Plans What gets subscribed to: price, billing period and the list of items the plan delivers. The `bulk-*` operations act on many plans at once. | Command | HTTP | Description | | ------------------------------ | -------------------------------- | ----------------------------------- | | `plans list` | `GET /v1/plans` | List plans | | `plans create` | `POST /v1/plans` | Create a plan | | `plans get` | `GET /v1/plans/{id}` | Get a plan | | `plans update` | `PATCH /v1/plans/{id}` | Update a plan | | `plans delete` | `DELETE /v1/plans/{id}` | Delete a plan (soft delete) | | `plans archive` | `POST /v1/plans/{id}/archive` | Archive a plan | | `plans duplicate` | `POST /v1/plans/{id}/duplicate` | Duplicate a plan | | `plans bulk-archive create` | `POST /v1/plans/bulk-archive` | Archive plans in bulk | | `plans bulk delete` | `DELETE /v1/plans/bulk` | Delete plans in bulk | | `plans bulk-move-group create` | `POST /v1/plans/bulk-move-group` | Move plans to another group in bulk | | `plans items get` | `GET /v1/plans/{id}/items` | List the plan's items | | `plans items update` | `PUT /v1/plans/{id}/items` | Replace the plan's items | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List plans kobana billing plans list \ --fields "id,public_id,external_id,organization_id,company_id" # Get a plan kobana billing plans get --params '{"id": "PLAN_ID"}' # Create a plan kobana billing plans create --json '{"name": "NAME", "slug": "SLUG"}' # Update a plan kobana billing plans update \ --params '{"id": "PLAN_ID"}' \ --json '{"external_id": "EXTERNAL_ID", "company_id": "COMPANY_ID", "plan_group_id": "PLAN_GROUP_ID"}' # Duplicate a plan kobana billing plans duplicate --params '{"id": "PLAN_ID"}' # Archive a plan (reversible) kobana billing plans archive --params '{"id": "PLAN_ID"}' # Delete a plan (soft delete) kobana billing plans delete --params '{"id": "PLAN_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Plan groups](https://docs.billing.kobana.com.br/en/en/cli/resources/plan-groups.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Product groups The grouping of the product catalogue, with its own ordering and archiving. | Command | HTTP | Description | | ------------------------------- | ---------------------------------------- | ---------------------------------- | | `product-groups list` | `GET /v1/product_groups` | List product groups | | `product-groups create` | `POST /v1/product_groups` | Create a product group | | `product-groups get` | `GET /v1/product_groups/{id}` | Get a product group | | `product-groups update` | `PATCH /v1/product_groups/{id}` | Update a product group | | `product-groups delete` | `DELETE /v1/product_groups/{id}` | Remove a product group | | `product-groups archive` | `POST /v1/product_groups/{id}/archive` | Archive a product group | | `product-groups unarchive` | `POST /v1/product_groups/{id}/unarchive` | Unarchive a product group | | `product-groups reorder create` | `POST /v1/product_groups/reorder` | Reorder product groups | | `product-groups reorder update` | `PUT /v1/product_groups/reorder` | Reorder product groups (PUT alias) | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List product groups kobana billing product-groups list \ --fields "id,public_id,external_id,organization_id,company_id" # Get a product group kobana billing product-groups get --params '{"id": "PRODUCT_GROUP_ID"}' # Create a product group kobana billing product-groups create --json '{"name": "NAME"}' # Update a product group kobana billing product-groups update \ --params '{"id": "PRODUCT_GROUP_ID"}' \ --json '{"name": "NAME", "slug": "SLUG", "company_id": "COMPANY_ID"}' # Remove a product group kobana billing product-groups delete \ --params '{"id": "PRODUCT_GROUP_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Service items](https://docs.billing.kobana.com.br/en/en/cli/resources/service-items.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Products The catalogue of what you charge for, item by item, before it becomes a plan or an invoice line. Publish, archive and restore control visibility without destroying history. | Command | HTTP | Description | | ------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------ | | `products list` | `GET /v1/products` | List products | | `products create` | `POST /v1/products` | Create a product | | `products get` | `GET /v1/products/{id}` | Get a product | | `products update` | `PATCH /v1/products/{id}` | Update a product | | `products delete` | `DELETE /v1/products/{id}` | Delete a product (soft delete: gone from every read and from every plan) | | `products archive` | `POST /v1/products/{id}/archive` | Archive a product | | `products publish` | `POST /v1/products/{id}/publish` | Publish a product | | `products restore` | `POST /v1/products/{id}/restore` | Restore an archived product | | `products bulk-archive create` | `POST /v1/products/bulk-archive` | Archive products in bulk | | `products bulk-change-company create` | `POST /v1/products/bulk-change-company` | Change products' company in bulk | | `products bulk delete` | `DELETE /v1/products/bulk` | Delete products in bulk | | `products bulk-move-group create` | `POST /v1/products/bulk-move-group` | Move products to another group | | `products bulk-visibility create` | `POST /v1/products/bulk-visibility` | Change visibility in bulk | | `products reorder create` | `POST /v1/products/reorder` | Reorder products | | `products reorder update` | `PUT /v1/products/reorder` | Reorder products (PUT /reorder) | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List products kobana billing products list \ --fields "id,public_id,external_id,organization_id,company_id" # Get a product kobana billing products get --params '{"id": "PRODUCT_ID"}' # Create a product kobana billing products create --json '{"name": "NAME", "slug": "SLUG"}' # Update a product kobana billing products update \ --params '{"id": "PRODUCT_ID"}' \ --json '{"name": "NAME", "slug": "SLUG", "description": "DESCRIPTION"}' # Archive a product kobana billing products archive --params '{"id": "PRODUCT_ID"}' # Delete a product (soft delete) kobana billing products delete --params '{"id": "PRODUCT_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Product groups](https://docs.billing.kobana.com.br/en/en/cli/resources/product-groups.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Proposal templates The templates proposals are born from, with one marked as the default. | Command | HTTP | Description | | ------------------------------- | --------------------------------------------- | ------------------------------ | | `proposal-templates list` | `GET /v1/proposal_templates` | List proposal templates | | `proposal-templates create` | `POST /v1/proposal_templates` | Create a proposal template | | `proposal-templates get` | `GET /v1/proposal_templates/{id}` | Get a proposal template | | `proposal-templates update` | `PATCH /v1/proposal_templates/{id}` | Update a proposal template | | `proposal-templates delete` | `DELETE /v1/proposal_templates/{id}` | Delete a proposal template | | `proposal-templates activate` | `POST /v1/proposal_templates/{id}/activate` | Activate a proposal template | | `proposal-templates deactivate` | `POST /v1/proposal_templates/{id}/deactivate` | Deactivate a proposal template | | `proposal-templates duplicate` | `POST /v1/proposal_templates/{id}/duplicate` | Duplicate a proposal template | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List proposal templates kobana billing proposal-templates list \ --fields "id,public_id,external_id,name,description" # Get a proposal template kobana billing proposal-templates get \ --params '{"id": "PROPOSAL_TEMPLATE_ID"}' # Create a proposal template kobana billing proposal-templates create \ --json '{"name": "NAME", "googleDocId": "GOOGLEDOCID"}' # Update a proposal template kobana billing proposal-templates update \ --params '{"id": "PROPOSAL_TEMPLATE_ID"}' \ --json '{"name": "NAME", "description": "DESCRIPTION", "documentType": "google_doc"}' # Activate a proposal template kobana billing proposal-templates activate \ --params '{"id": "PROPOSAL_TEMPLATE_ID"}' # Delete a proposal template kobana billing proposal-templates delete \ --params '{"id": "PROPOSAL_TEMPLATE_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Invoices (NF-e)](https://docs.billing.kobana.com.br/en/en/cli/resources/nfes.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Proposals The quote before the subscription: publish, send, generate a PDF and accept. Accepting is what turns the proposal into a subscription — and `undo-accept` reverses it. | Command | HTTP | Description | | ------------------------------ | ------------------------------------------ | ------------------------------------ | | `proposals list` | `GET /v1/proposals` | List proposals | | `proposals create` | `POST /v1/proposals` | Create a proposal | | `proposals get` | `GET /v1/proposals/{id}` | Get a proposal | | `proposals update` | `PATCH /v1/proposals/{id}` | Update a proposal | | `proposals delete` | `DELETE /v1/proposals/{id}` | Delete a proposal | | `proposals accept` | `POST /v1/proposals/{id}/accept` | Accept a proposal | | `proposals cancel` | `POST /v1/proposals/{id}/cancel` | Cancel a proposal | | `proposals duplicate` | `POST /v1/proposals/{id}/duplicate` | Duplicate a proposal | | `proposals generate-pdf` | `POST /v1/proposals/{id}/generate-pdf` | Generate the proposal PDF | | `proposals json` | `GET /v1/proposals/{id}/json` | Get the proposal's JSON snapshot | | `proposals pricing` | `GET /v1/proposals/{id}/pricing` | Get the proposal's price calculation | | `proposals publish` | `POST /v1/proposals/{id}/publish` | Publish a proposal | | `proposals send` | `POST /v1/proposals/{id}/send` | Send a proposal by e-mail | | `proposals undo-accept` | `POST /v1/proposals/{id}/undo-accept` | Undo the proposal's acceptance | | `proposals unpublish` | `POST /v1/proposals/{id}/unpublish` | Unpublish a proposal | | `proposals bulk-cancel create` | `POST /v1/proposals/bulk-cancel` | Cancel proposals in bulk | | `proposals bulk delete` | `DELETE /v1/proposals/bulk` | Delete proposals in bulk | | `proposals bulk-send create` | `POST /v1/proposals/bulk-send` | Send proposals in bulk | | `proposals items get` | `GET /v1/proposals/{id}/items` | List the proposal's items | | `proposals items create` | `POST /v1/proposals/{id}/items` | Add an item to a proposal | | `proposals items update` | `PATCH /v1/proposals/{id}/items/{itemId}` | Update a proposal item | | `proposals items delete` | `DELETE /v1/proposals/{id}/items/{itemId}` | Delete a proposal item | | `proposals stats list` | `GET /v1/proposals/stats` | Get proposal statistics | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List proposals kobana billing proposals list \ --fields "id,public_id,external_id,company_id,code" # Get a proposal kobana billing proposals get --params '{"id": "PROPOSAL_ID"}' # Create a proposal kobana billing proposals create \ --json '{"company_id": "COMPANY_ID", "title": "TITLE", "description": "DESCRIPTION"}' # Update a proposal kobana billing proposals update \ --params '{"id": "PROPOSAL_ID"}' \ --json '{"company_id": "COMPANY_ID", "title": "TITLE", "description": "DESCRIPTION"}' # Accept a proposal kobana billing proposals accept \ --params '{"id": "PROPOSAL_ID"}' \ --json '{"cycle": "monthly"}' # Delete a proposal kobana billing proposals delete --params '{"id": "PROPOSAL_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Proposal templates](https://docs.billing.kobana.com.br/en/en/cli/resources/proposal-templates.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Service items The municipal service list entries used to describe what an invoice (NFS-e) is charging for. | Command | HTTP | Description | | ---------------------- | ------------------------------- | ----------------------------------- | | `service-items list` | `GET /v1/service_items` | List service items | | `service-items create` | `POST /v1/service_items` | Create a service item | | `service-items get` | `GET /v1/service_items/{id}` | Get a service item | | `service-items update` | `PATCH /v1/service_items/{id}` | Update a service item | | `service-items delete` | `DELETE /v1/service_items/{id}` | Delete a service item (soft delete) | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List service items kobana billing service-items list \ --fields "id,public_id,external_id,organization_id,company_id" # Get a service item kobana billing service-items get --params '{"id": "SERVICE_ITEM_ID"}' # Create a service item kobana billing service-items create \ --json '{"name": "NAME", "internal_code": "INTERNAL_CODE", "lc116_code": "01.05"}' # Update a service item kobana billing service-items update \ --params '{"id": "SERVICE_ITEM_ID"}' \ --json '{"external_id": "EXTERNAL_ID", "company_id": "COMPANY_ID", "name": "NAME"}' # Delete a service item kobana billing service-items delete \ --params '{"id": "SERVICE_ITEM_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Subscriptions](https://docs.billing.kobana.com.br/en/en/cli/resources/subscriptions.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Subscription changes The configuration for how subscription changes get applied — immediately, next cycle, with or without proration. | Command | HTTP | Description | | ------------------------------------ | ------------------------------------- | -------------------------------------------- | | `subscription-changes config list` | `GET /v1/subscription_changes/config` | Get the subscription-change configuration | | `subscription-changes config update` | `PUT /v1/subscription_changes/config` | Update the subscription-change configuration | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # Get the subscription-change configuration kobana billing subscription-changes config list \ --fields "id,publicId,organizationId,externalId,allowItemAdd" # Update the subscription-change configuration kobana billing subscription-changes config update \ --json '{"allow_item_add": true, "allow_item_remove": true, "allow_quantity_change": true}' ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Subscription item changes](https://docs.billing.kobana.com.br/en/en/cli/resources/subscription-item-changes.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Subscription item changes The history of changes to a subscription's items, and the cancellation of a change that is still scheduled. | Command | HTTP | Description | | ---------------------------------- | ------------------------------------------------ | --------------------------------------- | | `subscription-item-changes list` | `GET /v1/subscription_item_changes` | List subscription item changes | | `subscription-item-changes get` | `GET /v1/subscription_item_changes/{id}` | Get a subscription item change | | `subscription-item-changes cancel` | `POST /v1/subscription_item_changes/{id}/cancel` | Cancel a change that is still scheduled | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List subscription item changes kobana billing subscription-item-changes list \ --fields "id,publicId,organizationId,subscriptionId,billingAccountId" # Get a subscription item change kobana billing subscription-item-changes get \ --params '{"id": "SUBSCRIPTION_ITEM_CHANGE_ID"}' ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Plan changes](https://docs.billing.kobana.com.br/en/en/cli/resources/plan-changes.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Subscriptions The live contract between a customer and a plan: activate, pause, resume, change plan and cancel. `create-invoice` forces an invoice outside the cycle. | Command | HTTP | Description | | ----------------------------------- | ------------------------------------------------- | ----------------------------------------------- | | `subscriptions list` | `GET /v1/subscriptions` | List subscriptions | | `subscriptions create` | `POST /v1/subscriptions` | Create a subscription | | `subscriptions get` | `GET /v1/subscriptions/{id}` | Get a subscription | | `subscriptions update` | `PATCH /v1/subscriptions/{id}` | Update a subscription | | `subscriptions delete` | `DELETE /v1/subscriptions/{id}` | Cancel and remove a subscription (soft delete) | | `subscriptions activate` | `POST /v1/subscriptions/{id}/activate` | Activate a draft/confirmed subscription | | `subscriptions cancel` | `POST /v1/subscriptions/{id}/cancel` | Cancel a subscription | | `subscriptions change-plan` | `POST /v1/subscriptions/{id}/change-plan` | Change the subscription's plan | | `subscriptions create-invoice` | `POST /v1/subscriptions/{id}/create-invoice` | Generate a one-off invoice for the subscription | | `subscriptions items get` | `GET /v1/subscriptions/{id}/items` | List the subscription's items | | `subscriptions pause` | `POST /v1/subscriptions/{id}/pause` | Pause a subscription | | `subscriptions resume` | `POST /v1/subscriptions/{id}/resume` | Resume a paused subscription | | `subscriptions revert-to-confirmed` | `POST /v1/subscriptions/{id}/revert-to-confirmed` | Revert a subscription to the confirmed state | | `subscriptions sync-plan-items` | `POST /v1/subscriptions/{id}/sync-plan-items` | Re-sync items with the current plan | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List subscriptions kobana billing subscriptions list \ --fields "id,public_id,external_id,billing_account_id,company_id" # Get a subscription kobana billing subscriptions get --params '{"id": "SUBSCRIPTION_ID"}' # Create a subscription kobana billing subscriptions create \ --json '{"billing_account_id": "BILLING_ACCOUNT_ID"}' # Update a subscription kobana billing subscriptions update \ --params '{"id": "SUBSCRIPTION_ID"}' \ --json '{"external_id": "EXTERNAL_ID", "plan_id": "PLAN_ID", "billing_cycle": "monthly"}' # Activate a draft/confirmed subscription kobana billing subscriptions activate --params '{"id": "SUBSCRIPTION_ID"}' # Cancel and remove a subscription (soft delete) kobana billing subscriptions delete \ --params '{"id": "SUBSCRIPTION_ID"}' \ --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Subscription changes](https://docs.billing.kobana.com.br/en/en/cli/resources/subscription-changes.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Tax periods The tax periods that group issued invoices. | Command | HTTP | Description | | -------------------- | ----------------------------- | ------------------------------- | | `tax-periods list` | `GET /v1/tax_periods` | List tax periods | | `tax-periods create` | `POST /v1/tax_periods` | Process the monthly tax period | | `tax-periods get` | `GET /v1/tax_periods/{id}` | Get a tax period | | `tax-periods update` | `PATCH /v1/tax_periods/{id}` | Run an action on the tax period | | `tax-periods delete` | `DELETE /v1/tax_periods/{id}` | Delete a tax period | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List tax periods kobana billing tax-periods list \ --fields "id,public_id,external_id,company_id,period_type" # Get a tax period kobana billing tax-periods get --params '{"id": "TAX_PERIOD_ID"}' # Process the monthly tax period kobana billing tax-periods create --json '{"year": 2026, "month": 6}' # Run an action on the tax period kobana billing tax-periods update \ --params '{"id": "TAX_PERIOD_ID"}' \ --json '{"action": "recalculate"}' # Delete a tax period kobana billing tax-periods delete --params '{"id": "TAX_PERIOD_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Digital certificates](https://docs.billing.kobana.com.br/en/en/cli/resources/certificates.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Tax rules Which tax applies to what, and at what rate — what invoice issuing consults. | Command | HTTP | Description | | ------------------ | --------------------------- | ----------------- | | `tax-rules list` | `GET /v1/tax_rules` | List tax rules | | `tax-rules create` | `POST /v1/tax_rules` | Create a tax rule | | `tax-rules get` | `GET /v1/tax_rules/{id}` | Get a tax rule | | `tax-rules update` | `PATCH /v1/tax_rules/{id}` | Update a tax rule | | `tax-rules delete` | `DELETE /v1/tax_rules/{id}` | Delete a tax rule | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List tax rules kobana billing tax-rules list \ --fields "id,public_id,external_id,scope,priority" # Get a tax rule kobana billing tax-rules get --params '{"id": "TAX_RULE_ID"}' # Create a tax rule kobana billing tax-rules create \ --json '{"name": "NAME", "scope": "global", "items": []}' # Update a tax rule kobana billing tax-rules update \ --params '{"id": "TAX_RULE_ID"}' \ --json '{"name": "NAME", "description": "DESCRIPTION", "priority": 0}' # Delete a tax rule kobana billing tax-rules delete --params '{"id": "TAX_RULE_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Tax periods](https://docs.billing.kobana.com.br/en/en/cli/resources/tax-periods.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Team roles The roles that define what each dashboard user can do. | Command | HTTP | Description | | ------------------- | ---------------------------- | -------------------- | | `team-roles list` | `GET /v1/team_roles` | List team roles | | `team-roles create` | `POST /v1/team_roles` | Create a custom role | | `team-roles get` | `GET /v1/team_roles/{id}` | Get a role | | `team-roles update` | `PATCH /v1/team_roles/{id}` | Update a role | | `team-roles delete` | `DELETE /v1/team_roles/{id}` | Remove a role | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List team roles kobana billing team-roles list \ --fields "id,public_id,organization_id,name,slug" # Get a role kobana billing team-roles get --params '{"id": "TEAM_ROLE_ID"}' # Create a custom role kobana billing team-roles create \ --json '{"name": "NAME", "slug": "billing_manager", "permissions": []}' # Update a role kobana billing team-roles update \ --params '{"id": "TEAM_ROLE_ID"}' \ --json '{"name": "NAME", "slug": "SLUG", "description": "DESCRIPTION"}' # Remove a role kobana billing team-roles delete --params '{"id": "TEAM_ROLE_ID"}' --dry-run ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Usage The usage events that feed metered billing, with daily and monthly snapshots and a consolidated summary. | Command | HTTP | Description | | -------------------------------- | ---------------------------------- | ------------------------------ | | `usage list` | `GET /v1/usage` | List usage records | | `usage create` | `POST /v1/usage` | Report usage (metered) | | `usage snapshots daily list` | `GET /v1/usage/snapshots/daily` | List daily usage snapshots | | `usage snapshots daily create` | `POST /v1/usage/snapshots/daily` | Create daily usage snapshots | | `usage snapshots monthly list` | `GET /v1/usage/snapshots/monthly` | List monthly usage snapshots | | `usage snapshots monthly create` | `POST /v1/usage/snapshots/monthly` | Create monthly usage snapshots | | `usage summary list` | `GET /v1/usage/summary` | Usage summary for the period | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List usage records kobana billing usage list \ --fields "id,public_id,external_id,subscription_item_id,quantity" # Report usage (metered) kobana billing usage create ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Dashboard users](https://docs.billing.kobana.com.br/en/en/cli/resources/dashboard-users.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Withholdings Amounts the customer withheld at source, which can be converted into credit. | Command | HTTP | Description | | ---------------------------------------- | ---------------------------------------------- | --------------------------------------------------- | | `withholdings list` | `GET /v1/withholdings` | List withholdings | | `withholdings get` | `GET /v1/withholdings/{id}` | Get a withholding | | `withholdings convert-to-credit` | `POST /v1/withholdings/{id}/convert-to-credit` | Convert a withholding into credit | | `withholdings convert-to-credits create` | `POST /v1/withholdings/convert-to-credits` | Convert pending withholdings into credits (in bulk) | ## Examples[​](#examples "Direct link to Examples") `--params` carries query and path parameters (id, page, filters); `--json` carries the request body; `--fields` limits which fields come back — worth using on every `list`/`get` to save context. See [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) for the full reference. ``` # List withholdings kobana billing withholdings list \ --fields "id,public_id,external_id,organization_id,invoice_id" # Get a withholding kobana billing withholdings get --params '{"id": "WITHHOLDING_ID"}' # Convert pending withholdings into credits (in bulk) kobana billing withholdings convert-to-credits create \ --json '{"tax_type": "iss", "competence_year": 0, "competence_month": 0}' # Convert a withholding into credit kobana billing withholdings convert-to-credit \ --params '{"id": "WITHHOLDING_ID"}' \ --json '{"amount_cents": 100}' ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Coupons](https://docs.billing.kobana.com.br/en/en/cli/resources/coupons.md) * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — every parameter this resource accepts. --- # Global flags | Flag | Description | | ------------------------- | -------------------------------------------------------------------- | | `--params ''` | Query/URL parameters (id, page, filters) | | `--json ''` | Request body (POST/PUT/PATCH) | | `--fields ''` | Limits which fields come back in the response | | `--dry-run` | Shows the request without executing it | | `--page-all` | Auto-pagination with NDJSON output | | `--page-limit ` | Maximum number of pages (default: 10) | | `--page-delay ` | Delay between pages (default: 100ms) | | `--env ` | Environment: `production` (default), `sandbox`, `development` | | `--verbose` | Request details on stderr | | `--output ` | Saves the response to a file | | `--output-format ` | Format: `json`, `table`, `csv` | | `--idempotency-key ` | Custom idempotency key | | `--lang ` | Language of the messages: `pt`, `en` or `es` (default: the system's) | ## Language[​](#language "Direct link to Language") The CLI speaks Portuguese, English or Spanish: help, messages, errors and command descriptions. The language comes, in this order, from `--lang`, the `KOBANA_LANG` variable, the terminal's locale variables (`LC_ALL`, `LC_MESSAGES`, `LANG`) and, last, the system language. ``` kobana --lang pt billing --help export KOBANA_LANG=es ``` Command and flag names, JSON keys and exit codes never change with the language. Available since version 0.6.0. ## Next steps[​](#next-steps "Direct link to Next steps") * [Usage](https://docs.billing.kobana.com.br/en/en/cli/usage/overview.md) — syntax, resources, examples. * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — parameters, required fields, types and responses. --- # Helpers Helpers are commands prefixed with `+` that provide multi-step workflows the dynamic commands alone cannot: simplified interfaces, batch operations, or calls composed across multiple endpoints. They do not wrap a single API call already available through the dynamic commands — every helper flag controls orchestration logic, not a reshaped version of `--params`/`--json`. Today's helpers belong to the **Banking Gateway**, and are available from the same binary whichever product you use: | Helper | Description | | ---------------- | ------------------------------------------------ | | `+emitir` | Simplified bank billet creation with named flags | | `+cancelar-lote` | Batch-cancel multiple bank billets by id | | `+cobrar` | Simplified Pix charge creation with named flags | ``` # Issue a bank billet kobana +emitir --valor 150.50 --vencimento 2026-05-01 \ --nome "Maria Silva" --cpf-cnpj "012.345.678-90" --carteira 1 # Create a Pix charge kobana +cobrar --valor 99.90 --conta-pix "UID" \ --nome "João" --cpf-cnpj "012.345.678-90" # Batch-cancel bank billets kobana +cancelar-lote --ids "123,456,789" ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Usage](https://docs.billing.kobana.com.br/en/en/cli/usage/overview.md) — the dynamic commands these helpers sit alongside. * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — inspect the underlying endpoints a helper calls. --- # Usage ## Syntax[​](#syntax "Direct link to Syntax") ``` kobana [flags] ``` * **``** — `banking`, `finance`, `billing` or `inbox`. * **``** — can be nested: `subscriptions`, `invoices installments`, `customers users`. * **``** — the action: `list`, `get`, `create`, `update`, `delete`, or an action specific to the resource. The API version never appears in the command — the CLI resolves the URL from the embedded OpenAPI spec. URL and query parameters go in `--params`; the request body goes in `--json`. The whole surface is discoverable through `--help`, at every level: ``` kobana --help # products kobana billing --help # Automatic Billing resources kobana billing plans --help # a resource's methods ``` ## `billing` resources[​](#billing-resources "Direct link to billing-resources") | Resource | Description | | --------------------------- | ------------------------- | | `plans` | Plans | | `plan-groups` | Plan groups | | `products` | Products | | `product-groups` | Product groups | | `service-items` | Service items | | `subscriptions` | Subscriptions | | `subscription-changes` | Subscription changes | | `subscription-item-changes` | Subscription item changes | | `plan-changes` | Plan changes | | `billing-accounts` | Billing accounts | | `invoices` | Invoices | | `payments` | Payments | | `payment-methods` | Payment methods | | `credits` | Credits | | `withholdings` | Withholdings | | `coupons` | Coupons | | `customers` | Customers | | `companies` | Companies | | `organization` | Organization | | `proposals` | Proposals | | `proposal-templates` | Proposal templates | | `nfes` | Invoices (NF-e) | | `tax-rules` | Tax rules | | `tax-periods` | Tax periods | | `certificates` | Digital certificates | | `usage` | Usage | | `dashboard-users` | Dashboard users | | `team-roles` | Team roles | Each resource has a page of its own, with the full command table and examples — see the [catalogue](https://docs.billing.kobana.com.br/en/en/cli/resources/overview.md). ## Examples[​](#examples "Direct link to Examples") ``` # Active subscriptions kobana billing subscriptions list \ --params '{"status": "active"}' \ --fields "id,status,plan_id,next_billing_at" # Pause and resume a subscription kobana billing subscriptions pause --params '{"id": "SUBSCRIPTION_ID"}' kobana billing subscriptions resume --params '{"id": "SUBSCRIPTION_ID"}' # Finalize an invoice and issue its NF-e kobana billing invoices finalize --dry-run --params '{"id": "INVOICE_ID"}' kobana billing invoices issue-nfe --dry-run --params '{"id": "INVOICE_ID"}' # Create a plan kobana billing plans create --json '{"name": "Pro", "slug": "pro"}' # List with automatic pagination (NDJSON) kobana billing invoices list --page-all --fields "id,status,total" # Table output kobana billing plans list --output-format table # Save the response to a file kobana billing invoices get --params '{"id": "INVOICE_ID"}' --output fatura.json ``` ## Next steps[​](#next-steps "Direct link to Next steps") * [Schema introspection](https://docs.billing.kobana.com.br/en/en/cli/usage/schema.md) — inspect any endpoint's parameters and body. * [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) — every flag a command accepts. * [Helpers](https://docs.billing.kobana.com.br/en/en/cli/usage/helpers.md) — `+verb` shortcuts for common workflows. * [Resources](https://docs.billing.kobana.com.br/en/en/cli/resources/overview.md) — the full catalogue, resource by resource. --- # Schema introspection ``` # List every product and its resources kobana schema --list # View the schema of a specific endpoint kobana schema billing.subscriptions.list kobana schema billing.subscriptions.create kobana schema billing.invoices.finalize ``` Returns parameters, required fields, types and responses — all derived from the embedded OpenAPI spec, so it is always in sync with what a command actually accepts. The path has the same shape as the command: `..`. This is the recommended first step for an AI agent that does not already know the exact shape of a payload: inspect the schema before issuing a mutating call, rather than guessing. ## Next steps[​](#next-steps "Direct link to Next steps") * [Global flags](https://docs.billing.kobana.com.br/en/en/cli/usage/global-flags.md) — `--params`, `--json`, `--dry-run` and the rest. * [Usage](https://docs.billing.kobana.com.br/en/en/cli/usage/overview.md) — syntax, resources, examples. --- ## [📄️Analytics](https://docs.billing.kobana.com.br/en/en/configuracoes/analytics.md) [The Analytics area (/dashboard/analytics) turns billing operational data into SaaS metrics for the finance and product teams: MRR, ARR, churn, LTV, ARPU, cohort retention and the billing funnel.](https://docs.billing.kobana.com.br/en/en/configuracoes/analytics.md) --- ## [📄️Analytics](https://docs.billing.kobana.com.br/en/en/configuracoes/analytics.md) [The Analytics area (/dashboard/analytics) turns billing operational data into SaaS metrics for the finance and product teams: MRR, ARR, churn, LTV, ARPU, cohort retention and the billing funnel.](https://docs.billing.kobana.com.br/en/en/configuracoes/analytics.md) --- # Analytics The Analytics area (`/dashboard/analytics`) turns billing operational data into **SaaS metrics** for the finance and product teams: MRR, ARR, churn, LTV, ARPU, cohort retention and the billing funnel. ## Main metrics[​](#main-metrics "Direct link to Main metrics") * **MRR** (Monthly Recurring Revenue) — normalized sum of the subscriptions active in the month. * **ARR** — annualized projection of MRR. * **MRR Movement** — how much of the change came from **new**, **expansion**, **contraction**, **reactivation** and **churn**. * **Churn** — number and percentage of subscriptions canceled in the period. * **NRR** (Net Revenue Retention) — how much the existing base grew or shrank, not counting new customers. * **ARPU** (Average Revenue Per User) — average revenue per billing account. * **LTV** (Lifetime Value) — estimated revenue per customer over time. ## Visualizations[​](#visualizations "Direct link to Visualizations") The page uses Vega/Vega-Lite charts to show: * **MRR time series** with a monthly movement waterfall. * **Billing funnel** — issued → sent → paid → failed. * **Cohort retention** — heatmap showing the survival of each customer cohort. * **Distribution by plan** — how many subscriptions on each plan and MRR per plan. ## Filters[​](#filters "Direct link to Filters") * **Date range** — defaults to the last 12 months. * **Plan** — narrow down to one or more plans. * **Currency** — when the organization operates in more than one. ## Where the data comes from[​](#where-the-data-comes-from "Direct link to Where the data comes from") Analytics queries the operational tables (`subscriptions`, `subscription_versions`, `invoices`, `payments`) directly, filtered by `organization_id`. There is no ETL: the numbers reflect the current state of the database in real time. ## Export[​](#export "Direct link to Export") Each chart can be exported as CSV or PNG. For raw (row-by-row) extractions, use [Reports](https://docs.billing.kobana.com.br/en/en/configuracoes/relatorios.md) or [Exports](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/exportacoes/.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Analytics panel with MRR, churn, cohort retention and distribution by plan](/en/assets/images/analytics-45a77a9e6d9e71704f65e130f868d137.png) --- # API Keys At `/dashboard/api` the organization manages its **API keys**. Each key belongs to an organization, has a set of scopes and can be revoked at any time. :::caution The public API no longer uses API keys `/api/v1` now accepts **only** the access token from Kobana's Authorization Server (`Authorization: Bearer `), verified against the public key it publishes. A key created here does **not** authenticate the public API. The reason is that the key was both the credential and what verified it: anyone who read the key store could act as any organization, and every rotation was a conversation with a customer. With the token, the Authorization Server issues it and the platform can only verify it. ::: ## Key types[​](#key-types "Direct link to Key types") * **Live** (`sk_live_...`) — used in production. They operate on real data and create real charges. * **Test** (`sk_test_...`) — point to the sandbox; ideal for the initial integration and automated tests. ## Create a key[​](#create-a-key "Direct link to Create a key") 1. Click **New key**. 2. Give it a descriptive name (e.g. "Production backend", "Import worker"). 3. Select the scopes: * `subscriptions:read` / `subscriptions:write` * `invoices:read` / `invoices:write` * `payments:read` / `payments:write` * `customers:read` / `customers:write` * `nfes:read` / `nfes:write` * `webhooks:manage` 4. Optionally restrict it by **IP** (list of CIDR prefixes). 5. The key is shown **only once** after it is created. Copy it and store it in a vault. ## Best practices[​](#best-practices "Direct link to Best practices") * **One key per application** — makes it easy to revoke access without affecting other systems. * **Minimal scopes** — grant only what the application needs. * **Periodic rotation** — generate a new key, update the application and revoke the old one. * **Never commit** — keys should live in environment variables or a secrets vault. ## Rate limits[​](#rate-limits "Direct link to Rate limits") Each key follows the limits configured in [Rate Limiting](https://docs.billing.kobana.com.br/en/en/configuracoes/rate-limiting/.md). Requests over the limit return `429 Too Many Requests` with a `Retry-After` header. ## Audit and usage[​](#audit-and-usage "Direct link to Audit and usage") The page shows: * **Status** — `active` or `revoked` * **Last used** — date, IP and endpoint called * **Volume** — requests in the last 24h and the last 30 days Every creation or revocation is recorded in [Audit](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md). ## API documentation[​](#api-documentation "Direct link to API documentation") The complete endpoint reference is available in the **API** section of the side menu. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![List of API keys with name, scopes, last use and status](/en/assets/images/api-1b202aece6ad2bec1d909ff2ed5be561.png) --- # Audit Log The audit trail (`/dashboard/audit`) records **every data change** made in the dashboard or via the API. Each entry captures who made it, what was changed, the values before and after, IP, User-Agent and time, forming an immutable history for compliance, debugging and incident analysis. ## What is recorded[​](#what-is-recorded "Direct link to What is recorded") Every sensitive operation goes through `auditService`. Among the recorded actions: * Creation, update, suspension and activation of **billing accounts** and **customers** * Changes to **plan**, **items**, **subscription status**, **pause** and **cancellation** * Operations on **invoices**, **payments**, **refunds** and **credits** * Issuance, cancellation and errors of **NF-e** * Changes to **companies**, **gateways**, **webhooks** and **API keys** * Changes to **members**, **roles**, **settings** and **templates** * Administrative logins and logouts The complete list of actions is defined in `lib/services/audit.service.ts` (`AuditActions`). ## Filters[​](#filters "Direct link to Filters") The interface lets you filter by: * **Action** (for example, `subscription.canceled`, `invoice.paid`) * **Resource type** (subscription, invoice, customer, nfe, etc.) * **User** who performed it * **Date range** * **Text search** by resource ID or name ## Entry detail[​](#entry-detail "Direct link to Entry detail") Each row can be expanded into a modal that shows: * **previous\_values** — JSON with the previous state * **new\_values** — JSON with the state after the change * **metadata** — additional context (origin, reason, idempotency key) * **IP** and **User-Agent** captured from the request ## Retention and export[​](#retention-and-export "Direct link to Retention and export") Audit entries are immutable. For external analysis or long-term retention, use [Exports](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/exportacoes/.md) to download them as CSV. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Audit trail with actions, resources and change details](/en/assets/images/auditoria-96b65bf43d3a6c7a193a5e7e6562ebe8.png) --- # Billing Settings Settings that affect the organization's pricing and billing behavior. ## Fields[​](#fields "Direct link to Fields") | Field | Default | Description | | ---------------------------- | --------- | ----------------------------------- | | **Quarterly discount (%)** | 5% | Discount for quarterly cycle | | **Semiannual discount (%)** | 10% | Discount for semiannual cycle | | **Annual discount (%)** | 15% | Discount for annual cycle | | **Proposal validity (days)** | 30 | Days until the proposal expires | | **Default billing cycle** | `monthly` | Default cycle for new subscriptions | ## Cycle Discounts[​](#cycle-discounts "Direct link to Cycle Discounts") Discounts are automatically applied when calculating proposal prices and when presenting cycle options to the customer: | Cycle | Default Discount | Example (R$ 100/month plan) | | ---------- | ---------------- | ----------------------------- | | Monthly | 0% | R$ 100/month | | Quarterly | 5% | R$ 285/quarter (R$ 95/month) | | Semiannual | 10% | R$ 540/semester (R$ 90/month) | | Annual | 15% | R$ 1,020/year (R$ 85/month) | ## Where They Are Used[​](#where-they-are-used "Direct link to Where They Are Used") * **Proposals**: Price calculation per cycle * **Subscriptions**: Default cycle definition * **Portal**: Presenting cycle options to the customer --- # Company (Fiscal Entity) Companies represent the legal entities that issue invoices and NF-e. An organization can have multiple companies (headquarters and branches). ## Fields[​](#fields "Direct link to Fields") | Field | Description | | ------------------- | ------------------------------------------------ | | **Name** | Trade name | | **Legal name** | Full legal name | | **Document type** | CPF or CNPJ | | **Document number** | CPF or CNPJ | | **Default** | Whether it is the organization's default company | | **Status** | `active` or `inactive` | | **Parent company** | For branches, reference to the headquarters | ## Hierarchy[​](#hierarchy "Direct link to Hierarchy") ``` Headquarters (main CNPJ) ├── Branch 1 (same CNPJ prefix) └── Branch 2 (same CNPJ prefix) ``` ### Branch Rules[​](#branch-rules "Direct link to Branch Rules") * The headquarters must have a CNPJ to have branches * The branch's CNPJ must have the same prefix as the headquarters * Branches cannot be set as default ## Default Company[​](#default-company "Direct link to Default Company") One company per organization is marked as default. Used automatically when the company is not specified in operations. When deactivating the default company, another is automatically promoted. ## Fiscal Profile[​](#fiscal-profile "Direct link to Fiscal Profile") Each company has a linked fiscal profile that defines: * Tax regime (Simples Nacional, Lucro Presumido, Lucro Real) * Tax rates * Simples Nacional configuration * CBS/IBS configuration ## Operations[​](#operations "Direct link to Operations") * **Create**: Create a company or branch * **Update**: Edit registration data * **Set as default**: Marks as the default company * **Deactivate**: Not possible if there are active subscriptions or if it is the only active company * **Reactivate**: Returns to `active` status --- # Events The events screen (`/dashboard/events`) exposes the **internal stream of domain events** the system generates every time a relevant state changes — `invoice.created`, `payment.succeeded`, `subscription.canceled`, `nfe.issued` and dozens of others. It is the same queue that feeds [Webhooks](https://docs.billing.kobana.com.br/en/en/webhooks.md) and the customer history in the portal. ## Why it matters[​](#why-it-matters "Direct link to Why it matters") Unlike the [Audit Log](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md), which records changes made by people, **events** represent what happened from the business domain's point of view — regardless of the origin (UI, API, worker, webhook received from a gateway). Events are useful for: * **Debugging**: finding out why a webhook did not reach its destination or why a subscription was canceled unexpectedly. * **Replays**: resending events to an endpoint that was down. * **Integrations**: confirming that an expected event was actually generated. ## Event structure[​](#event-structure "Direct link to Event structure") Each event contains: * **type** — name in the `resource.action` pattern (e.g. `invoice.paid`) * **resource\_type** and **resource\_id** — the affected entity * **payload** — JSON with the relevant state at the time of the event * **created\_at** — when the event was emitted * **delivery\_status** — aggregate of the delivery attempts to the subscribed endpoints ## Filters and search[​](#filters-and-search "Direct link to Filters and search") The list offers filters by event type, resource, date range and delivery status. Each row can be expanded to show the full payload and the history of attempts on each subscribed endpoint. ## Event catalog[​](#event-catalog "Direct link to Event catalog") The complete reference of event types (and when each one is triggered) is in [Webhooks > Events](https://docs.billing.kobana.com.br/en/en/webhooks/eventos/.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![List of events with type, resource, payload and delivery status](/en/assets/images/eventos-4529e352da4c3efb40047b6d7383afa7.png) --- # Holidays Holidays are the days the banks are closed. They serve two purposes: * **Finding the effective due date**: an invoice due on a weekend or holiday can be paid on the next business day with no fine or interest. * **Counting business days** when the late fee policy charges interest per working day instead of per calendar day. Each organization has its own list. A municipal holiday moves the working day for one customer's bank and not another's, and removing a holiday on your account affects no one else. ## Where to configure it[​](#where-to-configure-it "Direct link to Where to configure it") `System` → **Holidays**. The screen shows the holidays for the selected year, with each row's weekday and where it came from. ## Automatic import[​](#automatic-import "Direct link to Automatic import") Every organization created on the platform already carries the **national holidays** for the current year and the next two, imported from [BrasilAPI](https://brasilapi.com.br/docs#tag/Feriados-Nacionais). To bring in another year, or to fill in what was missed, use **Import national** with the year selected. The import includes Carnaval, Good Friday, Easter and Corpus Christi. Strictly speaking Carnaval and Corpus Christi are optional days off rather than statutory holidays — but the banks close on them, and it is the bank closing that matters for counting a business day. :::note The import does not undo a removal If you remove a holiday, importing the national ones again does **not** bring it back. The removed row stays on file precisely so the import can respect your decision. When that happens, the screen says how many removed holidays were left out. ::: ## Adding one by hand[​](#adding-one-by-hand "Direct link to Adding one by hand") Use **New holiday** for state and municipal holidays, your own optional days off, or any other date. | Field | Description | | --------- | --------------------------------------------------------------------------------------------------------- | | **Date** | The day on the calendar. No time of day — a holiday is a date, not an instant | | **Name** | Together with the date it identifies the row. A municipal and a national holiday can fall on the same day | | **Scope** | National, state, municipal, optional day off, or your own | | **Notes** | Free text — the city of a municipal holiday, for instance | A holiday falling on a Saturday or Sunday changes nothing in the count: those days were not working days to begin with. The screen flags it to save you the question. ## How it affects interest[​](#how-it-affects-interest "Direct link to How it affects interest") In the late fee policy, the **Day count** field decides what counts: * **Calendar days** — every day, weekends and holidays included. * **Business days** — only the days the bank is open, according to this list. With R$ 1,000.00 at 1% per month, due on a Thursday and looked at the following Monday: | Day count | Days | Interest | | ------------------------------- | --------------------- | -------- | | Calendar | 4 | R$ 1.33 | | Business | 2 (Friday and Monday) | R$ 0.67 | | Business, with Friday a holiday | 1 (Monday) | R$ 0.33 | The **fine** is unaffected: it applies once, counted in calendar days. The bank instruction treats it the same way — there is no "business days for the fine" setting. :::caution With no holidays on file the count is wrong If the policy charges per business day and the list is empty, the calculation skips only weekends. The bank skips the holidays too, so it will collect less than we accrue — and the difference shows up as credit on the customer's account, along with the `invoice.late_charges_unexplained` event. Import the national ones before turning business-day charging on. ::: ## Due dates on weekends and holidays[​](#due-dates-on-weekends-and-holidays "Direct link to Due dates on weekends and holidays") A bank slip due on a day the banks are closed can be paid on the next business day with no charges — that is the Febraban rule, and the slip is already registered with that date. Fines and interest follow the slip's due date: they count from the **next business day**, whatever the policy's day count. An invoice due on Saturday and paid on Monday owes no fine or interest. Paid on Tuesday, it is one day late, counted from Monday. To have the invoice itself show that date — not just the slip — turn on **Due dates on business days only** under `Settings` → **Billing**. With it on, every due date that falls on a weekend or holiday moves to the next business day: the one computed from the payment terms, one typed by hand, and each installment's. Imported invoices keep the date in the file. ## Through the API[​](#through-the-api "Direct link to Through the API") The resource is `/v1/holidays`. Dates are calendar days (`YYYY-MM-DD`), never instants. ``` # List a year's holidays curl "https://api.kobana.com.br/billing/v1/holidays?year=2026" \ -H "Authorization: Bearer $TOKEN" # Add a municipal holiday curl -X POST https://api.kobana.com.br/billing/v1/holidays \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "date": "2026-01-25", "name": "Aniversário de São Paulo", "type": "municipal", "notes": "São Paulo, SP" }' # Import the national ones curl -X POST https://api.kobana.com.br/billing/v1/holidays/sync \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"years": [2026, 2027]}' ``` The import response carries `created`, `existing` and `skipped_removed` — the last one counts the holidays that were removed and therefore left out. ## Frequently asked[​](#frequently-asked "Direct link to Frequently asked") **Do I need holidays if I charge interest per calendar day?** Yes. Even with calendar days, a due date that falls on a holiday moves to the next business day, and only the list says which days are holidays. Without it, only weekends move the due date. **Do the holidays apply to all my companies?** The list is per organization, so it applies to every company inside it. If one company sits in a municipality with its own holiday, add it with the municipal scope and note the city. **Why does Easter appear, if it always falls on a Sunday?** BrasilAPI returns it, and keeping it is harmless: a holiday on a weekend does not change the count. **Who can edit this?** Anyone with permission to update settings — the same one as `Settings`. --- # Members and Roles The members page (`/dashboard/members`) lists everyone with access to the organization's dashboard. Each member has an email linked to Kobana authentication and one or more **roles** that define what they can see and change. ## Invite a member[​](#invite-a-member "Direct link to Invite a member") 1. Click **Invite Member** and enter the email. 2. Select one or more roles (e.g. `admin`, `fiscal`, `financeiro`, `read_only`). 3. The user receives an acceptance link by email. 4. After accepting, the member shows up with `active` status and can sign in via SSO. ## Member status[​](#member-status "Direct link to Member status") * **invited** — invitation sent, waiting for acceptance. * **active** — access granted. * **suspended** — access temporarily blocked, without removing the history. * **removed** — member removed (the audit of previous actions is kept). ## Roles[​](#roles "Direct link to Roles") Roles are managed at `/dashboard/members/roles`. Each role is a set of granular permissions — for example, "can issue NF-e", "can refund a payment", "can change a plan". The organization can create custom roles in addition to the default ones. ### Default roles[​](#default-roles "Direct link to Default roles") | Role | Typical access | | ------------- | --------------------------------------------- | | **Owner** | Full access, including platform billing | | **Admin** | Settings, members, invoices, plans, NF-e | | **Finance** | Invoices, payments, credits, dunning, exports | | **Fiscal** | NF-e, tax rules, tax periods, certificates | | **Sales** | Customers, plans, subscriptions, proposals | | **Read-only** | View all areas, no actions | ### Custom permissions[​](#custom-permissions "Direct link to Custom permissions") When creating a new role, you can turn individual permissions on or off per resource (customers, subscriptions, invoices, NF-e, tax rules, gateways, webhooks, etc.). Each permission can be read, create, edit or delete. ## Audit[​](#audit "Direct link to Audit") Every change to members and roles is recorded in the [Audit Log](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md): who invited, who accepted, who changed a role, IP and User-Agent. ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Member list[​](#member-list "Direct link to Member list") ![List of members with email, roles and status](/en/assets/images/membros-a12939b25d2ebae6d2af8971b34b412e.png) ### Role management[​](#role-management "Direct link to Role management") ![Screen for configuring roles and granular permissions](/en/assets/images/membros-papeis-a6ce724e0795b831d8984166abedd69c.png) --- # Notifications The notification system sends multichannel communications to customers about important events. ## Channels[​](#channels "Direct link to Channels") | Channel | Description | | ----------- | ------------------------------------------------ | | **email** | Sent via SMTP | | **in\_app** | Stored in the database for display in the portal | | **webhook** | Sent to the configured endpoint | ## Notification Types[​](#notification-types "Direct link to Notification Types") ### Subscriptions[​](#subscriptions "Direct link to Subscriptions") * `subscription_renewal` — Subscription renewed * `subscription_created` — New subscription * `subscription_canceled` — Subscription canceled ### Payments[​](#payments "Direct link to Payments") * `payment_succeeded` — Payment processed * `payment_failed` — Payment failed ### Invoices[​](#invoices "Direct link to Invoices") * `invoice_created` — Invoice generated * `invoice_overdue` — Invoice overdue ### Account[​](#account "Direct link to Account") * `trial_ending` — Trial expiring * `plan_changed` — Plan changed * `account_suspended` — Account suspended * `account_activated` — Account reactivated ### Portal[​](#portal "Direct link to Portal") * `portal_invitation` — Portal invitation * `portal_signup_verification` — Email verification ### Proposals[​](#proposals "Direct link to Proposals") * `proposal_sent` — Proposal sent * `proposal_reminder` — Proposal reminder * `proposal_expired` — Proposal expired * `proposal_accepted` — Proposal accepted * `proposal_rejected` — Proposal rejected ## Notification Status[​](#notification-status "Direct link to Notification Status") | Status | Description | | ----------- | ---------------------- | | `pending` | Awaiting delivery | | `sent` | Sent/queued | | `delivered` | Confirmed as delivered | | `failed` | Delivery failed | | `read` | Read (in\_app only) | ## Preferences[​](#preferences "Direct link to Preferences") Each billing account can configure preferences per notification type: * Enable/disable email * Enable/disable in\_app * Enable/disable webhook The system checks preferences before sending. ## Retry[​](#retry "Direct link to Retry") Failed notifications can be retried manually. ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/notifications` screen brings together channel configuration (email, in-app, webhook), templates per event, send history with status (`sent`, `delivered`, `bounced`, `failed`), delivery charts for the period and filters by channel, recipient and notification type. ![Multichannel notification configuration and history](/en/assets/images/notificacoes-bb76496514b66f02fcb23eff881e41be.png) --- # User Profile The `/dashboard/profile` page gathers the **personal preferences** of the signed-in operator: theme, language, time zone and notification settings. Unlike the organization's settings (which affect all members), profile preferences are per user and are stored both locally and on the server. ## Account details[​](#account-details "Direct link to Account details") Shows information coming from the authentication provider (Kobana OAuth): * **Name** and **email** * **Organizations** the user has access to * **Roles** assigned in each organization ## Appearance[​](#appearance "Direct link to Appearance") * **Theme** — light, dark or automatic (follows the operating system). * **Language** — `pt-BR` or `en-US`. Switching immediately updates the interface messages. ## Onboarding[​](#onboarding "Direct link to Onboarding") The profile also exposes the interactive onboarding controls: re-enable tips, mark steps as seen and revisit the dashboard's initial checklist. ## Email signature editor[​](#email-signature-editor "Direct link to Email signature editor") Includes a rich-text editor used to customize the signature applied to messages sent on behalf of the operator (bold, italic, links, images, lists, tables, etc.). ## How preferences are persisted[​](#how-preferences-are-persisted "Direct link to How preferences are persisted") * **localStorage** — `kobana-billing-preferences` stores theme and language for immediate hydration. * **Server** — changes are saved to the user's account to sync across devices. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![User profile with appearance, language and email signature](/en/assets/images/perfil-2c9bf591bee3ea37facd7119a7cdf958.png) --- # Rate Limiting The system implements API request limits to protect the platform and ensure fair usage. ## Default Limits[​](#default-limits "Direct link to Default Limits") | Type | Per Minute | Per Hour | | --------------------------------- | ---------- | -------- | | **Read (GET)** | 200 | 5,000 | | **Write (POST/PUT/PATCH/DELETE)** | 60 | 1,000 | ### Burst Limit[​](#burst-limit "Direct link to Burst Limit") | Field | Default | Description | | ---------------- | --------- | ----------------------------- | | **Burst limit** | 20 | Maximum simultaneous requests | | **Burst window** | 5 seconds | Window for burst counting | ## Per-Organization Configuration[​](#per-organization-configuration "Direct link to Per-Organization Configuration") Each organization can have custom limits. If not configured, global limits are used. ## Hierarchy[​](#hierarchy "Direct link to Hierarchy") 1. Organization configuration (if exists) 2. Default global configuration (if exists) 3. System hardcoded values ## Operations[​](#operations "Direct link to Operations") * **View**: See current organization limits * **Customize**: Set custom limits * **Remove**: Revert to global limits * **Disable**: Deactivate rate limiting (not recommended) --- # Reports The reports center (`/dashboard/reports`) is where the finance, operations and support teams generate **tabular extractions** of the organization's data. Unlike [Analytics](https://docs.billing.kobana.com.br/en/en/configuracoes/analytics.md), which aggregates metrics, reports deliver row-by-row data ready for reconciliation, auditing or building external spreadsheets. ## Available reports[​](#available-reports "Direct link to Available reports") * **Invoices in the period** — all invoices with customer, status, amount, dates and payment method. * **Payments in the period** — payments received, with gateway, method, fee and net amount. * **Refunds and reversals** — reversal operations, with reason and operator. * **Active subscriptions** — snapshot of the active base with plan, MRR, next cycle and collection method. * **Detailed churn** — subscriptions canceled in the period, with reason and final LTV. * **Delinquency** — accounts with an open invoice, grouped by range (1-30, 31-60, 61-90, 90+). * **Gateway reconciliation** — comparison between what the platform recorded and what the gateway confirmed. ## How to generate one[​](#how-to-generate-one "Direct link to How to generate one") 1. Choose the report type. 2. Set the filters (date range, company, plan, status, gateway). 3. Select the format (CSV or XLSX). 4. Confirm — the generation goes into the exports queue. 5. When ready, the file is available in [Exports](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/exportacoes/.md) and is sent by email. Heavy reports run in the background so the browser does not hang. The status (`pending`, `processing`, `completed`, `failed`) updates in real time. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Reports center with filters and export format](/en/assets/images/relatorios-eccb9df649a1a193768d51e7e95aea1f.png) --- # Email Templates Email templates allow you to customize transactional communications sent to customers. ## Template Fields[​](#template-fields "Direct link to Template Fields") | Field | Description | | ------------- | ---------------------------------------------- | | **Name** | Template name | | **Slug** | Unique identifier | | **Type** | Associated notification type | | **Subject** | Subject line (supports variables) | | **HTML body** | HTML content of the email (supports variables) | | **Text body** | Plain text version (fallback) | | **Variables** | List of variables used | | **Default** | One default template per notification type | | **Active** | Whether the template is available | ## Variables[​](#variables "Direct link to Variables") Variables are replaced in the subject and body using the syntax `\{\{ variable_name \}\}`: | Variable | Description | | ----------------------------- | ----------------------- | | `\{\{ customer_name \}\}` | Customer name | | `\{\{ invoice_number \}\}` | Invoice number | | `\{\{ amount \}\}` | Currency amount | | `\{\{ due_date \}\}` | Due date | | `\{\{ verification_url \}\}` | Email verification link | | `\{\{ reset_url \}\}` | Password reset link | | `\{\{ subscription_name \}\}` | Plan name | | `\{\{ trial_end_date \}\}` | Trial end date | ## Operations[​](#operations "Direct link to Operations") * **Create**: New template with name, slug, type, and content * **Update**: Edit subject, body, and variables * **Duplicate**: Copy template with a new slug * **Delete**: Cannot delete the default template * **Preview**: View the template with sample data * **Set as default**: Marks as the default template for the type ## Rendering[​](#rendering "Direct link to Rendering") 1. Gets the template by ID or by type (uses the default) 2. Loads all variables from the context 3. Replaces all `\{\{ key \}\}` patterns with the values 4. Returns the rendered subject and HTML body ## Security[​](#security "Direct link to Security") * Special characters are escaped via regex to prevent ReDoS * User input is sanitized before rendering --- # Usage and Consumption The `/dashboard/usage` screen consolidates the **metered consumption** of all the organization's customers: API events, messages sent, transactions processed, storage — any metric the catalog defines as "usage" and that is billed by consumption. ## Consolidated view[​](#consolidated-view "Direct link to Consolidated view") The main table groups consumption by product and by billing account, with: * **Product** (with its unit of measure — calls, events, messages, GB) * **Customer / billing account** * **Quantity in the period** * **Last recorded event** — with relative time * **Estimated amount** — projected charge for the next invoice ## Filters[​](#filters "Direct link to Filters") * **Date range** — defaults to the start of the current month through today. * **Customer** — combobox of billing accounts. * **Show zeros** — toggles whether accounts without consumption appear in the list. ## Where the data comes from[​](#where-the-data-comes-from "Direct link to Where the data comes from") Usage events arrive through: 1. **Usage Records API** — `POST /v1/subscription_items/{id}/usage_records` (Stripe-like pattern). 2. **`usage-sync` worker** — runs every hour and aggregates external counters when configured. 3. **CSV import** — for batch loads, via [Imports](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/importacoes/.md). Each usage record is linked to a `SubscriptionItem` with a **metered** product. At the cycle turnover, the `invoice-generation` worker turns the period's consumption into an invoice line. ## Clearing[​](#clearing "Direct link to Clearing") Operators with permission can reset a customer's usage records (useful for test cases). The action is recorded in the [Audit Log](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Consolidated usage panel with consumption by product and customer](/en/assets/images/uso-355a75876ac84a02ea9a2a7f7a8fcacc.png) --- # Users The `/dashboard/users` page lists the **customer portal users** — individuals linked to a billing account (`BillingAccount`) who can sign in to the portal to view invoices, pay boletos, manage cards and update their details. Unlike [Members](https://docs.billing.kobana.com.br/en/en/configuracoes/membros.md), who are the organization's internal operators, portal users are end customers (B2B2C). They authenticate via magic link or Kobana OAuth and see only the data of their own billing account. ## What the list shows[​](#what-the-list-shows "Direct link to What the list shows") * User's **email** * Linked **billing account** (legal name or customer name) * **Status** — `pending`, `active`, `suspended` * **Last access** — date and time of the last session * **Pending invitations** — links that have not been accepted yet ## Invite a user[​](#invite-a-user "Direct link to Invite a user") From the detail of a [billing account](https://docs.billing.kobana.com.br/en/en/contas/contas-de-cobranca/.md) or directly on this screen, you can: 1. Enter the email of the responsible contact. 2. Set permissions within the portal (view, pay, change plan, manage methods). 3. Send the invitation — the user receives an activation link. The activation token is stored encrypted (`lib/crypto.ts`) and expires after use or after the configured period. ## Resend and revoke[​](#resend-and-revoke "Direct link to Resend and revoke") * **Resend invitation** — generates a new token and sends a new email. * **Suspend** — blocks sign-in without deleting data. * **Remove** — deactivates permanently. The audit history remains. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![List of portal users with email, billing account and status](/en/assets/images/usuarios-do-portal-9a3360e6ef2ebfd9feb251833dd07e53.png) --- ## [📄️Customers (Persons)](https://docs.billing.kobana.com.br/en/en/contas/clientes/.md) [Customers are represented by the Person model (Person) with different types depending on the context.](https://docs.billing.kobana.com.br/en/en/contas/clientes/.md) --- ## [📄️Customers (Persons)](https://docs.billing.kobana.com.br/en/en/contas/clientes/.md) [Customers are represented by the Person model (Person) with different types depending on the context.](https://docs.billing.kobana.com.br/en/en/contas/clientes/.md) --- # Customers (Persons) Customers are represented by the **Person** model (`Person`) with different types depending on the context. ## Person Types[​](#person-types "Direct link to Person Types") | Type | Description | | -------------- | ------------------------------------------ | | `organization` | Tenant/organization that uses the platform | | `customer` | Customer of an organization | | `contact` | Secondary contact | ## Customer Fields[​](#customer-fields "Direct link to Customer Fields") | Field | Description | | ------------------- | ---------------------------------------------------- | | **Name** | Name or legal name | | **Nickname** | Trade name | | **Legal name** | Full legal name | | **Document type** | CPF or CNPJ | | **Document number** | Normalized (digits only) | | **Nature** | `natural` (individual) or `juridical` (legal entity) | | **Date of birth** | Optional | | **Addresses** | List of addresses (JSON) | | **Phones** | List of phone numbers (JSON) | | **Emails** | List of emails (JSON) | | **Websites** | List of websites (JSON) | | **Tags** | List of tags for categorization | | **Notes** | Internal observations | | **Custom data** | Custom fields (JSON) | ## Hierarchy[​](#hierarchy "Direct link to Hierarchy") Customers belong to an organization via the `parent_id` field: ``` Organization (type=organization, parentId=null) ├── Customer A (type=customer, parentId=org_id) ├── Customer B (type=customer, parentId=org_id) └── Contact (type=contact, parentId=org_id) ``` ## Validations[​](#validations "Direct link to Validations") * Document number unique within the organization * External code (`external_id`) unique per organization * Document format restrictions: CPF (11 digits) or CNPJ (14 digits) ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Customer list[​](#customer-list "Direct link to Customer list") The `/dashboard/customers` screen lists the organization's customers with search by name, document or email. The table shows document, email, total linked billing accounts and consolidated MRR. ![List of customers with name, document and billing accounts](/en/assets/images/clientes-bf8af06788c5f476cd76327045b3fadf.png) ### Customer detail[​](#customer-detail "Direct link to Customer detail") The `/dashboard/customers/[id]` page brings together registration data, linked billing accounts, subscriptions, invoices, payments, NF-e and audit — all in a single context for support and finance. ![Customer detail with billing, subscription and invoice tabs](/en/assets/images/cliente-detalhe-ec2e52a8f26346262334c6b646969ad0.png) --- # Billing Accounts Billing accounts (BillingAccount) represent the financial relationship between an organization and its customer. Each account has subscriptions, invoices, payments, and payment methods. ## Fields[​](#fields "Direct link to Fields") | Field | Description | | ------------------------ | ----------------------------------------------------- | | **Organization** | Owning organization (required) | | **Person** | Associated customer (type=customer) | | **External ID** | Identifier for integrations (unique per organization) | | **Currency** | Billing currency (default: BRL) | | **Billing email** | Email to receive invoices | | **Payment terms (days)** | Payment deadline in days (default: 10) | | **Auto-charge** | Whether invoices are charged automatically | | **Balance (cents)** | Credit/debit balance of the account | | **Status** | `active`, `suspended`, or `closed` | ### Fiscal Configuration[​](#fiscal-configuration "Direct link to Fiscal Configuration") | Field | Description | | -------------------------- | ---------------------------------- | | **Tax exempt** | Whether the customer is tax exempt | | **Exemption certificate** | Tax exemption document | | **Customer tax type** | Tax classification | | **Withhold ISS** | ISS withholding flag | | **Withhold IRRF** | IRRF withholding flag | | **Withhold CSRF** | CSRF withholding flag | | **Withhold INSS** | INSS withholding flag | | **Municipal registration** | Municipal registration number | ## Status and Lifecycle[​](#status-and-lifecycle "Direct link to Status and Lifecycle") ``` active → suspended ↔ active ↓ closed ``` | Status | Description | | ------------- | -------------------------------------------------------------- | | **active** | Operational account | | **suspended** | Suspended due to delinquency or manually. Subscriptions paused | | **closed** | Permanently closed | ### Suspension[​](#suspension "Direct link to Suspension") * Sets `suspended_at` and `suspension_reason` * All active subscriptions are paused * Notification sent to the customer * Can be reactivated manually ### Closure[​](#closure "Direct link to Closure") * All subscriptions must be inactive/canceled * Permanent (soft delete via `deletedAt`) ## Uniqueness[​](#uniqueness "Direct link to Uniqueness") * One billing account per customer per organization * External ID unique per organization * Customer document unique per organization ## Statistics[​](#statistics "Direct link to Statistics") The dashboard displays counters by status: * Total accounts * Active accounts * Suspended accounts * Accounts with active subscription --- # Companies At `/dashboard/companies` the organization registers its **issuing legal entities** — the companies that sign contracts, invoices and NF-e. An organization can have several companies (headquarters, branches or different CNPJs from the same group) and set one as the default for billing. ## Registration data[​](#registration-data "Direct link to Registration data") Each company holds: * **Legal name and trade name** * **CNPJ** and municipal and state registrations * **Full address** (CEP, street, number, complement, neighborhood, city, state) * **Tax regime** — Simples Nacional, Lucro Presumido, Lucro Real, MEI * **Simples Nacional annex** (when applicable) and Factor R * **Fiscal contact** — email and phone for sending NF-e and fiscal communications * **Status** — active or deactivated ## Default company[​](#default-company "Direct link to Default company") One of the companies is marked as the default. Every new invoice or NF-e uses this company as the issuer, except when the customer, the plan or the subscription specifies another. Changing the default company does not change existing invoices or subscriptions. ## Multi-company[​](#multi-company "Direct link to Multi-company") Multi-company support lets a group operate separate CNPJs in the same dashboard: * **Catalog separated by company** — each company can have its own products, service items and tax rules. * **Isolated tax calculation** — tax periods and DAS are calculated per company. * **Invoices issued by the right company** — the customer sees the correct CNPJ on the invoice and the boleto. ## Deactivation[​](#deactivation "Direct link to Deactivation") Companies can be deactivated (not deleted) to stop receiving new invoices while keeping the fiscal history accessible. The action is recorded in the [Audit Log](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md). ## Screenshot — list[​](#screenshot--list "Direct link to Screenshot — list") ![List of registered companies with CNPJ and tax regime](/en/assets/images/empresas-1dae977686d5c568679df8e238a1d2ba.png) ## Screenshot — detail[​](#screenshot--detail "Direct link to Screenshot — detail") The detail page (`/dashboard/companies/[id]`) gathers fiscal data, contacts, address and the history of invoices and NF-e issued by the company. ![Company detail with fiscal data and invoice and NF-e tabs](/en/assets/images/empresa-detalhe-ef3c46708cfbaf118bd556264350e090.png) --- # Organizations Organizations are the platform's tenants. Each organization is a business that uses Automatic Billing to charge its own customers. ## Organization Fields[​](#organization-fields "Direct link to Organization Fields") | Field | Description | | ------------------- | ------------------------------------------- | | **External ID** | Unique identifier for external integrations | | **Name** | Organization name | | **Document type** | CPF or CNPJ | | **Document number** | CPF or CNPJ (normalized, digits only) | | **Email** | Primary contact email | | **Phone** | Contact phone number | | **Addresses** | List of addresses | | **Status** | `active` (default) | ## Automatic Bootstrap[​](#automatic-bootstrap "Direct link to Automatic Bootstrap") When creating an organization, the system automatically: 1. **Creates the default company** with the same registration data 2. **Creates the default dashboard roles** (owner, admin, viewer) 3. **Creates the owner user** with the organization's email ## Lifecycle[​](#lifecycle "Direct link to Lifecycle") * **Create**: Provide registration data, receive a ready organization with company and users * **Update**: Name, contact, and addresses are editable * **Delete**: Soft delete (only if there are no active billing accounts) ## Data Model[​](#data-model "Direct link to Data Model") The organization uses a **Person** (`Person` with `type=organization`) to store registration data. This allows organizations and customers to share the same flexible data model. --- # Customer Portal The customer portal allows end customers of each organization to manage their subscriptions, invoices, and payment methods autonomously. ## Access[​](#access "Direct link to Access") The portal is accessed via the organization's custom URL. Each organization configures its portal with branding, domain, and specific features. ## Portal Features[​](#portal-features "Direct link to Portal Features") * View and pay invoices * Manage subscriptions (pause, cancel, if allowed) * Update payment methods * View transaction history * Accept/reject commercial proposals ## Portal User (PortalUser)[​](#portal-user-portaluser "Direct link to Portal User (PortalUser)") | Field | Description | | ------------------- | ----------------------------- | | **Email** | Unique per billing account | | **Billing account** | Link to the financial account | | **SSO only** | If true, login only via SSO | | **Status** | User status | ### User Status[​](#user-status "Direct link to User Status") | Status | Description | | ---------------------- | ------------------------------------ | | `active` | Active user with full access | | `pending_verification` | Awaiting email verification (signup) | | `pending_invitation` | Awaiting invitation acceptance | | `suspended` | Account suspended | | `locked` | Locked due to failed login attempts | ### Security[​](#security "Direct link to Security") * Passwords hashed with bcrypt * Verification/reset tokens based on HMAC * Automatic lockout after failed login attempts * Verification tokens expire in 24 hours * Invitation tokens expire in 7 days ## Invitations[​](#invitations "Direct link to Invitations") The invitation system allows the organization to send email invitations: 1. The invitation is sent with a temporary token (7 days) 2. The recipient accepts and sets their password 3. Status changes to `active` 4. Pending invitations can be canceled or resent ## Self-Service Signup[​](#self-service-signup "Direct link to Self-Service Signup") Organizations can enable public signup: 1. The customer accesses the signup page via a unique slug 2. Enters CNPJ (validated against Receita Federal via minhareceita.org API) 3. Fills in company and administrator data 4. A verification email is sent 5. After verification, access is granted ### CNPJ Validation[​](#cnpj-validation "Direct link to CNPJ Validation") * CNPJ must have an "Active" registration status * CNPJ cannot already be registered in the organization * CNPJs with "Closed" status are blocked ## Portal Configuration[​](#portal-configuration "Direct link to Portal Configuration") | Setting | Description | | ----------------- | ------------------------------------------- | | **Company name** | Name displayed in the portal | | **Logo** | Light and dark logo | | **Colors** | Light and dark theme (HSL) | | **Languages** | Available languages (default: pt-BR, en-US) | | **Payments** | Enabled methods (card, boleto, PIX) | | **Subscriptions** | Allow pause/cancel | | **Invitations** | Enable invitations and allowed domains | | **Signup** | Slug and enable public signup | | **SSO** | Public key, algorithm, and issuer | ### SSO (Single Sign-On)[​](#sso-single-sign-on "Direct link to SSO (Single Sign-On)") The portal supports SSO via JWT: * Supported algorithms: RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384, PS512 * Configure PEM public key and issuer (iss claim) * SSO-only users do not need a password ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/portal` screen brings together the visual and functional configuration of the customer portal: logo, color palette for light and dark themes, supported languages, custom domain, invitation email text, enabled payment methods, authentication (magic link, OAuth, JWT SSO) and which areas the customer can view/edit. ![Visual and functional configuration of the customer portal](/en/assets/images/portal-do-cliente-b69700c76098b1b5098c475b296304e9.png) For the documentation of the screens seen by the end customer, see [Customer Portal](https://docs.billing.kobana.com.br/en/en/portal.md). --- ## [📄️Discount Codes](https://docs.billing.kobana.com.br/en/en/cupons-e-descontos/codigos-de-desconto/.md) [Discount codes are applied directly to subscriptions at the time of creation, offering recurring or one-time discounts.](https://docs.billing.kobana.com.br/en/en/cupons-e-descontos/codigos-de-desconto/.md) --- ## [📄️Discount Codes](https://docs.billing.kobana.com.br/en/en/cupons-e-descontos/codigos-de-desconto/.md) [Discount codes are applied directly to subscriptions at the time of creation, offering recurring or one-time discounts.](https://docs.billing.kobana.com.br/en/en/cupons-e-descontos/codigos-de-desconto/.md) --- # Discount Codes Discount codes are applied directly to subscriptions at the time of creation, offering recurring or one-time discounts. ## Fields[​](#fields "Direct link to Fields") | Field | Description | | ------------------------ | --------------------------------------------------- | | **Code** | Unique code, uppercase | | **Name** | Discount name | | **Description** | Discount details | | **Type** | `percentage` or `fixed_amount` | | **Fixed amount (cents)** | For `fixed_amount` type | | **Percentage** | For `percentage` type (max 100%) | | **Duration** | `once`, `repeating`, or `forever` | | **Duration in months** | For `repeating`, how many months the discount lasts | | **Maximum redemptions** | Total global uses allowed | | **Times redeemed** | Usage counter | | **Valid from / until** | Validity period | | **Status** | `active`, `expired`, or `depleted` | ## Discount Duration[​](#discount-duration "Direct link to Discount Duration") | Duration | Description | | ----------- | ----------------------------------------------------- | | `once` | Applied only to the first invoice | | `repeating` | Applied for N consecutive months | | `forever` | Applied indefinitely while the subscription is active | ## Restrictions[​](#restrictions "Direct link to Restrictions") | Restriction | Description | | ------------------ | ---------------------------------------- | | **Minimum amount** | Minimum subscription amount to use | | **First use only** | Valid only for new customers | | **Valid cycles** | Which billing cycles accept the discount | ## Application[​](#application "Direct link to Application") | Filter | Description | | ------------ | ------------------------------------------- | | **Products** | List of products where the discount applies | | **Plans** | List of plans where the discount applies | ## Status[​](#status "Direct link to Status") | Status | Description | | ---------- | --------------------------- | | `active` | Valid and usable | | `expired` | Outside the validity period | | `depleted` | Redemption limit reached | --- # Coupons Coupons are promotional codes that customers can redeem to get discounts on purchases and invoices. ## Coupon Fields[​](#coupon-fields "Direct link to Coupon Fields") | Field | Description | | ---------------------- | ---------------------------------------------------------- | | **Code** | Unique code, stored in uppercase | | **Name** | Internal coupon name | | **Description** | Promotion details | | **Discount type** | `percentage` or `fixed_amount` | | **Discount value** | Percentage (0–100) or amount in BRL, depending on the type | | **Currency** | Default: BRL | | **Minimum purchase** | Minimum order amount to use the coupon | | **Maximum discount** | Discount cap (for percentage coupons) | | **Total usage limit** | Maximum redemptions allowed | | **Per-customer limit** | Maximum redemptions per billing account | | **Valid from / until** | Validity period | | **Applies to** | Specific plans and/or products (JSON) | | **Excludes** | Excluded plans and/or products (JSON) | | **Active** | Whether the coupon is enabled | ## Coupon Validation[​](#coupon-validation "Direct link to Coupon Validation") When validating a coupon, the system checks: 1. The coupon exists and the code matches 2. The coupon is active (`isActive = true`) 3. It is within the validity period 4. The total usage limit has not been reached 5. The per-customer usage limit has not been reached 6. The purchase meets the minimum amount ### Discount Calculation[​](#discount-calculation "Direct link to Discount Calculation") ``` If percentage: discount = subtotal × percentage / 100 If fixed: discount = discount_value Apply cap: discount = min(discount, maxDiscountCents) Cannot exceed subtotal: discount = min(discount, subtotal) ``` ## Redeeming a Coupon[​](#redeeming-a-coupon "Direct link to Redeeming a Coupon") When applying a coupon: 1. Validates all conditions 2. Creates a `CouponRedemption` record with the discount amount 3. Increments the coupon's usage counter 4. Returns the redemption with the discounted amount The process is **atomic** (transaction) to prevent race conditions. ## Operations[​](#operations "Direct link to Operations") * **Activate/Deactivate**: Controls whether the coupon can be validated * **Delete**: Only if never used (no redemptions recorded) * **Update**: Code, name, limits, dates, and values are editable ## Redemption Report[​](#redemption-report "Direct link to Redemption Report") For each coupon, the system tracks: * Who redeemed it (billing account) * When it was redeemed * Discount amount applied * Associated invoice (optional) ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/coupons` screen lists all of the organization's coupons, with code, discount type, amount, validity, number of redemptions and status. The interface lets you create percentage or fixed-amount coupons, with a total limit and a per-customer limit. ![List of coupons with discount type, validity and redemptions](/en/assets/images/cupons-07be6d84515f69df5492b6bc403b0afe.png) --- # Docs MCP This documentation has **its own MCP server**. It lets an AI assistant (Claude, ChatGPT, Cursor, VS Code, Claude Code) search and read the pages of this site without you copying and pasting anything, so answers about Automatic Billing come from the published content, in the language you choose. ``` https://docs.billing.kobana.com.br/mcp ``` > **Not the product's MCP:** The Docs MCP only **reads the documentation**. It does not access your account, does not see customers, subscriptions or invoices, and changes nothing. For an agent to operate Automatic Billing, use the **product MCP** (`mcp.billing.kobana.com.br`), which requires sign-in and follows your permissions — see [MCP › Clients](https://docs.billing.kobana.com.br/en/en/mcp/overview/clients.md). ## How it works[​](#how-it-works "Direct link to How it works") * **Public and read-only:** no sign-in, no token. It exposes the same content anyone sees on the site. * **Always current:** it reads the published version of the documentation. A new or changed page shows up in the MCP as soon as the site is published. * **Three languages:** Portuguese (`pt`), English (`en`) and Spanish (`es`). Without a language, it uses Portuguese. * **Transport:** Streamable HTTP, sessionless. Any MCP client that connects to a remote server by URL works. ## Tools[​](#tools "Direct link to Tools") | Tool | What it does | Parameters | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | `search_docs` | Searches pages by keywords in the title, path and summary, ignoring accents and case. Returns the best pages with path and summary | `query` (required), `locale`, `limit` (1 to 25, default 8) | | `get_page` | Returns the full content of a page as Markdown | `path`: the path returned by `search_docs` or `list_pages` (e.g. `/en/assinaturas`) or the full URL | | `list_pages` | Lists every page, with path and summary | `locale` | The assistant decides on its own when to call each tool. It usually searches with `search_docs` and then reads the relevant pages with `get_page`. ## Installing[​](#installing "Direct link to Installing") The quickest way is the **Copy page** menu at the top of every page of this site. Under **Docs MCP** you'll find: * **Connect to Cursor** and **Connect to VS Code:** install the server in one click. * **Copy MCP config:** copies the JSON block for clients configured by file. * **Copy MCP command:** copies the install command for the terminal. If you'd rather configure it by hand, the steps for each client are below. ### Any client, from the terminal[​](#any-client-from-the-terminal "Direct link to Any client, from the terminal") [`add-mcp`](https://www.npmjs.com/package/add-mcp) detects the clients installed on your machine and adds the server to them: ``` npx add-mcp "https://docs.billing.kobana.com.br/mcp" ``` ### Claude Code[​](#claude-code "Direct link to Claude Code") ``` claude mcp add --transport http kobana-billing-docs https://docs.billing.kobana.com.br/mcp ``` ### Cursor[​](#cursor "Direct link to Cursor") Use **Connect to Cursor** in the page menu, or add this to `~/.cursor/mcp.json` (all projects) or the project's `.cursor/mcp.json`: ``` { "mcpServers": { "kobana-billing-docs": { "url": "https://docs.billing.kobana.com.br/mcp" } } } ``` ### VS Code[​](#vs-code "Direct link to VS Code") Use **Connect to VS Code** in the page menu, or create `.vscode/mcp.json` in the project. In VS Code the key is `servers`, not `mcpServers`: ``` { "servers": { "kobana-billing-docs": { "type": "http", "url": "https://docs.billing.kobana.com.br/mcp" } } } ``` ### Claude and ChatGPT[​](#claude-and-chatgpt "Direct link to Claude and ChatGPT") In **Settings › Connectors**, add a custom connector and paste the URL `https://docs.billing.kobana.com.br/mcp`. There is no sign-in. ### Other clients configured by file[​](#other-clients-configured-by-file "Direct link to Other clients configured by file") ``` { "mcpServers": { "kobana-billing-docs": { "type": "http", "url": "https://docs.billing.kobana.com.br/mcp" } } } ``` ## Example questions[​](#example-questions "Direct link to Example questions") With the server connected, just ask. The assistant checks the documentation before answering: * "How does proration work when a customer changes plans mid-cycle?" * "Which webhook events exist for invoices, and how do I verify the signature?" * "How do I set up NF-e issuance with a digital certificate?" * "Write an example API call to create a subscription, based on the documentation." ## Testing without a client[​](#testing-without-a-client "Direct link to Testing without a client") ``` curl -s https://docs.billing.kobana.com.br/mcp \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_docs","arguments":{"query":"webhook","locale":"en"}}}' ``` ## Limits[​](#limits "Direct link to Limits") * The per-endpoint API reference pages (`/api/v1/...`) are not in the MCP. The machine-readable source for the API is the OpenAPI spec, in [API › OpenAPI](https://docs.billing.kobana.com.br/en/en/api/overview/openapi.md). * Search is by keywords, not semantic. If nothing comes up, try other terms or ask the assistant to use `list_pages`. * You can also read any page as Markdown by appending `.md` to its URL, or download the whole documentation at [`llms-full.txt`](https://docs.billing.kobana.com.br/en/llms-full.txt). --- ## [📄️Exports](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/exportacoes/.md) [Export platform data in different formats for reports and integrations.](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/exportacoes/.md) --- ## [📄️Exports](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/exportacoes/.md) [Export platform data in different formats for reports and integrations.](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao/exportacoes/.md) --- # Exports Export platform data in different formats for reports and integrations. ## Exportable Resources[​](#exportable-resources "Direct link to Exportable Resources") | Resource | Description | | ---------------- | ---------------------------------- | | `products` | Product catalog with prices | | `customers` | List of customers/billing accounts | | `invoices` | Invoices with line items | | `subscriptions` | Active subscriptions | | `plans` | Plan definitions | | `service_items` | Service items (fiscal) | | `coupons` | Coupon codes | | `product_groups` | Product groups | ## Supported Formats[​](#supported-formats "Direct link to Supported Formats") | Format | Description | | ------ | -------------------------------- | | `csv` | Comma-separated values (default) | | `xlsx` | Excel spreadsheet | | `json` | Structured JSON | ## Export Status[​](#export-status "Direct link to Export Status") | Status | Description | | ------------ | ----------------------- | | `pending` | Queued for processing | | `processing` | Being processed | | `completed` | Ready for download | | `failed` | Error during processing | ## Flow[​](#flow "Direct link to Flow") 1. Create an export specifying the resource type and format 2. The job is queued for asynchronous processing 3. The worker fetches the data, applies filters, and generates the file 4. The file is stored in S3 with a validity of **7 days** 5. The export is updated with the download URL ## Export Fields[​](#export-fields "Direct link to Export Fields") | Field | Description | | ----------------- | ----------------------- | | **Resource type** | What to export | | **Format** | CSV, XLSX, or JSON | | **Status** | Processing state | | **File name** | Automatically generated | | **File URL** | Download link | | **Size** | Size in bytes | | **Total rows** | Exported records | | **Filters** | Applied filters | | **Expires at** | 7 days after completion | ## Automatic Cleanup[​](#automatic-cleanup "Direct link to Automatic Cleanup") Expired exports are automatically removed (S3 file + database record). --- # Imports Import data in bulk to the platform via file upload. ## Importable Resources[​](#importable-resources "Direct link to Importable Resources") The same resources supported in exports: products, customers, invoices, subscriptions, plans, service items, coupons, and product groups. ## Import Status[​](#import-status "Direct link to Import Status") | Status | Description | | ----------------------- | ------------------------------------ | | `pending` | Queued | | `processing` | Being processed | | `completed` | Success, no errors | | `completed_with_errors` | Partial success, some records failed | | `failed` | Critical error, processing aborted | ## Flow[​](#flow "Direct link to Flow") 1. Upload the file (CSV, XLSX, or JSON) 2. The file is stored in S3 3. The job is queued for asynchronous processing 4. The worker reads the file, validates each row, and creates/updates records 5. Errors are tracked per row 6. The import is updated with the result ## Progress Tracking[​](#progress-tracking "Direct link to Progress Tracking") | Field | Description | | ------------------ | ----------------------------- | | **Total rows** | Total in the file | | **Processed rows** | Current progress | | **Success** | Successfully imported records | | **Errors** | Failed records | | **Error details** | Row and reason for each error | ## Error Example[​](#error-example "Direct link to Error Example") ``` [ { "row": 5, "error": "Invalid product name" }, { "row": 12, "error": "Duplicate CNPJ" } ] ``` --- ## [📄️Credits](https://docs.billing.kobana.com.br/en/en/faturas-e-pagamentos/creditos/.md) [The credit system allows adding balance to a customer's account that is automatically applied to future invoices.](https://docs.billing.kobana.com.br/en/en/faturas-e-pagamentos/creditos/.md) --- ## [📄️Credits](https://docs.billing.kobana.com.br/en/en/faturas-e-pagamentos/creditos/.md) [The credit system allows adding balance to a customer's account that is automatically applied to future invoices.](https://docs.billing.kobana.com.br/en/en/faturas-e-pagamentos/creditos/.md) --- # Credits The credit system allows adding balance to a customer's account that is automatically applied to future invoices. ## Credit Types[​](#credit-types "Direct link to Credit Types") | Type | Description | | ------------- | ---------------------------------- | | `promotional` | Promotional credits (may expire) | | `adjustment` | Administrative balance adjustments | | `refund` | Credit generated from a refund | | `manual` | Manual credit addition | ## Credit Fields[​](#credit-fields "Direct link to Credit Fields") | Field | Description | | -------------------- | ----------------------------------------- | | **Billing account** | Customer receiving the credit | | **Company** | Issuing company (for application scoping) | | **Type** | Credit type | | **Amount (cents)** | Total credit amount | | **Amount remaining** | Unused balance | | **Description** | Reason or description of the credit | | **Expires at** | Expiration date (null = never expires) | ## Automatic Credit Application[​](#automatic-credit-application "Direct link to Automatic Credit Application") When an invoice is **finalized**, the system automatically applies credits using the **FIFO** strategy: ### Application Order[​](#application-order "Direct link to Application Order") 1. Credits expiring soonest (priority to avoid loss) 2. Oldest credits (when expiration dates are equal) ### Company Scoping Rules[​](#company-scoping-rules "Direct link to Company Scoping Rules") * If the invoice has a company: applies credits from the same company **and** credits without a company * If the invoice has no company: applies only credits without a company ### Process (in atomic transaction)[​](#process-in-atomic-transaction "Direct link to Process (in atomic transaction)") 1. Fetches unexpired credits with available balance 2. For each credit: applies the minimum of (credit balance, invoice remaining amount) 3. Creates a `CreditApplication` record for traceability 4. Updates the credit and invoice balances 5. If the invoice is fully paid: marks it as `paid` 6. Updates the billing account's `balance` ## Credit Restoration[​](#credit-restoration "Direct link to Credit Restoration") When an invoice is **voided**, all applied credits are restored: * Each credit has its remaining balance increased * The `CreditApplication` records are removed * The invoice returns to `open` status * The billing account balance is updated ## Credit Expiration[​](#credit-expiration "Direct link to Credit Expiration") Credits with an expiration date are automatically zeroed out when the date passes: * The `amount_remaining` is set to 0 * The billing account balance is reduced ## Operations[​](#operations "Direct link to Operations") * **Add credit**: Creates a credit and increments the account balance * **Adjust balance**: Adds or subtracts credits * **Refund credit**: Creates a credit of type `refund` * **Promotional credit**: Creates a credit with optional expiration * **Delete credit**: Only if never used (remaining balance = total amount) * **Check available balance**: Returns total available, active credits, and expiring credits ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/credits` screen lists all of the organization's credits, with filters by status, origin (downgrade, refund, manual adjustment, promotion), billing account and period. The interface also lets you create one-off credits and see the aggregated balance per customer. ![List of credits with origin, balance and applications](/en/assets/images/creditos-55db71fde4995c0ffd5529bc1cc5457e.png) --- # Invoices Invoices represent charges sent to customers. Each invoice contains line items detailing the products and amounts charged. ## Invoice Statuses[​](#invoice-statuses "Direct link to Invoice Statuses") ``` draft → open → paid ↓ ↓ void uncollectible ``` | Status | Description | | ----------------- | -------------------------------------------------------------------- | | **draft** | Draft. Can be edited, items can be added/removed | | **open** | Finalized. Chargeable, can receive payments and have credits applied | | **paid** | Fully paid | | **void** | Voided. Applied credits are restored, installments canceled | | **uncollectible** | Marked as uncollectible (write-off) | ## Invoice Fields[​](#invoice-fields "Direct link to Invoice Fields") ### Identification[​](#identification "Direct link to Identification") | Field | Description | | ------------------- | -------------------------------------------------- | | **Number** | Unique sequential number (format: INV-YYYY-NNNNNN) | | **Billing account** | Customer who will receive the invoice | | **Subscription** | Associated subscription (optional) | | **Company** | Issuing company (for multi-company setups) | ### Amounts (in BRL)[​](#amounts-in-brl "Direct link to Amounts (in BRL)") | Field | Description | | -------------------- | -------------------------------------------- | | **Subtotal** | Sum of line items before discounts and taxes | | **Discount** | Total discount applied | | **Taxes** | Total taxes calculated | | **Total withheld** | Withheld taxes (PIS/COFINS/IRPJ) | | **Net amount** | Net amount after withholdings | | **Total** | Final amount (subtotal - discount + taxes) | | **Amount due** | Total amount payable | | **Amount paid** | Amount already received | | **Amount remaining** | Outstanding balance | ### Configuration[​](#configuration "Direct link to Configuration") | Field | Description | | --------------------- | ------------------------------------------------------------------------------- | | **Collection method** | `charge_automatically`, `manual_charge`, or `manual_invoice` | | **Billing reason** | `subscription_cycle`, `subscription_create`, `subscription_update`, or `manual` | | **NF-e policy** | `disabled`, `on_finalization`, `on_full_payment`, or `per_installment` | | **Due date** | Calculated from the customer's payment term days | ## Line Items[​](#line-items "Direct link to Line Items") Each invoice contains line items that detail the charges: | Field | Description | | ---------------- | ------------------------------------- | | **Type** | `subscription` or `invoiceitem` | | **Description** | Descriptive text | | **Quantity** | Quantity charged | | **Unit amount** | Price per unit | | **Total amount** | Quantity × unit amount | | **Proration** | Whether the item is a prorated charge | | **Period** | Start and end of the billed period | ## Operations[​](#operations "Direct link to Operations") ### Create Invoice[​](#create-invoice "Direct link to Create Invoice") When creating an invoice, provide: * Billing account (required) * Line items with description, quantity, and amount * Due date (or uses the customer's payment term days) * Installments (optional, minimum 2, sum must equal the total) * NF-e policy (optional) The invoice number is automatically generated using PostgreSQL advisory locks to prevent duplication. ### Edit Invoice[​](#edit-invoice "Direct link to Edit Invoice") `draft` and `open` invoices accept edits to every field. Once settled — `paid`, `void` or `uncollectible` — an invoice keeps its terms locked: | Status | Editable fields | | --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | **draft**, **open** | All | | **paid** | Public ID, subscription, description, line items, metadata, external ID, NF-e issuance policy and NF-e description line | | **void**, **uncollectible** | Public ID, subscription, description, line items, metadata and external ID | Company, collection method, late-fee policy, due date, billing period and footer are locked. Line items can be corrected (through the API or with inline editing on the items tab, after a warning), but not while the invoice has an issued or in-flight NF-e — cancel it first. The rule applies to the dashboard, the API and MCP alike: changing a locked field returns `422` with code `INVOICE_FIELD_LOCKED`, listing the refused fields. Sending a locked field with the value already stored is not a change. ### Finalize (`draft` → `open`)[​](#finalize-draft--open "Direct link to finalize-draft--open") When finalizing an invoice: 1. Validates that at least 1 line item exists 2. Validates that the sum of installments = total (if installment-based) 3. Calculates taxes automatically 4. **Applies credits automatically** (FIFO: earliest expiration first, then oldest) 5. If collection method is `charge_automatically`: attempts to charge immediately ### Mark as Paid[​](#mark-as-paid "Direct link to Mark as Paid") * Supports partial payments * When the full amount is received, the status changes to `paid` * Creates a transaction record ### Void[​](#void "Direct link to Void") When voiding an invoice: * Applied credits are automatically restored * Pending installments are canceled * The void reason is stored ### Undo Payment[​](#undo-payment "Direct link to Undo Payment") Reverts an invoice from `paid` to `open`: * Resets the paid amount to zero * Creates an adjustment transaction (negative amount) * Stores the reason in metadata ### Mark as Uncollectible[​](#mark-as-uncollectible "Direct link to Mark as Uncollectible") Marks the invoice as a write-off. Irreversible. No automatic payment attempts will be made. ## Automatic Number Generation[​](#automatic-number-generation "Direct link to Automatic Number Generation") Invoice numbers are generated sequentially per year using PostgreSQL advisory locks. Format: `INV-{year}-{6-digit sequence}`. Example: `INV-2026-000147` ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Invoice list[​](#invoice-list "Direct link to Invoice list") The `/dashboard/invoices` screen lists all invoices with filters by status, billing account, issuing company, period and payment method. Each row shows number, customer, amount, due date, status and quick actions (download PDF, copy boleto/PIX, mark as paid). ![Dashboard invoice list with filters and actions](/en/assets/images/faturas-072282bf988927aee0a60b30e065ec0e.png) ### Invoice detail[​](#invoice-detail "Direct link to Invoice detail") The `/dashboard/invoices/[id]` page shows the complete invoice: items (with quantity and unit price), totals, discounts, credits applied, taxes withheld, payment history, linked NF-e and event timeline. ![Invoice detail with items, totals and history](/en/assets/images/fatura-detalhe-1be83a58d6fc5d03118a7e48092fe0be.png) --- # Payment Methods Each billing account can have multiple stored payment methods. One of them is marked as the **default** for automatic charges. ## Supported Types[​](#supported-types "Direct link to Supported Types") | Type | Description | Automatic Charge | | ------------------ | ---------------------- | ---------------- | | **card** | Credit/debit card | Yes | | **bank\_slip** | Boleto bancario | No | | **pix** | PIX (instant transfer) | No | | **bank\_transfer** | Bank transfer | No | > **Note**: Only credit card supports automatic charging (`charge_automatically`). ## Credit Card[​](#credit-card "Direct link to Credit Card") ### Stored Data[​](#stored-data "Direct link to Stored Data") * Brand (Visa, Mastercard, Elo, Amex, Hipercard) * First 6 digits (BIN) * Last 4 digits * Cardholder name * Expiration month and year * Fingerprint (unique card identifier at the gateway) ### Tokenization[​](#tokenization "Direct link to Tokenization") The card is tokenized on the client side via the gateway SDK and stored securely: 1. Customer submits card data through the gateway form 2. Gateway returns a temporary card token (sent to the API as `card_token`) 3. The server uses the token to create the customer and card at the gateway (Pagar.me) 4. Only gateway tokens and masked data are stored ### Expiration Monitoring[​](#expiration-monitoring "Direct link to Expiration Monitoring") The system automatically checks for cards expiring within the next 30 days and can send proactive notifications to the customer. ## Boleto (`bank_slip`)[​](#boleto-bank_slip "Direct link to boleto-bank_slip") * Generated for each individual charge * Includes barcode and URL for PDF download * Configurable payment deadline (default: 3 days) * Confirmation via gateway webhook when paid ## PIX[​](#pix "Direct link to PIX") * QR Code generated for each charge * EMV format with PNG/base64 image * Default expiration: 30 minutes * Real-time confirmation via webhook ## Bank Transfer (`bank_transfer`)[​](#bank-transfer-bank_transfer "Direct link to bank-transfer-bank_transfer") Stored data: * Bank code, bank name * Branch and account number * Type: checking or savings * Account holder name and document Confirmation is manual — the operator must verify receipt. ## Default Method[​](#default-method "Direct link to Default Method") * Each billing account has **one** default method * The first method created is automatically set as default * When the default method is removed, the next active method is promoted ## Removal[​](#removal "Direct link to Removal") When removing a payment method: * Validates that there are no pending/processing payments with this method * For cards: deletes the card from the gateway * If it was the default: reassigns to another active method * Status changes to `removed` --- # Payments Payments represent charge attempts associated with invoices. Each payment tracks the status, method, gateway used, and provider response. ## Payment Statuses[​](#payment-statuses "Direct link to Payment Statuses") ``` pending → processing → succeeded → refunded ↓ ↓ failed partially_refunded ↓ canceled ``` | Status | Description | | ----------------------- | ---------------------------------- | | **pending** | Awaiting processing | | **processing** | Sent to gateway, awaiting response | | **succeeded** | Confirmed as paid | | **failed** | Declined by gateway or error | | **canceled** | Manually canceled | | **partial** | Partial payment received | | **refunded** | Fully refunded | | **partially\_refunded** | Partially refunded | ## Payment Flow[​](#payment-flow "Direct link to Payment Flow") ### 1. Automatic Charge (`charge_automatically`)[​](#1-automatic-charge-charge_automatically "Direct link to 1-automatic-charge-charge_automatically") ``` Invoice finalized → Applies credits automatically → If credits cover everything: invoice = paid → If not: → Gets default payment method → Processes payment via gateway → Card: immediate response → Boleto/PIX: awaits gateway webhook → Success: invoice = paid → Failure: schedules retry (dunning) ``` ### 2. Manual Payment[​](#2-manual-payment "Direct link to 2. Manual Payment") The operator or customer initiates payment via the dashboard or portal. ## Processing a Payment[​](#processing-a-payment "Direct link to Processing a Payment") When processing, the system: 1. Validates that the invoice is `open` 2. Determines the payment method (provided, saved, or default) 3. Gets the organization's gateway for the payment type 4. Creates a payment record with an idempotency key 5. Sends the charge to the gateway 6. Updates the payment with the response ### Idempotency[​](#idempotency "Direct link to Idempotency") Each payment has a unique idempotency key. Duplicate requests return the existing result without reprocessing. ## Special Scenarios[​](#special-scenarios "Direct link to Special Scenarios") ### Partial Payment[​](#partial-payment "Direct link to Partial Payment") * The received amount is less than the total * The invoice remains `open` with the balance updated * The customer can pay the remaining amount with another payment ### Overpayment[​](#overpayment "Direct link to Overpayment") When the paid amount exceeds the invoice balance: 1. The invoice amount is applied normally 2. The **surplus becomes a credit** automatically on the customer's account 3. The credit is of type `adjustment` with description "Overpayment credit on invoice {number}" 4. The credit will be automatically applied to future invoices ### Already Paid Invoice[​](#already-paid-invoice "Direct link to Already Paid Invoice") If the invoice was already paid when the payment is processed, the full amount becomes a credit on the customer's account. ## Operations[​](#operations "Direct link to Operations") ### Cancel Payment[​](#cancel-payment "Direct link to Cancel Payment") Only `pending` payments can be canceled. For boleto/PIX, the cancellation is sent to the gateway. ### Refund[​](#refund "Direct link to Refund") `succeeded` or `partially_refunded` payments can be refunded: * **Full refund**: Status changes to `refunded` * **Partial refund**: Status changes to `partially_refunded` * The request is sent to the gateway when available ### Retry[​](#retry "Direct link to Retry") `failed` payments can be retried. A new payment is created with the same amount, invoice, and method. ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Payment list[​](#payment-list "Direct link to Payment list") The `/dashboard/payments` screen aggregates all payments received, with filters by status, method, gateway, customer and period. Each row shows the related invoice, amount, gateway fee, net amount and response message. ![List of payments with filters by gateway and method](/en/assets/images/pagamentos-6df77e13129e7fa17e309a5690eea57f.png) ### Payment detail[​](#payment-detail "Direct link to Payment detail") The `/dashboard/payments/[id]` page shows the complete record: gateway, transaction at the provider, settled invoice, method (with the card's last 4 digits or the boleto's bank), attempt history, refunds and webhooks received. ![Payment detail with gateway, method and history](/en/assets/images/pagamento-detalhe-4ee0f9e428bb71ee80e7bbcfde240798.png) --- # Installments Invoices can be split into multiple installments with individual due dates. ## Installment Statuses[​](#installment-statuses "Direct link to Installment Statuses") ``` scheduled → pending → paid ↓ overdue ↓ canceled ``` | Status | Description | | ------------- | ------------------------------------ | | **scheduled** | Future due date, awaiting processing | | **pending** | Due date reached, awaiting payment | | **paid** | Installment paid | | **overdue** | Past due and unpaid | | **canceled** | Canceled (invoice voided) | ## Creating Installments[​](#creating-installments "Direct link to Creating Installments") When creating or editing an invoice, provide the installments: | Field | Description | | ------------------ | --------------------- | | **Amount (cents)** | Installment amount | | **Due date** | Expected payment date | ### Validation Rules[​](#validation-rules "Direct link to Validation Rules") * Minimum of **2 installments** * Dates must be **strictly ascending** * The sum of amounts must **equal the invoice total** * The invoice due date is set to the date of the last installment ## Installment Billing[​](#installment-billing "Direct link to Installment Billing") ### Sequential Processing[​](#sequential-processing "Direct link to Sequential Processing") Installments are processed sequentially — each installment is only charged when the previous one is paid: 1. The worker finds installments with due date ≤ today 2. Checks if the previous installment is paid (or if it's the first one) 3. For `charge_automatically`: charges the default payment method 4. Links the payment to the installment 5. If it's the last installment: invoice is marked as `paid` ### Per-Installment NF-e Policy[​](#per-installment-nf-e-policy "Direct link to Per-Installment NF-e Policy") When the NF-e policy is `per_installment`, a fiscal invoice (NF-e) is issued for each individually paid installment. ## Cancellation[​](#cancellation "Direct link to Cancellation") When the invoice is voided: * All installments with status `scheduled` or `pending` are canceled * Already paid installments are not affected --- ## [📄️Callbacks (Provider Webhooks)](https://docs.billing.kobana.com.br/en/en/gateways-de-pagamento/callbacks/.md) [Payment gateway providers send notifications to the system when payment statuses change. These notifications are processed asynchronously.](https://docs.billing.kobana.com.br/en/en/gateways-de-pagamento/callbacks/.md) --- ## [📄️Callbacks (Provider Webhooks)](https://docs.billing.kobana.com.br/en/en/gateways-de-pagamento/callbacks/.md) [Payment gateway providers send notifications to the system when payment statuses change. These notifications are processed asynchronously.](https://docs.billing.kobana.com.br/en/en/gateways-de-pagamento/callbacks/.md) --- # Callbacks (Provider Webhooks) Payment gateway providers send notifications to the system when payment statuses change. These notifications are processed asynchronously. ## Callback Endpoints[​](#callback-endpoints "Direct link to Callback Endpoints") ### Kobana[​](#kobana "Direct link to Kobana") ``` POST /api/callbacks/kobana ``` **Signature Header:** `X-Kobana-Signature: sha256=` **Received events:** * `pix.register.confirmed` / `error` / `failed` / `requested` * `pix.paid` * `bank_billet.register.confirmed` / `error` / `failed` / `requested` * `bank_billet.paid` ### Pagar.me[​](#pagarme "Direct link to Pagar.me") ``` POST /api/callbacks/pagarme ``` **Signature Header:** `x-hub-signature: sha256=` **Received events:** * `order.*` (paid, payment\_failed, created, canceled, closed, updated) * `charge.*` (paid, payment\_failed, refunded, pending, processing, etc.) * `card.*` (created, updated, deleted, expired) ## Processing Flow[​](#processing-flow "Direct link to Processing Flow") ``` Receives POST from provider → Validates HMAC-SHA256 signature → Checks idempotency key (ignores duplicates) → Creates Callback record (status=pending) → Enqueues job for async processing → Returns 200 immediately ``` ### Async Processing[​](#async-processing "Direct link to Async Processing") ``` Worker processes the queue → Routes to provider handler → Maps provider status to internal status → Updates payment record → Creates event for notification → Updates Callback (status=completed) ``` ## Security[​](#security "Direct link to Security") * **Signature validation**: HMAC-SHA256 with timing-safe comparison * **Idempotency**: Unique key `[provider, idempotencyKey]` prevents duplication * **Retries**: Maximum of 5 attempts with exponential backoff * **Retention**: Failed callbacks kept for 7 days ## Callback Record[​](#callback-record "Direct link to Callback Record") Each received callback is recorded with: * Source provider * Idempotency key * Complete headers and payload * Processing status * Number of attempts * Result or error message --- # Gateway Configuration Each organization can configure multiple gateways and set defaults per payment method. ## Gateway Fields[​](#gateway-fields "Direct link to Gateway Fields") | Field | Description | | ---------------------- | --------------------------------------------------- | | **Provider** | MOCK, KOBANA, or PAGARME | | **Name** | Display name | | **Environment** | SANDBOX or PRODUCTION | | **Active** | Whether the gateway is enabled | | **Credentials** | Provider-specific settings (encrypted) | | **Default for card** | Whether it is the default gateway for card payments | | **Default for boleto** | Whether it is the default gateway for boleto | | **Default for PIX** | Whether it is the default gateway for PIX | ## Default Gateway[​](#default-gateway "Direct link to Default Gateway") Each organization defines **one default gateway per payment method**: * One default gateway for card * One default gateway for boleto * One default gateway for PIX When setting a gateway as default, the previous default is automatically unset. The system uses transactions to ensure consistency. ## Operations[​](#operations "Direct link to Operations") ### Create Gateway[​](#create-gateway "Direct link to Create Gateway") 1. Select the provider 2. Enter the credentials 3. Choose the environment (sandbox/production) 4. Define whether it will be the default for any method **Kobana**: Requires OAuth authorization before activation **Pagar.me**: Requires a connection test before activation **Mock**: Activated automatically ### Update Gateway[​](#update-gateway "Direct link to Update Gateway") Update name, credentials, status, or default configuration. Masked values are filtered to prevent accidental overwriting. ### Delete Gateway[​](#delete-gateway "Direct link to Delete Gateway") Only if there are no associated payments. ## Monitoring[​](#monitoring "Direct link to Monitoring") For each gateway, the system tracks: * Total gateways (active/inactive) * Count by provider * Payments processed per gateway * Consecutive delivery failures --- # Gateway Providers The system supports three payment providers, each with specific capabilities. ## Available Providers[​](#available-providers "Direct link to Available Providers") ### Pagar.me (`PAGARME`)[​](#pagarme-pagarme "Direct link to pagarme-pagarme") * **Purpose**: Credit card processing * **Supported methods**: Credit card only * **API**: Pagar.me v5 () * **Environment**: Sandbox and Production **Required credentials:** | Field | Required | Description | | ------------ | -------- | --------------------------- | | `secretKey` | Yes | API secret key | | `publicKey` | No | Public key for tokenization | | `merchantId` | No | Merchant ID | | `accountId` | No | Account ID | **Features:** * Card tokenization (client → token → gateway) * Authorization and capture * Full and partial refunds * Customer and card management on the gateway ### Kobana (`KOBANA`)[​](#kobana-kobana "Direct link to kobana-kobana") * **Purpose**: Brazilian payment methods * **Supported methods**: Boleto and PIX * **Environment**: Sandbox and Production **Required credentials:** | Field | Required | Description | | ----------------- | -------- | ---------------------------------- | | `accessToken` | Yes | API access token | | `billetAccountId` | No | Boleto account ID | | `pixAccountUid` | No | PIX account UID (required for PIX) | | `webhookSecret` | No | Secret for webhook validation | **Features:** * Boleto issuance with barcode and PDF * PIX QR Code generation (EMV) * Charge cancellation * Webhooks for payment confirmation ### Mock (`MOCK`)[​](#mock-mock "Direct link to mock-mock") * **Purpose**: Development and testing * **Supported methods**: Card, Boleto, and PIX * **Credentials**: None required * **Activation**: Automatic upon creation Simulates all payment types for the development environment. ## Payment Methods by Provider[​](#payment-methods-by-provider "Direct link to Payment Methods by Provider") | Method | Pagar.me | Kobana | Mock | | ------------- | -------- | ------ | ---- | | Credit card | Yes | - | Yes | | Boleto | - | Yes | Yes | | PIX | - | Yes | Yes | | Bank transfer | - | - | - | ## Credential Security[​](#credential-security "Direct link to Credential Security") * All credentials are **encrypted** at rest using AES-256-GCM * Credentials are decrypted only at the time of the API call * API responses mask credentials (format: `****[last 4]`) * Sensitive fields are filtered from logs --- ## [📄️Dunning Configuration](https://docs.billing.kobana.com.br/en/en/gestao-de-inadimplencia/configuracao-de-dunning/.md) [The dunning configuration defines how the system handles overdue payments: how many attempts, the interval between them, and the behavior after exhaustion.](https://docs.billing.kobana.com.br/en/en/gestao-de-inadimplencia/configuracao-de-dunning/.md) --- ## [📄️Dunning Configuration](https://docs.billing.kobana.com.br/en/en/gestao-de-inadimplencia/configuracao-de-dunning/.md) [The dunning configuration defines how the system handles overdue payments: how many attempts, the interval between them, and the behavior after exhaustion.](https://docs.billing.kobana.com.br/en/en/gestao-de-inadimplencia/configuracao-de-dunning/.md) --- # Dunning Configuration The dunning configuration defines how the system handles overdue payments: how many attempts, the interval between them, and the behavior after exhaustion. ## Configuration Fields[​](#configuration-fields "Direct link to Configuration Fields") | Field | Default | Range | Description | | ------------------------------------ | --------------------- | ----- | ---------------------------------------------------------- | | **Maximum attempts** | 3 | 1-10 | Total attempts allowed | | **Interval between attempts (days)** | \[2, 5, 7] | - | Days to wait between each attempt | | **Grace period (days)** | 3 | 1-90 | Days before suspension | | **Automatic retry** | Yes | - | Whether attempts are triggered automatically | | **Suspend after attempts** | Yes | - | Whether the account is suspended after exhausting attempts | | **Payment methods for retry** | pix, bank\_slip, card | - | Which methods to use for retry attempts | ## Configuration Hierarchy[​](#configuration-hierarchy "Direct link to Configuration Hierarchy") 1. **Organization configuration**: Each organization can customize its rules 2. **Global default configuration**: Used when the organization has no custom config 3. **System defaults**: Hardcoded values as final fallback ## Timeline Example[​](#timeline-example "Direct link to Timeline Example") With the default configuration (attempts: \[2, 5, 7], grace period: 3 days): ``` Day 0: Invoice becomes due Day 2: 1st retry attempt Day 5: 2nd retry attempt (if 1st failed) Day 7: 3rd retry attempt (if 2nd failed) Day 10: Grace period ends → account suspended ``` ## Dunning Stages[​](#dunning-stages "Direct link to Dunning Stages") The delinquent account progresses through the following stages: | Stage | Days overdue | Description | | ----------- | ------------------ | --------------------------- | | `initial` | 1-7 days | Recent delinquency | | `reminder` | 8-15 days | Reminders sent | | `warning` | 16-30 days | Imminent suspension warning | | `final` | 30+ days | Last chance before action | | `suspended` | After grace period | Account suspended | ## Management[​](#management "Direct link to Management") ### Pause Dunning[​](#pause-dunning "Direct link to Pause Dunning") Use "Stop Dunning" to temporarily suspend communications while keeping the invoice as past-due. ### Cancel Attempts[​](#cancel-attempts "Direct link to Cancel Attempts") Cancels all pending attempts for a specific invoice and clears the next retry date. ### Manual Retry[​](#manual-retry "Direct link to Manual Retry") The operator can trigger a manual retry at any time, regardless of the automatic schedule. --- # Late Fees An overdue invoice can accrue a **fine** (charged once) and **interest** (accruing per day of delay). A late fee policy defines both, applies organization-wide, and can be overridden per customer, per subscription or per invoice. Every organization starts with a policy that **charges nothing**. Turning charges on is an explicit commercial decision, because it changes what your customers owe. ## Where to configure it[​](#where-to-configure-it "Direct link to Where to configure it") `Settings` → **Late fees** tab. The screen lists the policies and offers a live simulation: as you edit the values you see the effect on a R$ 1,000.00 invoice fifteen days overdue, before applying the rule to real customers. ## Fields[​](#fields "Direct link to Fields") ### Fine[​](#fine "Direct link to Fine") | Field | Description | | --------------------------- | ------------------------------------------------------------------------ | | **Fine type** | `No charge`, `Percentage of the balance` or `Flat amount` | | **Percentage / Amount** | Only the field the chosen type uses is shown | | **Days after the due date** | When the fine starts applying. Default is 1 — the day after the due date | The fine is charged **once**, not per day. ### Interest[​](#interest "Direct link to Interest") | Field | Description | | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | | **Interest type** | `No charge`, a percentage per day, per month or per year, or a flat amount per day | | **Percentage / Amount per day** | Only the field the chosen type uses is shown | | **Days after the due date** | When interest starts accruing. Default is 1 | | **Day count** | Calendar days or business days. Business days come from the [Holidays](https://docs.billing.kobana.com.br/en/en/configuracoes/feriados.md) registry | A monthly rate is divided *pro rata die* by 30, and a yearly one by 360 — the basis the bank instruction uses. 1% per month on R$ 1,000.00 yields R$ 0.33 per day of delay. Interest accrues **on the outstanding balance**, never on the balance plus the fine. ### Ceilings[​](#ceilings "Direct link to Ceilings") | Field | Description | | ------------------------------ | ---------------------------------------------------------------------------------------------- | | **Maximum months of interest** | Stops the accrual. Empty = uncapped | | **Total charge ceiling** | A percentage of the balance. When it bites, the fine is kept whole and the interest is trimmed | | **Respect the legal ceilings** | Refuses a fine above 2% and interest above 1% per month | The legal ceiling comes from art. 52 of the Brazilian Consumer Code and applies to **consumer relations**. Business-to-business contracts may agree above it, which is why the guard can be turned off — the decision is recorded in the audit log, separately from an ordinary policy change. ### Behaviour[​](#behaviour "Direct link to Behaviour") | Field | Description | | ------------------------------------------- | -------------------------------------------------------------------------- | | **A partial payment pays down** | `Fine and interest` (default) or `The invoice amount` | | **Register the instruction with the bank** | The bank slip or Pix collects the charges itself after the due date | | **Recompute on card charges and re-issues** | A card has no bank instruction, so the charge goes into the amount charged | | **Instructions printed on the bank slip** | Free text | The `Fine and interest` default follows art. 354 of the Brazilian Civil Code: a partial payment goes first to interest, then to the fine, and only the remainder reduces the invoice amount. That way the debt does not quietly stop accruing. ## Which policy applies to an invoice[​](#which-policy-applies-to-an-invoice "Direct link to Which policy applies to an invoice") Resolution is a cascade, and the first level that names a policy wins: ``` Invoice → Subscription → Billing account → Organization default ``` A blank level means **inherit**, never "no charge". Charging nothing is an explicit policy, with both types set to `No charge`. ### Invoices already issued do not move[​](#invoices-already-issued-do-not-move "Direct link to Invoices already issued do not move") At finalization the invoice **freezes** the policy in force at that moment. If you renegotiate the policy in March, invoices issued in January keep charging January's rules — both in the calculation and in the instruction registered with the bank. ## How the charge is collected[​](#how-the-charge-is-collected "Direct link to How the charge is collected") | Method | How it works | | ------------- | ------------------------------------------------------------------------------------------------------------------ | | **Bank slip** | The fine and interest instruction is registered with the bank, which computes and collects the extra at settlement | | **Pix** | Registered as a Pix Charge (Pix Cobrança), with the same logic. An instant Pix cannot carry charges | | **Card** | There is no bank instruction: the amount charged is recomputed at the moment of the attempt | When re-issuing a bank slip for an overdue invoice, the **original due date is preserved**. Re-dating the slip to today would reset the delay and waive the charge the customer already owes. :::caution Business days depend on the holiday registry With business-day counting and an empty holiday list, the calculation skips only weekends — the bank skips the holidays too and will collect less than we accrue. Import the national holidays in `System` → [Holidays](https://docs.billing.kobana.com.br/en/en/configuracoes/feriados.md) before turning this on. ::: :::note Banks and the monthly percentage On a bank slip, the "percentage per month" type is supported by Bradesco, BB, BTG, Caixa, Inter, Itaú, Safra, Santander, Sicoob and Sicredi. On other banks, prefer the daily percentage. ::: ## What happens when the customer pays[​](#what-happens-when-the-customer-pays "Direct link to What happens when the customer pays") The settled amount is split into three parts: 1. **Principal** — reduces the invoice balance 2. **Fine and interest** — booked apart, as financial revenue 3. **Unexplained excess** — what the policy does not justify becomes account credit, as before That separation matters in three places: * **Tax invoice**: the NF-e amount is the service amount, without the charges. Fine and interest are financial revenue and sit outside the ISS tax base and the withholding base. * **Revenue reports**: revenue per customer counts only the principal. Counting the charges inflates LTV with money that did not come from the sale. * **Customer statement**: the charges appear on their own line, "Juros e multa — fatura X". When the amount received exceeds what the policy explains, the system emits the `invoice.late_charges_unexplained` event. That usually means our arithmetic and the bank's diverged beyond rounding, and it is worth a look. ## Where to follow it[​](#where-to-follow-it "Direct link to Where to follow it") * **Invoice detail**: a "Late charges" card with days overdue, fine, interest, updated total and what has already been received. Shown only for an overdue invoice, or one that already received charges. * **Delinquency**: the total overdue remains the principal alone — it is the metric comparable across periods. Accumulated charges appear in a separate column. ## Through the API[​](#through-the-api "Direct link to Through the API") The resource is `/v1/late_fee_policies`. Percentages are floats (`2.0` for 2%) and amounts are in BRL. ``` curl -X POST https://api.kobana.com.br/billing/v1/late_fee_policies \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "name": "Default", "is_default": true, "fine_mode": "percentage", "fine_percent": 2.0, "interest_mode": "monthly_percentage", "interest_percent": 1.0 }' ``` To reconcile the arithmetic before an invoice actually goes late: ``` curl -X POST https://api.kobana.com.br/billing/v1/late_fee_policies/simulate \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "principal": 1000.0, "due_date": "2026-09-10", "reference_date": "2026-10-10", "policy_id": "..." }' ``` The response carries `days_past_due`, `fine`, `interest`, `total` and `total_due`. ## Frequently asked[​](#frequently-asked "Direct link to Frequently asked") **Do the charges go into the tax invoice amount?** No. The NF-e uses the service amount. Fine and interest are financial revenue, outside the ISS base and the withholding base. If your operation needs a complementary invoice for the charges, it is issued manually. **What happens to old invoices when charges are turned on?** Invoices still in `draft` inherit the new policy when finalized. Invoices already finalized keep what they carry — including the ones that had no policy at all. **What if the customer pays more than fine and interest justify?** The difference becomes credit on their account, and the `invoice.late_charges_unexplained` event is emitted for you to check. **Can I charge interest without a fine, or a fine without interest?** Yes. The two types are independent; leave one on `No charge`. --- # Revenue Recovery The system tracks all revenue recovered via dunning for efficiency analysis. ## Recovery Record[​](#recovery-record "Direct link to Recovery Record") Each successful payment via retry creates a `RecoveryRecord`: | Field | Description | | --------------------- | --------------------------------------------- | | **Billing account** | Account that paid | | **Invoice** | Recovered invoice | | **Payment** | Payment that settled the debt | | **Amount (cents)** | Amount recovered | | **Days overdue** | How many days overdue at the time of recovery | | **Attempts** | How many attempts until success | | **Recovery method** | E.g.: `auto_retry_pix`, `manual_retry_card` | | **Original due date** | When the invoice should have been paid | | **Recovered at** | Payment date | ## Available Metrics[​](#available-metrics "Direct link to Available Metrics") ### Overview[​](#overview "Direct link to Overview") | Metric | Description | | --------------------------- | ---------------------------------- | | **Total recovered** | Sum of all recovered payments | | **Total lost** | Invoices marked as uncollectible | | **Recovery rate** | Percentage of potential recovered | | **Average days to recover** | Average days overdue until payment | | **Average attempts** | Average attempts until success | ### By Payment Method[​](#by-payment-method "Direct link to By Payment Method") Distribution of recoveries by method: * PIX * Credit card * Boleto * Bank transfer ### By Aging Bucket[​](#by-aging-bucket "Direct link to By Aging Bucket") | Bucket | Estimated recovery rate | | ---------- | ----------------------- | | 1-7 days | 85% | | 8-15 days | 70% | | 16-30 days | 50% | | 30+ days | 25% | ### Trends[​](#trends "Direct link to Trends") Track monthly evolution: * Recovered and lost amounts per month * Monthly recovery rate * Number of invoices processed ### Recovery Potential[​](#recovery-potential "Direct link to Recovery Potential") Estimate of how much can be recovered from currently overdue invoices, based on historical rates per aging bucket. --- # Account Suspension Delinquent accounts are automatically suspended when the grace period is exceeded. ## Suspension Worker[​](#suspension-worker "Direct link to Suspension Worker") Runs **daily at 02:00 UTC** and: 1. Synchronizes the status of delinquent accounts 2. Gets the `gracePeriodDays` from the dunning configuration (default: 3 days) 3. Finds delinquent accounts with: * Stage `warning` or `final` * Oldest overdue date > grace period * Not yet suspended * Not recovered 4. For each account: * Changes the billing account status to `suspended` * Updates the delinquency stage to `suspended` * **Pauses all active subscriptions** * Sends a suspension notification ## Suspension Effects[​](#suspension-effects "Direct link to Suspension Effects") * Billing account status: `suspended` * All active subscriptions are automatically paused * The suspension reason is recorded (e.g., "Delinquency for X+ days") * Notification sent to the account holder ## Suspension Notification[​](#suspension-notification "Direct link to Suspension Notification") Type: `account_suspended` Available variables: * Organization name * Total overdue amount * Suspension date ## Reactivation[​](#reactivation "Direct link to Reactivation") Reactivation is done manually after payment is settled: 1. Operator accesses the billing account 2. Clicks "Reactivate" 3. Status returns to `active` 4. Suspension fields are cleared 5. Paused subscriptions can be resumed individually --- # Payment Retries The retry system automatically processes charge attempts for overdue invoices. ## Attempt Statuses[​](#attempt-statuses "Direct link to Attempt Statuses") | Status | Description | | ------------ | ----------------------------------------- | | `pending` | Awaiting processing | | `processing` | Being processed (claimed by worker) | | `succeeded` | Payment successful | | `failed` | Payment declined, more attempts available | | `exhausted` | Maximum attempts reached | ## Attempt Fields[​](#attempt-fields "Direct link to Attempt Fields") | Field | Description | | ------------------- | ---------------------------------- | | **Invoice** | Associated invoice | | **Payment** | Created payment record | | **Attempt number** | Sequential (1, 2, 3...) | | **Payment method** | Method used for the attempt | | **Amount (cents)** | Amount to be charged | | **Failure code** | Decline reason | | **Failure message** | Detailed error description | | **Scheduled for** | Attempt date/time | | **Processed at** | Processing date/time | | **Next retry at** | When the next attempt will be made | ## Retry Worker[​](#retry-worker "Direct link to Retry Worker") The worker runs **every 6 hours** and: 1. Finds attempts with `status=pending` and `scheduledFor ≤ now` 2. Atomically claims each attempt (`pending → processing`) to avoid duplication 3. For each attempt: * Checks if the invoice is already paid (skips) * Creates a payment record * Processes the payment via gateway 4. On **success**: * Marks the invoice as paid * Creates a recovery record * Removes the account from the delinquent list 5. On **failure**: * If attempts remain: schedules the next one * If attempts exhausted: marks as `exhausted` and suspends the account (if configured) ## Race Condition Prevention[​](#race-condition-prevention "Direct link to Race Condition Prevention") The system uses atomic `updateMany` with status verification to ensure only one worker processes each attempt: ``` WHERE id = X AND status = 'pending' SET status = 'processing' ``` If `count = 0`, another worker has already claimed the attempt. ## Retry for Installments[​](#retry-for-installments "Direct link to Retry for Installments") Retries can also target specific installments: * The `metadata.installmentId` identifies the installment * The retry amount is for the installment, not the entire invoice --- # Getting Started The **Getting Started** page (`/dashboard/getting-started`) is the starting point for new organizations. It presents a guided sequence of the tasks needed to start recurring billing: register the company, set up gateways and NF-e, create plans and products, import customers and activate the first subscription. Each card on the page represents an onboarding milestone and shows the organization's state in real time (completed, pending or blocked). The dashboard uses these same checks to decide when to hide the initial instructions and show the operational metrics. ## Suggested steps[​](#suggested-steps "Direct link to Suggested steps") 1. **Set up the company and fiscal data** — enter the CNPJ, tax regime and addresses in `Accounts > Companies`. 2. **Connect a payment gateway** — choose a provider (Kobana, Asaas, Iugu, Pagar.me) in `Payment Gateways` and set the default gateway per method (card, boleto, PIX). 3. **Register plans and products** — define the catalog in `Plans and Products`, with cycles, amounts in reais and proration rules. 4. **Enable NF-e issuance** (optional) — select a provider in `Invoices (NF-e) > Settings`, attach the digital certificate and map the service codes. 5. **Import customers** — use CSV import in `Export and Import > Imports` or register them manually. 6. **Create the first subscription** — link a customer to a plan in `Subscriptions` and confirm the start of the cycle. 7. **Set up dunning and notifications** — in `Dunning` and `Settings > Notifications`. 8. **Connect webhooks and the API** — register endpoints in `Webhooks`. The public API uses the Kobana Account access token (`Authorization: Bearer`), not a key generated here. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Onboarding panel with the initial setup checklist](/en/assets/images/primeiros-passos-a7b02b923e4fe6c9e96d47c6f58edbdd.png) --- ## [📄️Taxes](https://docs.billing.kobana.com.br/en/en/impostos.md) [Automatic Billing features a complete tax calculation engine for the Brazilian market, with support for multiple tax regimes, withholdings, and the new CBS/IBS system.](https://docs.billing.kobana.com.br/en/en/impostos.md) --- ## [📄️Taxes](https://docs.billing.kobana.com.br/en/en/impostos.md) [Automatic Billing features a complete tax calculation engine for the Brazilian market, with support for multiple tax regimes, withholdings, and the new CBS/IBS system.](https://docs.billing.kobana.com.br/en/en/impostos.md) --- # Tax Calculation Engine The calculation engine determines all applicable taxes based on tax rules, the company profile, and the customer's tax type. ## Supported Taxes[​](#supported-taxes "Direct link to Supported Taxes") | Tax | Description | Jurisdiction | | ---------- | ------------------------------------------ | ------------- | | **ISS** | Service Tax | Municipal | | **PIS** | Social Integration Program | Federal | | **COFINS** | Contribution for Social Security Financing | Federal | | **CSLL** | Social Contribution on Net Income | Federal | | **IRPJ** | Corporate Income Tax | Federal | | **IRRF** | Withholding Income Tax | Federal | | **CSRF** | PIS + COFINS + CSLL withheld together | Federal | | **INSS** | Social Security Contribution | Federal | | **CBS** | Contribution on Goods and Services (2026+) | Federal | | **IBS** | Tax on Goods and Services (2026+) | Federal/State | ## Calculation Flow[​](#calculation-flow "Direct link to Calculation Flow") ### 1. Get Applicable Rules[​](#1-get-applicable-rules "Direct link to 1. Get Applicable Rules") Queries the `TaxRuleService` with the operation context. Rules are filtered by scope and priority. ### 2. Resolve Rates[​](#2-resolve-rates "Direct link to 2. Resolve Rates") * Extracts rates from applicable rules * Falls back to the company's Tax Profile * Applies withholding overrides from the billing account ### 3. Calculate Each Tax[​](#3-calculate-each-tax "Direct link to 3. Calculate Each Tax") ``` ISS = service_value × (iss_rate / 100) PIS = service_value × (pis_rate / 100) COFINS = service_value × (cofins_rate / 100) CSLL = service_value × (csll_rate / 100) IRRF = service_value × (irrf_rate / 100) [always withheld] CSRF = service_value × (4.65 / 100) [always withheld] INSS = service_value × (inss_rate / 100) [always withheld] ``` ### 4. Rounding[​](#4-rounding "Direct link to 4. Rounding") Each tax is rounded independently with `Math.round()`. Rounding compensation is applied to the tax with the largest contribution. ### 5. Result[​](#5-result "Direct link to 5. Result") ``` Total taxes = sum of all taxes Total withheld = sum of taxes with isWithheld flag Net amount = service value - total taxes ``` ## CBS/IBS (Tax Reform 2026+)[​](#cbsibs-tax-reform-2026 "Direct link to CBS/IBS (Tax Reform 2026+)") The system already supports the new taxes from the tax reform: | Mode | Description | | ------------- | ----------------------------------------------- | | `informative` | Calculated but not included in the total (2026) | | `compositive` | Included in the total (2027+) | CBS and IBS rates are configurable in the company's Tax Profile. --- # Tax Profile The tax profile defines the tax configuration of each company (legal entity) within the organization. ## Main Fields[​](#main-fields "Direct link to Main Fields") ### Tax Regime[​](#tax-regime "Direct link to Tax Regime") | Regime | Description | | ----------------- | ---------------------------------- | | `simple_national` | Simples Nacional | | `presumed_profit` | Presumed Profit (Lucro Presumido) | | `real_profit` | Actual Profit (Lucro Real) | | `mei` | Individual Microentrepreneur (MEI) | ### Simples Nacional[​](#simples-nacional "Direct link to Simples Nacional") | Field | Description | | ------------------ | -------------------------------------------------------- | | **Annex** | `annex_iii`, `annex_iv`, or `annex_v` | | **RBT12 (cents)** | Gross Tax Revenue for the last 12 months | | **R Factor** | Payroll / revenue ratio | | **CPP within DAS** | Whether the Employer Contribution is included in the DAS | ### Presumed Profit[​](#presumed-profit "Direct link to Presumed Profit") | Field | Description | | -------------------- | ----------------------- | | **Presumption rate** | Default: 32% of revenue | ### ISS[​](#iss "Direct link to ISS") | Field | Description | | ----------------------- | ---------------------- | | **Municipality (IBGE)** | IBGE municipality code | | **ISS rate** | ISS percentage | ### Federal Taxes[​](#federal-taxes "Direct link to Federal Taxes") | Field | Description | | --------------- | ----------------- | | **PIS rate** | PIS percentage | | **COFINS rate** | COFINS percentage | | **CSLL rate** | CSLL percentage | | **IRPJ rate** | IRPJ percentage | ### CBS/IBS (2026+)[​](#cbsibs-2026 "Direct link to CBS/IBS (2026+)") | Field | Description | | ------------ | --------------------------------------------- | | **Enabled** | Whether the new system is active | | **CBS rate** | CBS percentage | | **IBS rate** | IBS percentage | | **Mode** | `informative` (2026) or `compositive` (2027+) | ## Versioning[​](#versioning "Direct link to Versioning") Tax profiles are versioned: * `effective_from` and `effective_to` define the validity period * `version` is incremented automatically with each change * History allows tracking changes over time ## Historical RBT12[​](#historical-rbt12 "Direct link to Historical RBT12") The system maintains the monthly Gross Tax Revenue history for accurate Simples Nacional calculation. Each record contains the month, year, and revenue amount. --- # Fiscal Periods Fiscal periods aggregate invoices for monthly or quarterly tax assessment. ## Period Types[​](#period-types "Direct link to Period Types") | Type | Description | | ----------- | ---------------------------------- | | `monthly` | Monthly assessment (month 1-12) | | `quarterly` | Quarterly assessment (quarter 1-4) | ## Period Fields[​](#period-fields "Direct link to Period Fields") ### Revenue[​](#revenue "Direct link to Revenue") | Field | Description | | ------------------- | ---------------------------- | | **Gross revenue** | Total invoiced in the period | | **Taxable revenue** | Tax calculation base | ### Taxes Due[​](#taxes-due "Direct link to Taxes Due") | Field | Description | | -------------- | -------------- | | **ISS due** | ISS payable | | **PIS due** | PIS payable | | **COFINS due** | COFINS payable | | **IRPJ due** | IRPJ payable | | **CSLL due** | CSLL payable | ### Withholding Offset[​](#withholding-offset "Direct link to Withholding Offset") | Field | Description | | ------------------ | -------------------------------------------- | | **IRRF to offset** | IRRF withheld to deduct from IRPJ | | **CSRF to offset** | CSRF withheld to deduct from PIS/COFINS/CSLL | | **ISS to offset** | ISS withheld to deduct | ### Simples Nacional[​](#simples-nacional "Direct link to Simples Nacional") | Field | Description | | ------------------ | ----------------------------- | | **Estimated DAS** | Estimated DAS amount | | **Effective rate** | Calculated rate | | **Annex** | Simples annex (III, IV, or V) | ### CBS/IBS[​](#cbsibs "Direct link to CBS/IBS") | Field | Description | | ----------- | ----------- | | **CBS due** | CBS payable | | **IBS due** | IBS payable | ## Status[​](#status "Direct link to Status") | Status | Description | | ------------ | ------------------------------- | | `open` | Period open, receiving invoices | | `calculated` | Taxes calculated | | `closed` | Period closed | ## Calculations[​](#calculations "Direct link to Calculations") ### For Simples Nacional[​](#for-simples-nacional "Direct link to For Simples Nacional") 1. Gets RBT12 (Gross Tax Revenue for the last 12 months) 2. Locates the applicable bracket 3. Calculates the effective rate 4. Applies to monthly revenue 5. Distributes among ISS, PIS, COFINS, CPP 6. Tracks withholdings for offset ### For Presumed Profit[​](#for-presumed-profit "Direct link to For Presumed Profit") 1. Gets gross revenue 2. Applies presumption rate (default: 32%) 3. Calculates IRPJ on the presumed profit 4. Calculates CSLL on the presumed profit 5. Calculates PIS/COFINS on gross revenue 6. Calculates ISS according to municipal rules 7. Tracks withholdings for offset ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/tax-periods` screen lists each tax period (monthly, quarterly or annual), with gross revenue, taxable revenue, taxes due (ISS, PIS, COFINS, IRPJ, CSLL, CBS, IBS), withholdings to offset, estimated DAS and effective rate. Periods can be closed (`closed`) — an irreversible operation that freezes the calculated amounts. ![Tax periods with revenue, taxes and closing status](/en/assets/images/periodos-fiscais-a755dd2f95588a50e49b808bf9279428.png) --- # Tax Rules Tax rules allow configuring tax rates with different levels of specificity. ## Rule Fields[​](#rule-fields "Direct link to Rule Fields") | Field | Description | | ------------ | ------------------------------------------------ | | **Name** | Descriptive rule name | | **Scope** | Application level (see table) | | **Priority** | Higher number = higher priority within the scope | | **Active** | Whether the rule is active | | **Validity** | Validity period (from/to) | | **Items** | List of taxes and rates | ### Matching Criteria (optional)[​](#matching-criteria-optional "Direct link to Matching Criteria (optional)") | Field | Description | | --------------------- | ------------------------ | | **Company** | Specific issuing company | | **Service item** | Specific service | | **Billing account** | Specific customer | | **Customer tax type** | Customer classification | | **Municipality** | IBGE municipality code | | **Operation type** | `internal` or `external` | ## Scope and Priority[​](#scope-and-priority "Direct link to Scope and Priority") Rules are evaluated from most specific to most generic: | Scope | Priority | Description | | -------------- | -------- | -------------------------------- | | `customer` | 100 | Rule for a specific customer | | `service` | 80 | Rule for a specific service item | | `company` | 60 | Rule for the issuing company | | `municipality` | 40 | Rule by municipality | | `organization` | 20 | Organization-wide rule | | `global` | 0 | System default | **The rule with the highest priority takes precedence.** Multiple rules with the same priority are combined. ## Rule Items[​](#rule-items "Direct link to Rule Items") Each rule contains items that define rates: | Field | Description | | -------------------- | -------------------------------------------------------------- | | **Tax type** | ISS, PIS, COFINS, CSLL, IRPJ, IRRF, CSRF, INSS | | **Rate** | Percentage (e.g., 5.00 for 5%) | | **Withheld** | Whether it is withheld at source | | **Calculation base** | `service_value`, `service_value_minus_iss`, or `presumed_base` | | **Exempt** | Whether the tax is exempt | | **Exemption reason** | Justification for the exemption | ## Examples[​](#examples "Direct link to Examples") ### Organization default ISS[​](#organization-default-iss "Direct link to Organization default ISS") ``` Scope: organization (priority 20) Item: ISS = 5.00%, withheld at source, base = service value ``` ### Service-specific rule[​](#service-specific-rule "Direct link to Service-specific rule") ``` Scope: service (priority 80) Service item: "Software Development" Items: - ISS = 3.50%, not withheld - IRRF = 15.00%, withheld at source ``` The service rule takes precedence over the organization rule for ISS. ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/tax-rules` screen lets you create, edit and prioritize tax rules. The main filters include company, customer, service item, tax type and whether it is withheld. Each rule carries a list of taxes with rate, withholding flag and exemption. ![List of tax rules with scope, priority and rates](/en/assets/images/regras-fiscais-01ad7b6543edcddcf4060017308c9f30.png) --- # Fiscal Reports The fiscal reports area (`/dashboard/fiscal/reports`) consolidates the information needed for accounting close and for generating ancillary tax obligations. The data is built from the organization's paid invoices, issued NF-e, withholdings and closed tax periods. ## Report types[​](#report-types "Direct link to Report types") * **Summary by accrual period** — gross revenue, taxable revenue, ISS, PIS, COFINS, IR, CSLL, INSS and estimated DAS per month, quarter or year. * **Withholdings suffered** — all withholdings applied by the service takers (IR, INSS, CSRF, ISS), with calculation base, rate, amount withheld and status (`open`, `partially_compensated`, `fully_compensated`). * **NF-e issued in the period** — paginated list with number, series, amount, status, municipality code, rates applied and calculated taxes. * **DAS / Simples Nacional** — for companies under the simplified regime, the report shows the RBT12, the current bracket and the estimated amount of the payment slip. ## Available filters[​](#available-filters "Direct link to Available filters") * **Company** — limits to one of the registered companies. * **Period** — month, quarter, year or custom range. * **Tax regime** — when the organization has companies under different regimes. ## How the amounts are calculated[​](#how-the-amounts-are-calculated "Direct link to How the amounts are calculated") The reports query the `tax_periods`, `tax_computations`, `withholdings` and `nfes` tables directly, always filtered by `organization_id`. `closed` periods are immutable; `open` periods may change as new invoices are paid or NF-e are issued. To close the accrual period, use [Tax Periods](https://docs.billing.kobana.com.br/en/en/impostos/periodos-fiscais/.md). ## Export[​](#export "Direct link to Export") Reports can be exported as CSV to send to the accountant or import into bookkeeping systems. Exports are available in [Export and Import](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Fiscal reports with taxes by accrual period and withholdings](/en/assets/images/relatorios-fiscais-02d2fa3d6e044b7635a333b2aa377f30.png) --- # Withholdings at Source Withholdings are taxes retained by the payer (customer) that must be tracked, reported, and offset. ## Withholding Types[​](#withholding-types "Direct link to Withholding Types") | Tax | Description | | -------- | ------------------------------------ | | **ISS** | Withheld by the service recipient | | **IRRF** | Withholding income tax | | **CSRF** | PIS + COFINS + CSLL combined (4.65%) | | **INSS** | Social security contribution | ## Withholding Fields[​](#withholding-fields "Direct link to Withholding Fields") | Field | Description | | ------------------------- | -------------------------------------------------- | | **Invoice** | Source invoice | | **NF-e** | Related fiscal invoice | | **Tax type** | Which tax was withheld | | **Base (cents)** | Calculation base | | **Rate** | Withheld percentage | | **Amount (cents)** | Withheld amount | | **Withholder** | Entity that withheld (usually the billing account) | | **Competence month/year** | Accounting period | | **Status** | Withholding status | | **Offset (cents)** | Amount already used to deduct taxes | ## Withholding Status[​](#withholding-status "Direct link to Withholding Status") | Status | Description | | ----------------------- | ------------------------ | | `retained` | Recorded, not yet offset | | `compensated` | Fully offset | | `partially_compensated` | Partially offset | ## Flow[​](#flow "Direct link to Flow") 1. **Creation**: Automatically generated from the tax calculation of each invoice 2. **Retention**: The amount is withheld by the customer at the time of payment 3. **Tracking**: Stored by competence month/year 4. **Offset**: Applied to reduce the tax liability in subsequent periods 5. **Reconciliation**: Reported in tax filings ## Configuration per Customer[​](#configuration-per-customer "Direct link to Configuration per Customer") Each billing account can have individual withholding flags: * `withholdIss` — Withhold ISS * `withholdIrrf` — Withhold IRRF * `withholdCsrf` — Withhold CSRF (PIS/COFINS/CSLL) * `withholdInss` — Withhold INSS These flags override the default behavior of tax rules. ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/withholdings` screen lists all of the organization's withholdings, with filters by tax type, status, accrual month/year, withholding company and search by invoice or NF-e. Each row shows base, rate, amount withheld, amount already offset and actions to open the originating invoice/NF-e. ![List of withholdings with type, base, rate and offset](/en/assets/images/retencoes-c351b02b503276e42bd832cf6cbd02a6.png) --- # Simples Nacional The system automatically calculates the DAS (Simples Nacional Collection Document) based on revenue and the correct annex. ## Supported Annexes[​](#supported-annexes "Direct link to Supported Annexes") ### Annex III — General Services[​](#annex-iii--general-services "Direct link to Annex III — General Services") | Bracket | RBT12 (R$ thousand) | Nominal Rate | | ------- | ------------------- | ------------ | | 1st | Up to 180 | 6.0% | | 2nd | 180 to 360 | 11.2% | | 3rd | 360 to 720 | 13.5% | | 4th | 720 to 1,800 | 16.0% | | 5th | 1,800 to 3,600 | 21.0% | | 6th | 3,600 to 4,800 | 33.0% | ### Annex IV — Construction, Security, Cleaning[​](#annex-iv--construction-security-cleaning "Direct link to Annex IV — Construction, Security, Cleaning") | Bracket | RBT12 (R$ thousand) | Nominal Rate | | ------- | ------------------- | ------------ | | 1st | Up to 180 | 4.5% | | 2nd | 180 to 360 | 9.0% | | 3rd | 360 to 720 | 10.2% | | 4th | 720 to 1,800 | 14.0% | | 5th | 1,800 to 3,600 | 22.0% | | 6th | 3,600 to 4,800 | 33.0% | ### Annex V — Intellectual Services[​](#annex-v--intellectual-services "Direct link to Annex V — Intellectual Services") | Bracket | RBT12 (R$ thousand) | Nominal Rate | | ------- | ------------------- | ------------ | | 1st | Up to 180 | 15.5% | | 2nd | 180 to 360 | 18.0% | | 3rd | 360 to 720 | 19.5% | | 4th | 720 to 1,800 | 20.5% | | 5th | 1,800 to 3,600 | 23.0% | | 6th | 3,600 to 4,800 | 30.5% | ## R Factor[​](#r-factor "Direct link to R Factor") The R Factor determines whether companies originally in Annex V can use Annex III (lower rates): ``` R Factor = Payroll (12 months) / Gross Revenue (12 months) ``` * **R Factor >= 28%**: Can use Annex III * **R Factor < 28%**: Remains in Annex V ## Effective Rate Calculation[​](#effective-rate-calculation "Direct link to Effective Rate Calculation") ``` Effective Rate = (RBT12 × Nominal Rate - Deduction) / RBT12 × 100 ``` ## DAS Calculation[​](#das-calculation "Direct link to DAS Calculation") ``` DAS = Monthly Revenue × Effective Rate ``` ## DAS Distribution[​](#das-distribution "Direct link to DAS Distribution") The DAS amount is distributed among taxes: * IRPJ: 4.0% to 35% * CSLL: 3.5% to 15% * COFINS: 12.82% to 16.03% * PIS: 2.78% to 3.47% * CPP: 30.5% to 43.4% * ISS: 0% to 33.5% The proportions vary according to the annex and bracket. ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/simples` screen presents the Simples Nacional calculation per company: current annex, RBT12 (gross revenue of the last 12 months), the bracket the company is in, nominal rate, deduction amount, Factor R when applicable and the estimated DAS for the current month. It includes alerts when the company is close to the ceiling or about to change brackets. ![Simples Nacional calculation with annex, bracket and estimated DAS](/en/assets/images/simples-nacional-c3706a4a73d6fe3c7d30ffe9455e7280.png) --- # Authentication The MCP server accepts a **Bearer token** in the `Authorization` header, and nothing else — no cookie, no client certificate. :::warning Never in the URL A token in the query string (`?access_token=…`, or parameters such as `token` and `api_key`) **does not authenticate**, even next to a valid header: the request is answered `401` with `error="invalid_request"` in `WWW-Authenticate`. A token in the URL leaks into proxy and CDN logs, `Referer` and browser history — the MCP authorization spec and RFC 6750 forbid it. ::: That token is an **OAuth 2.1 access token issued by the Kobana authorization server** (`https://account.kobana.com.br`): an RS256-signed JWT issued **for this resource**, whose `aud` is `https://mcp.billing.kobana.com.br`. It arrives one of two ways — the OAuth flow, run by the client itself, or a **personal token** you create in your Kobana account — and it is verified the same way in both cases. ``` Authorization: Bearer eyJhbGciOiJSUzI1NiIs… ``` :::info Each surface has its own audience A token issued for the MCP server is **not valid** on the REST API (`api.billing.*`), and an API token is not valid here. That is what stops a token handed to an assistant from being reused against the API — and the other way round. ::: ## Two ways to connect[​](#two-ways-to-connect "Direct link to Two ways to connect") | | OAuth flow | Personal token | | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | How you get it | Paste the URL into the client; it opens the Kobana sign-in and you authorize | Create it at **Kobana account → Tokens and Access → New Personal Token**: app **Faturamento Automático**, usage **MCP**, resources and access, validity | | How the client uses it | On its own, after you authorize | You paste it into the client as `Authorization: Bearer ` | | Validity | 30 minutes, renewed by the client | 7 days to 1 year, your choice | | Scope | The resources and access levels you kept checked on the consent screen (`read`, `write`, `delete`, `import`, `export`, `all`) | The resources and access you selected | | Good for | Claude, ChatGPT, IDEs and any client with OAuth | Clients without OAuth support, scripts and automations | The personal token has to be created with the **MCP** usage. A token created for the **REST API** carries the API's audience and is refused here with `401` — and the reverse holds too. ## The OAuth flow[​](#the-oauth-flow "Direct link to The OAuth flow") You run none of these steps: the MCP client (Claude, ChatGPT, an IDE) does all of it on its own, starting from the URL. They are here for when something fails halfway. 1. **Challenge.** A request without a token gets `401` with the challenge every OAuth 2.1 resource server must send ([RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728)): ``` WWW-Authenticate: Bearer realm="kobana-billing-mcp", error="invalid_token", resource_metadata="https://mcp.billing.kobana.com.br/.well-known/oauth-protected-resource" ``` 2. **Resource metadata.** The client reads the document it points at. It is public and carries no secret — only pointers: ``` curl https://mcp.billing.kobana.com.br/.well-known/oauth-protected-resource ``` ``` { "resource": "https://mcp.billing.kobana.com.br", "authorization_servers": ["https://account.kobana.com.br"], "bearer_methods_supported": ["header"], "scopes_supported": [ "billing/billing_accounts", "billing/certificates", "billing/companies", "billing/coupons", "billing/credits", "billing/customers", "billing/dashboard_users", "billing/invoices", "billing/nfes", "billing/organization", "billing/payment_methods", "billing/payments", "billing/plan_changes", "billing/plan_groups", "billing/plans", "billing/portal_users", "billing/product_groups", "billing/products", "billing/proposal_templates", "billing/proposals", "billing/service_items", "billing/subscription_changes", "billing/subscription_item_changes", "billing/subscriptions", "billing/tax_periods", "billing/tax_rules", "billing/team_roles", "billing/usage", "billing/withholdings", "read", "write", "delete", "import", "export", "all" ], "resource_documentation": "https://docs.billing.kobana.com.br" } ``` 3. **Authorization server metadata** ([RFC 8414](https://datatracker.ietf.org/doc/html/rfc8414)), at `https://account.kobana.com.br/.well-known/oauth-authorization-server`. 4. **Dynamic client registration** ([RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591)). The client registers itself; the consent screen warns that it is not a verified app. 5. **Authorization with PKCE and `resource`** ([RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707)). You sign in to Kobana, pick the organization (if you have more than one) and authorize. 6. **Token.** The client exchanges the code for a short-lived access token and sends it on every request, refreshing it when it expires. The token carries who you are (`sub`) and the organization you authorized (`org`). `org` is what scopes the data — no tool takes an organization as an argument. A token whose organization does not exist in Billing gets `403 unknown_organization`. ## Authorization: the permissions of whoever authorized[​](#authorization-the-permissions-of-whoever-authorized "Direct link to Authorization: the permissions of whoever authorized") What a caller sees is **narrower** than the catalog: tools are filtered by the **dashboard permissions of the person who authorized the client**, in that organization, resolved on every request. The ceiling is always what that person can do in the UI. | Situation | Result | | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | The person is not a member of the organization | **Denies every tool** (`key_owner_not_member`). Authorize again with an account that belongs to the organization. | | Active membership | The person's permissions and roles, applied tool by tool. `owner` and the `*` wildcard open everything; `invoices.*` opens the family. | | Membership suspended, removed, or with no role | **Denies every tool** (`membership_inactive`). | | The permission lookup fails | **Denies every tool.** Fail closed. | Permissions are read on every call, so revoking a role in the dashboard takes effect on the very next tool, without waiting for the token to expire. A tool the caller cannot run is **not listed** by `tools/list`. When `tools/call` refuses, the code says **who fixes it**: | Code | Who fixes it | | ------------------------- | -------------------------------------------------------------------------------------------------------------------------- | | `insufficient_scope` | Using a token that reaches the resource with the access requested — for example, a personal token with write access to it. | | `insufficient_permission` | An organization admin, granting the permission (the error names which). | | `membership_inactive` | Reinstating the person — no permission fixes a dead membership. | | `key_owner_not_member` | Authorizing again with an account that is a member of the organization. | :::tip Recommended posture for agents Authorize the client with an account that holds only the permissions the agent needs. A client authorized by a read-only analyst exposes only the read tools, whatever the model on the other end does. ::: ## Token scope[​](#token-scope "Direct link to Token scope") On top of permissions, the MCP server applies the scope the token carries, in the `scope` claim. The two checks add up: a tool only shows up if both allow it. Reading is a read tool, a resource, a read prompt and a completion. Delete tools (`*_delete`, bulk ones included) require `delete`; the Barueri NFS-e import (`billing_nfes_import_barueri`) requires `import`; everything else that changes data requires `write`. No level stands in for another: `write` neither deletes nor imports. Each tool requires exactly the level the REST endpoint behind it requires — every delete tool calls a `DELETE`, and the endpoint checks the token again with that level. **Token with resources** — the personal-token and OAuth-flow case. The resources define how far the token reaches, and the verbs apply only within them: | Token scope | Result | | ----------------------------------------------- | ---------------------------------------------------------- | | `billing/invoices billing/customers read write` | Reads and writes invoices and customers — and nothing else | | `billing/invoices read` | Only reads invoices | | `billing/all read` | Reads everything, writes nothing | Bank accounts, banks and Pix keys are reachable only with `billing/all`. `delete`, `import` and `export` on their own do not count as writing, and `write` on its own does not delete. To delete, the token needs the resource and `delete`: `billing/products read write delete` reads, changes and deletes products. **Token without resources** — a token that carries no `billing/…` scope. Only the access level applies: reading with `read`, `write` or `all`; writing with `write` or `all`; deleting with `delete` or `all`; importing with `import` or `all`; exporting with `export` or `all`. A token with none of these levels and no `billing/…` scope reaches no tool but `billing_me`. :::info Clients connected through the OAuth flow ask for every level — you choose which to grant The `/.well-known/oauth-protected-resource` document advertises the billing resources and the six access levels — `read`, `write`, `delete`, `import`, `export` and `all` — and that is what the client (Claude, ChatGPT, the MCP Inspector, IDEs) asks for on the consent screen. There you uncheck what you do not want to grant, level by level: the token issued carries only the resources and levels left checked, and the MCP server lists only the tools they reach. A tool outside it returns `insufficient_scope`, and the way out is to authorize again granting the missing access — `delete` for the delete tools, for instance. ::: The same rule applies to the REST API, with the resource taken from the path and one level per request: `GET` needs `read`, `DELETE` needs `delete`, the import needs `import` and everything else needs `write` — without it the answer is `403 insufficient_scope`. See [API Authentication](https://docs.billing.kobana.com.br/en/en/api/overview/authentication.md). ### Personal token revocation[​](#personal-token-revocation "Direct link to Personal token revocation") Revoking a personal token in your Kobana account **does not cut access right away**: Billing verifies the token on its own, without asking Kobana on every call, and it keeps being accepted until it expires. So: * pick the **shortest validity** the use allows; * select only the **resources and access** the agent needs; * to cut an agent off immediately, suspend or remove the person's membership in the organization — permissions are read on every call and take effect at once. ## Failure modes[​](#failure-modes "Direct link to Failure modes") | HTTP | `code` | Cause | | ---- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 400 | `-32022` (JSON-RPC) | Unsupported protocol version, in the `MCP-Protocol-Version` header or in `_meta`; `data.supported` lists the supported ones. See [Transport](https://docs.billing.kobana.com.br/en/en/mcp/overview/transport.md#protocol-versions). | | 401 | `invalid_token` | Token missing, malformed, invalid, issued for another resource (for example, the REST API), or naming more than one audience in `aud`. | | 401 | `token_expired` | The token expired. The client refreshes it and retries. | | 401 | `invalid_request` | Token in the query string — see the warning at the top of this page. | | 403 | `unknown_organization` | The token is valid, but the organization it names does not exist in Billing. | | 403 | `FORBIDDEN` | `Origin` outside the allow-list (`origin_not_allowed`). | | 404 | `NOT_FOUND` | The request arrived through a host that does not serve MCP. | | 429 | `TOO_MANY_REQUESTS` | Rate limit reached, with `Retry-After` and `X-RateLimit-*` — see [Rate limit](https://docs.billing.kobana.com.br/en/en/mcp/overview/rate-limit.md). | | 503 | `SERVICE_UNAVAILABLE` | We could not reach the authorization server to verify the token. It is on our side: retry after `Retry-After`. | Every `401` carries the `WWW-Authenticate` challenge above, which sends the client back into the OAuth flow. The challenge always says `error="invalid_token"` (or `invalid_request`, for a token in the URL), as RFC 6750 prescribes; the body `code` is what tells an expired token (`token_expired`) from the rest. No `/mcp` response is cacheable: all of them, refusals included, carry `Cache-Control: no-store` and `Content-Security-Policy: default-src 'none'`. The exception is the public `/.well-known/oauth-protected-resource` document, served with `Cache-Control: public, max-age=300`. Permission denials are **not** HTTP errors: they come back as a tool result flagged `isError`, so the model can read them and react — see [Errors](https://docs.billing.kobana.com.br/en/en/mcp/overview/errors.md). ## Host and edge[​](#host-and-edge "Direct link to Host and edge") `/mcp` must be reachable **only** through `mcp.billing.*` — never through the app host, never through the API host, whose distributions point at the same origin. Any other path answers `404`: the endpoint does not advertise that it exists somewhere else. The OAuth resource identifier — and therefore the audience the token must carry — is derived from the **server configuration**, never from the request `Host`, so a forged `Host` cannot steer a client to a different identifier. --- # Clients Any client that speaks **Streamable HTTP** MCP and can run the MCP **OAuth 2.1** flow can connect. You only provide the URL; the client discovers where to authenticate on its own, opens the Kobana sign-in in the browser and keeps the token — see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). A client without OAuth support connects too, with a **personal token**: create it at **Kobana account → Tokens and Access → New Personal Token**, with the **Faturamento Automático** app and the **MCP** usage, and configure the client to send it in the `Authorization: Bearer ` header. ## Claude Code[​](#claude-code "Direct link to Claude Code") ``` claude mcp add --transport http kobana-billing https://mcp.billing.kobana.com.br ``` Then run `/mcp` in a session and pick **Authenticate** to sign in to Kobana. With a personal token, no OAuth flow: ``` claude mcp add --transport http kobana-billing https://mcp.billing.kobana.com.br \ --header "Authorization: Bearer " ``` ## Clients configured by file[​](#clients-configured-by-file "Direct link to Clients configured by file") Clients that read a JSON configuration file ask for the URL and the transport. Through the OAuth flow there is no authentication header: ``` { "mcpServers": { "kobana-billing": { "type": "http", "url": "https://mcp.billing.kobana.com.br" } } } ``` On the first connection the client opens the browser for you to authorize. There is no organization-selection header: you pick the organization on the consent screen, and it is recorded in the token. With a personal token, add the header — the organization is the one of the account you created the token in: ``` { "mcpServers": { "kobana-billing": { "type": "http", "url": "https://mcp.billing.kobana.com.br", "headers": { "Authorization": "Bearer " } } } } ``` Treat the file as a secret: whoever reads it uses the token. ## Clients that connect by URL[​](#clients-that-connect-by-url "Direct link to Clients that connect by URL") Claude and ChatGPT connect a remote server by pasting the URL `https://mcp.billing.kobana.com.br` into their connector settings. The OAuth flow runs inside the app itself. ## Recommended posture for agents[​](#recommended-posture-for-agents "Direct link to Recommended posture for agents") * **Authorize with the right account.** Tools are narrowed to the dashboard permissions of whoever authorized the client. A client authorized by a read-only analyst exposes only the read tools, whatever the model on the other end does. It is the strongest way to restrict an agent. * **One token per client.** Each client runs its own flow and gets its own token, which is valid only on MCP — it cannot call the REST API. To switch an agent off, remove its authorization in Kobana without affecting your integrations. * **Personal token: short validity, least scope.** Select only the resources and access the agent needs, and the shortest validity the use allows: revoking the token in Kobana does not cut access before it expires — see [Personal token revocation](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md#personal-token-revocation). * **Start in sandbox.** Destructive tools cancel real subscriptions and void real invoices; the server asks for confirmation before each one (and refuses them to a client that cannot confirm), but the first exploration should not be in production. ## Checking the connection[​](#checking-the-connection "Direct link to Checking the connection") The simplest way is to ask the assistant: "which organization am I using in Billing?" — it calls `billing_organization_get`. With a token issued for MCP — a personal token with the **MCP** usage, for example — you can check with `curl`: ``` # 1. Which organization does this token reach? curl -s https://mcp.billing.kobana.com.br/ \ -H "Authorization: Bearer $MCP_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call", "params":{"name":"billing_organization_get","arguments":{}}}' # 2. How many tools does this token reach? curl -s https://mcp.billing.kobana.com.br/ \ -H "Authorization: Bearer $MCP_TOKEN" \ -H 'Content-Type: application/json' \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | jq '.result.tools | length' ``` If the number is lower than you expected, it is the permissions of whoever authorized or the token scope — see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). It is not an error. --- # Endpoints ## MCP server[​](#mcp-server "Direct link to MCP server") | Environment | URL | | ----------- | ------------------------------------------- | | Production | `https://mcp.billing.kobana.com.br` | | Sandbox | `https://mcp.billing.sandbox.kobana.com.br` | The server URL is the **root of the host** — that whole address is what you paste into an MCP client. It is also the OAuth *resource identifier*, which is why it carries no path. ## Routes served[​](#routes-served "Direct link to Routes served") | Method | Path | Purpose | | -------- | --------------------------------------- | ------------------------------------------------------------------- | | `POST` | `/` | One JSON-RPC message per request. The entire tool surface. | | `GET` | `/.well-known/oauth-protected-resource` | Protected-resource metadata (RFC 9728). Public, unauthenticated. | | `GET` | `/` | `405` — this server is stateless and opens no server→client stream. | | `DELETE` | `/` | `204` — there are no sessions to terminate. | ## Documentation and API[​](#documentation-and-api "Direct link to Documentation and API") | | URL | | --------------------- | ------------------------------------------- | | Documentation | | | REST API (production) | | | REST API (sandbox) | | tip Each environment has its own database and its own authorization server. A token issued in sandbox is not valid in production — start in sandbox. :::info Separate host, on purpose The MCP server has its own host rather than a path on the API or app host. Three reasons: the OAuth discovery document has to live at the root of the host; no dashboard cookie is ever sent to this origin, which removes a whole class of confused-deputy problems by construction; and the API host has an edge policy designed for server-to-server integrations, not for a consumer app. ::: ## Local development[​](#local-development "Direct link to Local development") In development the endpoint answers at `/mcp` on the app host (`http://localhost:3001/mcp`), and the discovery document at `/.well-known/oauth-protected-resource`. Outside development the host allow-list hides the endpoint (`404`) outside `mcp.billing.*`. On the MCP host, any path that is neither the endpoint nor the discovery document answers a JSON `404`, whatever the method: ``` { "error": { "code": "NOT_FOUND", "message": "Not found." } } ``` --- # Errors Failures arrive on **two different channels**, and the difference matters: one is a broken request, the other is something the model is meant to read and react to. ## Tool errors[​](#tool-errors "Direct link to Tool errors") Anything the caller can act on — validation, not found, insufficient scope, insufficient permission, an endpoint error — comes back as a **successful JSON-RPC response** whose result is flagged `isError`, carrying the API's own error envelope as text: ``` { "jsonrpc": "2.0", "id": 2, "result": { "isError": true, "content": [{ "type": "text", "text": "{ \"error\": { \"code\": \"NOT_FOUND\", \"message\": \"Invoice not found\" } }" }] } } ``` The `code` vocabulary is the REST API's, unchanged. The ones you will meet most: | `code` | When | | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `VALIDATION_ERROR` | The arguments failed the endpoint's validation; the details name the fields. | | `NOT_FOUND` | No such record, or it belongs to another organization. | | `CONFLICT` / `DUPLICATE_ERROR` | `external_id` already in use, or a duplicated business key. | | `BAD_REQUEST` | Business rule violated — cancelling an already-cancelled subscription, finalizing an invoice that is not a draft. | | `FORBIDDEN` | The operation is not allowed on this resource in the state it is in. | | `GATEWAY_ERROR` / `EXTERNAL_SERVICE_ERROR` | The payment gateway or the NF-e provider refused or did not answer. | | `USER_DECLINED` | On the `2026-07-28` era, the user declined or cancelled the confirmation of a destructive tool. Nothing was changed. | | `confirmation_required` | The tool is destructive, the client cannot confirm in the chat, and the token has no person who could open an approval link. Use a client on revision `2026-07-28` with elicitation. Nothing was executed. | | `confirmation_replayed` | The confirmation sent had already been used — each one runs a call once. Call the tool again to be asked again. Nothing was executed. | | `confirmation_unavailable` | The server could not record the confirmation (or the approval by link) right now, so it refused the tool. Nothing was executed; try again later. | And the four MCP adds of its own, because they are about *authorization*, not about the resource: | `code` | Who resolves it | | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `insufficient_scope` | The token scope does not reach the tool: the resource is not in the token, or the verb the tool requires (`write`, `delete` or `import`) is missing. Authorize again granting the missing access (through the OAuth flow: read, write and import over the approved resources), or use a personal token that reaches the resource with the verb requested — deletion (`delete`) only through a personal token. | | `insufficient_permission` | An organization admin, by granting the permission the error names. | | `membership_inactive` | Reinstating the person who authorized the client — no permission fixes a dead membership. | | `key_owner_not_member` | Authorizing the client again with an account that is a member of the organization. | Those four are separate **on purpose**: they are different conversations, with different people. A single error would say "you may not" without saying whom to ask. See [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). ### `input_required` is not an error[​](#input_required-is-not-an-error "Direct link to input_required-is-not-an-error") On the `2026-07-28` era, the first `tools/call` to a destructive tool may come back with `resultType: "input_required"` and a confirmation request for the user. That is the normal flow, not a failure: the client shows the question and re-sends the same call with the answer. See [Confirming destructive tools](https://docs.billing.kobana.com.br/en/en/mcp/overview/resources-and-prompts.md#confirming-destructive-tools). ## Protocol errors[​](#protocol-errors "Direct link to Protocol errors") A malformed message gets a JSON-RPC error object instead of a result: | Code | Meaning | | -------- | ------------------------------------------------------------------------------------------------------------------- | | `-32700` | Parse error — the body is not valid JSON | | `-32600` | Invalid request — not a JSON-RPC object, or an array (batching is not supported) | | `-32601` | Method not found | | `-32602` | Invalid params — unknown tool, prompt or argument, `name` missing; on the `2026-07-28` era, also resource not found | | `-32002` | Resource not found — 2025 era only (`2026-07-28` uses `-32602`) | | `-32603` | Internal error — an unexpected failure while running the tool | ``` { "jsonrpc": "2.0", "id": 3, "error": { "code": -32601, "message": "Method not found: tools/describe" } } ``` ## Transport errors[​](#transport-errors "Direct link to Transport errors") Rejections that happen **before** the JSON-RPC message is read are plain HTTP responses with the API's error envelope: missing or invalid token, unsupported protocol version, disallowed `Origin`, rate limit, a body over **1 MB** (`413`, with JSON-RPC error `-32600` `Request body too large`). They are listed in [Authentication → Failure modes](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md#failure-modes). ## Why `isError` and not a JSON-RPC error[​](#why-iserror-and-not-a-json-rpc-error "Direct link to why-iserror-and-not-a-json-rpc-error") A `404` on an invoice is not a defect in the MCP client — it is information about the world, and the model on the other side needs it to correct itself. Burying it in a protocol error would make the client treat it as a transport failure, hide the text and, at best, retry identically. Hence the rule: **if the caller can act on it, it is a result; if the request is broken, it is an error.** ## Observability[​](#observability "Direct link to Observability") Every `tools/call` writes a structured line with the tool, the organization, the token, the status and the duration. **Writes** also appear in the organization's audit trail, written by the dispatched endpoint itself and attributed to the person who authorized the client — what an agent did shows up next to what a person did, on the same screen. --- # Idempotency The tools that **create a resource or move money** accept an optional `idempotency_key` argument. It is sent to the endpoint as the `X-Idempotency-Key` header the REST API already honours. ``` { "name": "billing_invoices_create", "arguments": { "billing_account_id": "…", "total": 1250.00, "idempotency_key": "7c4a8d09-ca37-4f21-b1f0-3d2f2b8c9a11" } } ``` | | | | -------------------------- | ------------------------------------------------------------------- | | **Format** | Opaque string, 1 to 255 characters. A UUID is the usual choice. | | **Replay, same body** | Returns the original response, without running the operation again. | | **Replay, different body** | Conflict. | ## Why an agent needs this more than your backend does[​](#why-an-agent-needs-this-more-than-your-backend-does "Direct link to Why an agent needs this more than your backend does") An MCP client that times out and tries again, or a model that decides "I am not sure that worked, let me redo it", is exactly the pattern that creates the second invoice, the second charge and the second customer. Your backend has a retry loop you wrote; the agent has a judgement call. **Send a key whenever the operation charges, issues or creates.** Reads and updates are naturally idempotent and take no key. ## Tools that accept it[​](#tools-that-accept-it "Direct link to Tools that accept it") | Family | Tools | | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `customers` | `billing_customers_create`, `billing_customers_upsert`, `billing_billing_accounts_create`, `billing_billing_accounts_upsert` | | `portal-users` | `billing_customer_users_create`, `billing_customer_users_invite` | | `users`, `roles` | `billing_dashboard_users_create`, `billing_dashboard_users_upsert`, `billing_team_roles_create`, `billing_team_roles_upsert` | | `products`, `plans`, `services` | `billing_products_create`, `billing_products_upsert`, `billing_product_groups_create`, `billing_product_groups_upsert`, `billing_plans_create`, `billing_plans_upsert`, `billing_plan_groups_create`, `billing_plan_groups_upsert`, `billing_service_items_create`, `billing_service_items_upsert` | | `subscriptions`, `plan-changes` | `billing_subscriptions_create`, `billing_subscriptions_upsert`, `billing_subscriptions_items_change`, `billing_plan_changes_execute`, `billing_plan_changes_rules_create` | | `invoices` | `billing_invoices_create`, `billing_invoices_upsert`, `billing_invoices_finalize`, `billing_invoices_pay`, `billing_invoices_installments_pay`, `billing_subscriptions_create_invoice` | | `payments` | `billing_payments_create`, `billing_payments_retry`, `billing_payments_refund`, `billing_payment_methods_create`, `billing_payment_methods_upsert` | | `credits`, `coupons` | `billing_credits_create`, `billing_credits_upsert`, `billing_coupons_create`, `billing_coupons_upsert` | | `nfes`, `companies` | `billing_nfes_create`, `billing_nfes_upsert`, `billing_nfes_issue`, `billing_companies_create`, `billing_companies_upsert` | | `tax-rules`, `tax-periods`, `withholdings` | `billing_tax_rules_create`, `billing_tax_rules_upsert`, `billing_tax_periods_process_month`, `billing_withholdings_create`, `billing_withholdings_upsert`, `billing_withholdings_convert_to_credit`, `billing_withholdings_convert_to_credits` | | `proposals`, `templates` | `billing_proposals_create`, `billing_proposals_upsert`, `billing_proposals_send`, `billing_proposals_accept`, `billing_proposal_templates_create`, `billing_proposal_templates_upsert` | | `usage` | `billing_usage_report`, `billing_usage_snapshots_daily_create`, `billing_usage_snapshots_monthly_create` | :::caution The ones that charge `billing_invoices_pay`, `billing_payments_create`, `billing_payments_retry` and `billing_nfes_issue` produce an effect in the world — a charge at the gateway, a tax invoice at the tax authority — that no `_delete` undoes. Send an `idempotency_key` on those even when you think you will not repeat. ::: ## Upsert is not idempotency[​](#upsert-is-not-idempotency "Direct link to Upsert is not idempotency") `*_upsert` matches an existing record by `id`, then `external_id`, then the resource's business key, and creates only if it finds none. That solves "I do not know whether it already exists", which is a different problem from "I do not know whether my call arrived". The two combine well: an `upsert` with an `idempotency_key` is safe on both dimensions. --- # Introduction The **Automatic Billing MCP server** is a remote [Model Context Protocol](https://modelcontextprotocol.io) server that exposes the operations of the public API — customers, subscriptions, invoices, payments, tax invoices, proposals and usage — as **tools** an AI client can call. You connect it by URL; there is nothing to install. It is served on its own host, `mcp.billing.kobana.com.br`, with **Streamable HTTP** transport in stateless mode and **Bearer token** authentication. No client certificate is involved. :::info Availability The server and its **293 tools** are implemented, and authentication goes through the Kobana authorization server: via the **OAuth 2.1** flow, where the client is given only the URL and signs in on its own, or via a **personal token** created in your Kobana account. The dedicated edge (the `mcp.billing.*` distribution, WAF and DNS) is still being provisioned. ::: ## When to use it[​](#when-to-use-it "Direct link to When to use it") | | REST API (`/v1`) | MCP server (this) | | --------- | ------------------------------- | ---------------------------------------------------- | | Consumer | your backend | an AI client (Claude, ChatGPT, an IDE) | | Setup | a token, out of band | one URL | | Transport | HTTPS/REST | Streamable HTTP (JSON-RPC 2.0) | | Auth | Bearer token issued for the API | OAuth 2.1 or a personal token, always issued for MCP | | Surface | 178 routes | 293 tools over the same endpoints | The MCP server **does not replace** the REST API. Every tool dispatches in-process to the endpoint that implements the operation, so filters, upsert matching, validation, proration and tenant isolation are exactly the same. If you are writing code, use the [REST API](https://docs.billing.kobana.com.br/en/en/api/overview/introduction.md). If you are connecting an assistant, use this. ## The principle[​](#the-principle "Direct link to The principle") **A capability exists in MCP only if it exists in the public API.** There is no second implementation of anything. The tool calls the endpoint's handler with the identity the caller's token already proved — the same person, the same organization — so it runs the way it would for any HTTP request, and the audit trail it writes is attributed to whoever authorized the client. A tool does what the endpoint does over REST — never more. The practical consequence: what exists only in the dashboard today does not become a tool before it becomes an endpoint. ## What you see is narrower than the catalogue[​](#what-you-see-is-narrower-than-the-catalogue "Direct link to What you see is narrower than the catalogue") `tools/list` returns only the tools **this caller can actually run**, filtered by the dashboard permissions of whoever authorized the client. An agent is not told about capabilities that would only earn it a refusal. The rules are in [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). ## Getting started[​](#getting-started "Direct link to Getting started") 1. **Point your client at the server URL** — see [Endpoints](https://docs.billing.kobana.com.br/en/en/mcp/overview/endpoints.md) and [Clients](https://docs.billing.kobana.com.br/en/en/mcp/overview/clients.md). 2. **Authorize.** The client opens the Kobana sign-in; sign in with an account of the organization and authorize access. See [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). 3. **List the tools** to confirm what your access reaches — ask the assistant, or, with a token issued for MCP at hand: ``` curl https://mcp.billing.kobana.com.br/ \ -H "Authorization: Bearer $MCP_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "MCP-Protocol-Version: 2025-06-18" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }' ``` 4. **Explore the documentation** — the full catalogue is in [Tools](https://docs.billing.kobana.com.br/en/en/mcp/tools/overview.md). ## Next steps[​](#next-steps "Direct link to Next steps") * [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md) — the OAuth flow, the personal token, the scope and permissions applied, and the failure modes. * [Endpoints](https://docs.billing.kobana.com.br/en/en/mcp/overview/endpoints.md) — URLs per environment and the routes served. * [Transport](https://docs.billing.kobana.com.br/en/en/mcp/overview/transport.md) — JSON-RPC, headers and methods. * [Resources and prompts](https://docs.billing.kobana.com.br/en/en/mcp/overview/resources-and-prompts.md) — documents by URI, ready-made prompts, autocomplete, and the confirmation of destructive tools. * [Clients](https://docs.billing.kobana.com.br/en/en/mcp/overview/clients.md) — connecting Claude Code and file-configured clients. * [Listing, sorting and fields](https://docs.billing.kobana.com.br/en/en/mcp/overview/pagination.md) — `page`, `sort_by`, `fields`. * [Errors](https://docs.billing.kobana.com.br/en/en/mcp/overview/errors.md) — the two failure channels, and why the difference matters. * [Tools](https://docs.billing.kobana.com.br/en/en/mcp/tools/overview.md) — the catalogue of all 293 tools. --- # Listing, Sorting and Fields The `*_list` tools use the same pagination as the REST API: **by page number**. | Argument | Default | Max | | ---------- | ------- | ----- | | `page` | `1` | — | | `per_page` | `20` | `100` | ``` { "name": "billing_invoices_list", "arguments": { "status": "open", "page": 2, "per_page": 50 } } ``` The result carries the usual envelope: ``` { "data": [ /* ... */ ], "meta": { "total": 142, "page": 2, "per_page": 50, "total_pages": 3 } } ``` When `page > total_pages`, `data` comes back empty — that is not an error. :::note Collections that do not paginate Some collections are **child sets bounded by construction** (a plan's items, an NF-e's attempts) or small configuration lists. Those answer with the whole set and **do not accept `page`** — and the matching tool does not offer the argument either. That is intentional: a tool advertising `page` on a route that ignores it would make the model page forever through a list that never moves. ::: ## Sorting[​](#sorting "Direct link to Sorting") | Argument | Values | Default | | ------------ | ----------------------------------------------------------- | ------------------- | | `sort_by` | A column name in **snake\_case** (`due_date`, `created_at`) | varies per resource | | `sort_order` | `asc` or `desc`, in any case | varies per resource | ``` { "name": "billing_invoices_list", "arguments": { "sort_by": "due_date", "sort_order": "asc" } } ``` Two rules worth knowing, different from each other on purpose: * **A column the resource does not sort by falls back to the default.** Sorting by a field that does not exist is a request the server cannot honour, but it is not a reason to fail the whole call; `billing_schemas_get` lists the accepted ones under `sortable_fields`. * **A direction that is not a direction is a `400`.** `sort_order: "descending"` is an error, not a silent `desc` — returning the right order by accident would hide the bug until the day the accident landed the other way. ## Fields (`fields`)[​](#fields-fields "Direct link to fields-fields") Every read tool accepts `fields`, an array of column names. Omitted, the whole resource comes back; given, only that: ``` { "name": "billing_invoices_list", "arguments": { "status": "open", "fields": ["number", "total", "due_date"] } } ``` | Rule | Why | | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **`id` always comes back** | A projection you cannot follow is useless, and dropping `id` silently would break the next call, not this one. | | **Top level only** | `fields: ["billing_account"]` returns the whole nested object; there is no `billing_account.name` syntax. | | **Reads only** | A create answers with an envelope the caller did not choose; projecting it would hide half the receipt for an operation that already happened. | | **An unknown name is a `400`** | With the list of what exists. Ignoring it would return fewer fields than asked for and look like the resource does not have them — a wrong answer wearing a right one's face. | `fields` is the cheapest way to cut the context an agent spends: a list of 300 invoices with three columns fits where the same list in full would not. ## `billing_schemas_get` — the field catalogue[​](#billing_schemas_get--the-field-catalogue "Direct link to billing_schemas_get--the-field-catalogue") `fields` only helps if you know what to ask for, and a model left guessing will try `invoice.amount` when the contract says `total`. `billing_schemas_get` answers that directly: ``` { "name": "billing_schemas_get", "arguments": {} } { "name": "billing_schemas_get", "arguments": { "resource": "invoice" } } ``` With no argument it returns the resource catalogue. With `resource`, it returns every field of that resource — name, type, enum, nullability, description — and, separately, its `sortable_fields`. It comes from the same schemas that generate the published OpenAPI, so the list the tool reports and the one this documentation publishes cannot diverge. ## Data contract[​](#data-contract "Direct link to Data contract") What holds for the v1 API holds here, because it is the same code: * **snake\_case everywhere**, arguments and responses. * **Money is a float in BRL**, in both directions, with no unit suffix. `amount: 100` is R$ 100.00; pricing fields take up to 4 decimals. * **Dates in ISO 8601**, processed in UTC. * **Writes accept `idempotency_key`** — see [Idempotency](https://docs.billing.kobana.com.br/en/en/mcp/overview/idempotency.md). --- # Rate Limiting The MCP server shares the **same limits as the REST API**, counted **per person and organization** — the token's `sub` and `org`, not the token itself. Switching tokens does not reset the budget: a new token, whether from a fresh OAuth authorization or a new personal token, for the same person in the same organization lands in the same bucket. The same person in another organization has a budget of its own. A tool call is **never cheaper than the endpoint it mirrors**: the request is counted once in the MCP's own bucket and, when it is a `tools/call`, again by the bucket of the endpoint it dispatches to. That is deliberate — an agent looping over listings should not be able to dodge the limit the same sweep would pay over REST. Attempts with an invalid token are throttled **by IP**, not by token, the same way the REST edge does it: a token that does not verify cannot have a bucket of its own. A request with no token at all — every client's first step, before OAuth — does not count as an attempt. ## When the limit is hit[​](#when-the-limit-is-hit "Direct link to When the limit is hit") The server answers `429` — **the JSON-RPC message is not processed at all**: ``` HTTP/1.1 429 Too Many Requests Retry-After: 37 X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1793280037 Cache-Control: no-store Content-Type: application/json { "error": { "code": "TOO_MANY_REQUESTS", "message": "Rate limit exceeded" }, "retry_after": 37 } ``` Wait the `Retry-After` seconds before the next request. `X-RateLimit-Limit` and `X-RateLimit-Remaining` give the bucket size and what is left of it; `X-RateLimit-Reset` is when it refills, in seconds since the Unix epoch. The per-account, per-request-type limits are on the [API rate-limit page](https://docs.billing.kobana.com.br/en/en/api/overview/rate-limit.md) — they are the same ones. ## Spending less[​](#spending-less "Direct link to Spending less") An agent burns the same budget as your backend, and additionally pays context for every row it brings back. Two habits cover almost everything: * **Filter before paginating.** `billing_invoices_list { status: "open", due_date_lte: "2026-09-30" }` costs one request; sweeping every invoice to filter in the model costs dozens. * **Ask only for the columns you need.** `fields: ["number", "total", "due_date"]` does not reduce the number of requests, but it greatly reduces the context spent — see [Listing, sorting and fields](https://docs.billing.kobana.com.br/en/en/mcp/overview/pagination.md). --- # Resources and prompts Besides tools, the server offers three things the **client** uses on its own: **resources** (documents the user attaches to the conversation), **prompts** (ready-made scripts the user picks) and **completions** (autocomplete for their arguments). On the `2026-07-28` era it also asks for **confirmation** before running a destructive tool. None of this opens a new path to your data: everything goes through the same tools, under the same permissions and the same [token scope](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md#token-scope). With a read-only token, resources and completions stay available, but a prompt that writes — like `collect_overdue_invoices`, which sends reminders — is not listed. ## Resources[​](#resources "Direct link to Resources") A resource is a document identified by a URI. The user picks, say, an invoice, and the client reads the document and puts it in context, without the model having to call a tool. | URI | What comes back | | ------------------------------------- | --------------------------------------------------------------------- | | `kobana://billing/organization` | The token's organization (JSON) | | `kobana://billing/schemas` | The API's resource catalogue (JSON) | | `kobana://billing/schemas/{resource}` | One resource's fields: type, enum, meaning, which are sortable (JSON) | | `kobana://billing/customers/{id}` | One customer (JSON) | | `kobana://billing/subscriptions/{id}` | One subscription (JSON) | | `kobana://billing/invoices/{id}` | One invoice (JSON) | | `kobana://billing/invoices/{id}/pdf` | The invoice PDF | | `kobana://billing/nfes/{id}` | One NF-e (JSON) | | `kobana://billing/nfes/{id}/pdf` | The NF-e DANFE | | `kobana://billing/nfes/{id}/xml` | The authorized NF-e XML (text) | `resources/list` returns the fixed URIs and `resources/templates/list` the templates with `{id}`. * **Permissions.** Each resource is read by the matching tool (`kobana://billing/invoices/{id}` is `billing_invoices_get`). It is only listed, and only read, if you can run that tool. * **Binaries.** PDFs come back base64-encoded (`blob`), up to **10 MB**. Unlike the tools, which only describe the file, here the document is the answer: the client asked for it. * **Not found.** An unknown URI, or a record that does not exist in this organization, is `-32002` on the 2025 era and `-32602` on `2026-07-28` — see [Errors](https://docs.billing.kobana.com.br/en/en/mcp/overview/errors.md). * **No change subscriptions.** The server is stateless: there is no `resources/subscribe` and no list-changed notice. ## Prompts[​](#prompts "Direct link to Prompts") A prompt is a ready-made instruction you pick in the client, which becomes the first message of the conversation. It is only listed if you can run **all** the tools it relies on. | Prompt | Arguments | What it does | | -------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | `collect_overdue_invoices` | `customer_id` (optional) | Lists open invoices past due, shows a table and **asks** which ones should get a reminder before sending any. | | `review_pending_nfes` | — | Gathers invoices that still have no NF-e and the rejected NF-e, summarises them and suggests the next step, without issuing anything. | | `customer_overview` | `customer_id` | One customer's picture: their data, subscriptions, what is open and what is overdue. | | `monthly_billing_summary` | `month` (optional, `YYYY-MM`) | What was invoiced, collected and left open in the month. | A missing required argument, or a malformed `month`, is `-32602`. ## Completions[​](#completions "Direct link to Completions") `completion/complete` suggests values while you type an argument: * **Ids** (`customer_id`, and the `{id}` of customers, invoices and subscriptions): searches the matching listing, under its permission. If you cannot list, there is no suggestion. * **`{resource}` in `kobana://billing/schemas/{resource}`**: the catalogue names, by prefix. * **`month`**: the last twelve months. With no source for suggestions, the answer is an empty list and you keep typing. ## Confirming destructive tools[​](#confirming-destructive-tools "Direct link to Confirming destructive tools") Destructive tools — the ones that delete, void, cancel or archive in bulk; charge, pay, refund, mark paid or apply credit; issue or cancel a fiscal document; send an e-mail, invite, reminder or proposal, or publish a public link; or change the receiving bank account or Pix key — carry `destructiveHint`. The **server** does not rely on the client alone: on the `2026-07-28` era it asks for confirmation itself: 1. The first `tools/call` runs nothing. It comes back with `resultType: "input_required"` and a one-question form: run this action, with these arguments? 2. The client shows the question and re-sends the same call with your answer. 3. Only an explicit **yes** runs it. Declining or cancelling returns an `isError` result with `USER_DECLINED`, and nothing changes. The confirmation holds **only for that call**: the same tool, the same arguments, the same person and organization, for **5 minutes**. An answer cannot be reused for another invoice or another action; if anything does not match, the server simply asks again. And it is **single-use**: re-sending a call that was already confirmed returns `isError` with `confirmation_replayed`, and nothing runs — to repeat the action, call the tool again and confirm again. ### Client without the confirmation form: approval by link[​](#client-without-the-confirmation-form-approval-by-link "Direct link to Client without the confirmation form: approval by link") A client that **cannot confirm in the chat** — on the 2025 era, or on `2026-07-28` without declaring elicitation forms (the Claude mobile app, for instance) — can still use destructive tools, through an **approval link**. The call **runs nothing**: the server records the operation as pending and answers with a success, in a single JSON text: ``` { "status": "approval_required", "approval": { "id": "6f0c2d1e-…", "url": "https://app.billing.kobana.com.br/approvals/…", "expires_at": "2026-10-31T12:15:00.000Z" }, "message": "… Show this URL to the user … Do not call the tool again … After the user says they decided, call `billing_operation_approvals_get` with this `approval.id` …" } ``` 1. The assistant shows the URL. Do not call the tool again: that would create another approval. 2. You open the link **signed in to Automatic Billing** (without a session, it goes through the login and back to the link). The page shows what will happen ("Pay the invoice", "Delete the customer"), who asked, when, the organization, the record's current data and **every** argument — each item of a batch, one by one. The raw arguments are under "Technical details". 3. **Continue** runs the operation right away, with the permissions you hold **now**: if you lost the permission since the request, the run fails and nothing changes. **Cancel** closes it without running anything. The link is valid for **15 minutes** and decides **once**: two clicks on Continue run once, and an expired or cancelled link never runs. Only **you** — the person behind the token that made the call — can open the link: for anyone else, even in your organization, it does not exist. Your approvals are under **System → Approvals** in the dashboard, with tabs by status; clicking a row opens the approval read-only (a pending one is decided through the link the assistant showed). #### After the decision: the outcome in the chat itself[​](#after-the-decision-the-outcome-in-the-chat-itself "Direct link to After the decision: the outcome in the chat itself") The same session that asked for the operation reads what happened, without you copying anything from the page. Once you tell the assistant you decided, it calls `billing_operation_approvals_get` **once** with the `approval.id` from the answer — never polling in a loop while you have not decided: ``` { "data": { "id": "6f0c2d1e-…", "status": "executed", "action": "billing_invoices_pay", "title": "Pay the invoice", "resource": "invoices", "operation": "pay", "amount": 150.5, "requested_at": "2026-10-31T12:00:00.000Z", "expires_at": "2026-10-31T12:15:00.000Z", "decided_at": "2026-10-31T12:03:10.000Z", "executed_at": "2026-10-31T12:03:11.000Z", "error": null, "result": { "data": { "id": "…", "status": "paid" } }, "result_hidden": false } } ``` | `status` | What it means | | ---------- | ----------------------------------------------------------------------------------------------------------- | | `pending` | Not decided yet. | | `approved` | You chose Continue and the run is in progress. | | `executed` | Ran: `result` has what the tool returned, with secrets masked (the clear value is shown once, on the page). | | `failed` | Did not run; `error.code` says why (`subject_changed`, a missing permission…). It changed nothing. | | `declined` | You cancelled. Nothing ran. | | `expired` | The link lapsed without a decision. Nothing ran. | `billing_operation_approvals_list` lists your approvals, most recent first, filtered by `status` and by `created_after`/`created_before`. Both tools are read-only — neither approves, cancels or reopens an approval — and need no scope or permission: any token with a person reads its **own** approvals in that organization. Another person's, another organization's or a nonexistent id answer the same `NOT_FOUND`. What the operation returned (`result`, `error` and an `amount` read from the record) comes back only when the token can also read that approval's resource and you still hold a read permission on it: a token narrowed to products sees its approval on an invoice — status, title, dates — but with those fields `null` and `result_hidden: true`. `title` comes in the request's language (`Accept-Language`), and the answer never carries the link or the arguments. Over the REST API, the same is at `GET /v1/operation_approvals` and `GET /v1/operation_approvals/{id}`. If the invoice, payment, account or destination key changes between opening the page and Continue, nothing runs (`subject_changed`): ask for the operation again and review the new link. Raw card data (number or CVV) is never stored to wait for approval: the call returns `confirmation_required` — use a `card_token` or a client with the confirmation form. A token with no person who could open the link gets `isError` with `confirmation_required`. If the server cannot record the approval at that moment, the tool is refused with `confirmation_unavailable`; try again later. Every other tool keeps working as usual. --- # Transport **Streamable HTTP, stateless.** One JSON-RPC 2.0 message per `POST`, one JSON response. There is no `Mcp-Session-Id`, no resumability and no server→client stream: the application runs several replicas, and every long operation already answers immediately and finishes in a background worker rather than on the MCP channel. ## Protocol versions[​](#protocol-versions "Direct link to Protocol versions") The server speaks two eras of the protocol on the same endpoint: | Version | Era | Status | | ------------ | ----------------------------------------------------------------------- | --------- | | `2026-07-28` | Stateless, no handshake — discovered through `server/discover` | Supported | | `2025-06-18` | `initialize` handshake — the version `initialize` settles on by default | Supported | | `2025-03-26` | `initialize` handshake | Supported | The era is decided **by the request body**, with the headers as a cross-check: * **`params._meta` carries `io.modelcontextprotocol/protocolVersion`** → `2026-07-28` era (see below). * **No such envelope**, with a 2025 `MCP-Protocol-Version` or no header at all → 2025 era, with `initialize`. * **`MCP-Protocol-Version: 2026-07-28` without the envelope** → `400` with `-32602`. The server does not silently fall back to the old era: you asked for stateless semantics and would get the other ones. A version the server does not speak — in the header or in the envelope, in either era — is answered `400` with the JSON-RPC error `-32022`, listing the supported ones: ``` { "jsonrpc": "2.0", "id": 1, "error": { "code": -32022, "message": "Unsupported protocol version", "data": { "supported": ["2026-07-28", "2025-06-18", "2025-03-26"], "requested": "1999-01-01" } } } ``` The version in use comes back on the `MCP-Protocol-Version` response header. ### The `2026-07-28` era[​](#the-2026-07-28-era "Direct link to the-2026-07-28-era") There is no handshake: **every** request carries its own version and the client's capabilities in `params._meta`, and the server remembers nothing from one request to the next. | `params._meta` key | Required | Meaning | | -------------------------------------------- | ----------- | --------------------------------------------------- | | `io.modelcontextprotocol/protocolVersion` | yes | `2026-07-28` | | `io.modelcontextprotocol/clientCapabilities` | yes | The client's capabilities (an object; `{}` will do) | | `io.modelcontextprotocol/clientInfo` | recommended | The client's `name` and `version` | The headers repeat what the body says, so intermediaries can route without reading it — which is why they have to agree with it: | Header | Must equal | | ---------------------- | ------------------------------------------------------------- | | `MCP-Protocol-Version` | The envelope version | | `Mcp-Method` | The message `method` | | `Mcp-Name` | On `tools/call` only: `params.name`, raw or as `=?base64?…?=` | Any disagreement is `400` with `-32020` (`Header mismatch: …`). Missing `clientCapabilities` is `400` with `-32602`. Results in this era always carry `resultType: "complete"` and the server in `_meta["io.modelcontextprotocol/serverInfo"]`. `server/discover`, `tools/list`, `resources/list`, `resources/templates/list`, `resources/read` and `prompts/list` also carry `ttlMs: 0` and `cacheScope: "private"`: what comes back is filtered by the caller's permissions, so it must not be reused or shared. A `tools/call` to a destructive tool may come back with `resultType: "input_required"` — see [Confirming destructive tools](https://docs.billing.kobana.com.br/en/en/mcp/overview/resources-and-prompts.md#confirming-destructive-tools). ## Request headers[​](#request-headers "Direct link to Request headers") | Header | Required | Meaning | | ---------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `Authorization` | yes | `Bearer ` issued for MCP — see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md) | | `Content-Type` | yes | `application/json` | | `Accept` | recommended | `application/json` | | `MCP-Protocol-Version` | yes in the `2026-07-28` era; recommended in the 2025 one | Protocol revision | | `Mcp-Method` | yes in the `2026-07-28` era | The message method | | `Mcp-Name` | yes on `tools/call` in the `2026-07-28` era | The tool name | | `Origin` | conditional | Sent by browser-based clients; validated against an allow-list | There is no tenant-selection header: the organization comes from the token itself, and no tool takes an organization argument. The request body is capped at **1 MB**. Above that — by the declared `Content-Length` or by what actually arrives — the answer is `413` with `{ "jsonrpc": "2.0", "id": null, "error": { "code": -32600, "message": "Request body too large (limit 1048576 bytes)" } }`. No tool takes a file, so a legitimate call stays far below it. ## Response headers[​](#response-headers "Direct link to Response headers") | Header | Meaning | | ---------------------- | -------------------------------------------------------------------------------------------------------- | | `MCP-Protocol-Version` | Revision in use | | `Cache-Control` | Always `no-store` | | `Retry-After` | On `429` only — see [Rate limiting](https://docs.billing.kobana.com.br/en/en/mcp/overview/rate-limit.md) | ## Methods[​](#methods "Direct link to Methods") | Method | `2026-07-28` era | 2025 era | Purpose | | -------------------------- | ---------------- | -------- | ---------------------------------------------------------------------------- | | `server/discover` | yes | — | Supported versions, server capabilities and instructions | | `initialize` | — | yes | Version negotiation, server capabilities and instructions | | `ping` | — | yes | Liveness check; answers an empty result | | `tools/list` | yes | yes | The tools this caller can run, with their JSON Schema and annotations | | `tools/call` | yes | yes | Runs one tool | | `resources/list` | yes | yes | The fixed-URI documents this caller can read | | `resources/templates/list` | yes | yes | The URI templates (`kobana://billing/invoices/{id}`, …) this caller can read | | `resources/read` | yes | yes | Reads one document by URI | | `prompts/list` | yes | yes | The ready-made prompts this caller can use | | `prompts/get` | yes | yes | Renders one prompt with the given arguments | | `completion/complete` | yes | yes | Suggestions for a prompt or template argument | Resources, prompts and completions are covered in [Resources and prompts](https://docs.billing.kobana.com.br/en/en/mcp/overview/resources-and-prompts.md). Any other method is `-32601 Method not found` — with HTTP `404` in the `2026-07-28` era, in the body of a `200` in the 2025 one. **JSON-RPC batching is not supported** — it was removed in the `2025-06-18` revision, and an array body is answered `400`. A **notification** (a message with no `id`, such as `notifications/initialized`) is accepted with `202` and an empty body, in both eras. Authentication comes **before** any method, `server/discover` included: with no token, the answer is the `401` with the challenge that sends the client to the OAuth login — see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). ### `server/discover` (`2026-07-28` era)[​](#serverdiscover-2026-07-28-era "Direct link to serverdiscover-2026-07-28-era") ``` POST / HTTP/1.1 Authorization: Bearer Content-Type: application/json MCP-Protocol-Version: 2026-07-28 Mcp-Method: server/discover ``` ``` { "jsonrpc": "2.0", "id": 1, "method": "server/discover", "params": { "_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientCapabilities": {}, "io.modelcontextprotocol/clientInfo": { "name": "my-client", "version": "1.0.0" } } } } ``` ``` { "jsonrpc": "2.0", "id": 1, "result": { "resultType": "complete", "supportedVersions": ["2026-07-28", "2025-06-18", "2025-03-26"], "capabilities": { "tools": {}, "resources": {}, "prompts": {}, "completions": {} }, "instructions": "Tools for Kobana Billing: ...", "ttlMs": 0, "cacheScope": "private", "_meta": { "io.modelcontextprotocol/serverInfo": { "name": "kobana-billing", "title": "Kobana Billing", "version": "1.0.0" } } } } ``` ### `initialize` (2025-era handshake)[​](#initialize-2025-era-handshake "Direct link to initialize-2025-era-handshake") ``` { "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-06-18" } } ``` ``` { "jsonrpc": "2.0", "id": 1, "result": { "protocolVersion": "2025-06-18", "capabilities": { "tools": { "listChanged": false }, "resources": { "subscribe": false, "listChanged": false }, "prompts": { "listChanged": false }, "completions": {} }, "serverInfo": { "name": "kobana-billing", "title": "Kobana Billing", "version": "1.0.0" }, "instructions": "Tools for Kobana Billing: ..." } } ``` ### `tools/list`[​](#toolslist "Direct link to toolslist") Returns **only** the tools the caller can run, filtered by the dashboard permissions of whoever authorized the client. Every tool carries `annotations`, which is what makes the client ask the user to confirm: | Annotation | Meaning | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `readOnlyHint` | The tool only reads | | `destructiveHint` | The tool deletes, cancels, charges, refunds, issues a fiscal document or sends something to a third party. The server asks for confirmation in the chat on the `2026-07-28` era with elicitation; any other client gets an approval link, and nothing runs until you choose Continue | | `idempotentHint` | Repeating the call has the same effect | | `openWorldHint` | Always `false` — the tool reaches nothing outside Automatic Billing | ### `tools/call`[​](#toolscall "Direct link to toolscall") ``` { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "billing_invoices_list", "arguments": { "status": "open", "per_page": 10, "fields": ["number", "total", "due_date"] } } } ``` The result carries the endpoint's JSON response as text content: ``` { "jsonrpc": "2.0", "id": 2, "result": { "content": [{ "type": "text", "text": "{ \"data\": [ ... ], \"meta\": { \"total\": 42, ... } }" }] } } ``` Errors the caller can act on come back with `isError: true` **inside** the result, not as a JSON-RPC error — see [Errors](https://docs.billing.kobana.com.br/en/en/mcp/overview/errors.md). ## In-process dispatch[​](#in-process-dispatch "Direct link to In-process dispatch") Every tool dispatches **in-process** to the `/api/v1` route handler that implements the operation. There is no second HTTP round trip and no second implementation: listing filters, upsert matching, validation, soft-delete, proration and tenant isolation are the same code the REST API runs. A tool cannot drift from the endpoint it mirrors. ## Binaries[​](#binaries "Direct link to Binaries") `billing_invoices_pdf`, `billing_nfes_pdf` and `billing_nfes_xml` **do not** return the bytes: a base64 PDF in a model's context is expensive and useless. The result carries the `content_type`, the size and the path to fetch the file from the API host, with a token issued for the API. --- # Catalogue What the organization sells: products and their groups, plans, prices and standalone service items. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | ---------------------------------------- | ----- | ---- | ----- | ----------- | | `products` — Products and product groups | 24 | 4 | 16 | 4 | | `plans` — Plans, prices and groups | 21 | 5 | 12 | 4 | | `services` — Service items | 6 | 2 | 3 | 1 | ## `products`[​](#products "Direct link to products") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------------------- | ----------- | -------- | ----------------- | --------------------------------------- | -------------------------------------------------------------------------------------- | | `billing_products_list` | read | `read` | `products.list` | `GET /v1/products` | List products in the catalog. | | `billing_products_get` | read | `read` | `products.show` | `GET /v1/products/:id` | Fetch one product with its prices. | | `billing_products_create` | write | `write` | `products.create` | `POST /v1/products` | Create a product, optionally with its prices in the same call. | | `billing_products_upsert` | write | `write` | `products.create` | `PUT /v1/products` | Create or update a product matched on `id` → `external_id` → `slug`. | | `billing_products_update` | write | `write` | `products.update` | `PATCH /v1/products/:id` | Update a product in place. | | `billing_products_delete` | destructive | `delete` | `products.delete` | `DELETE /v1/products/:id` | Delete a product: it disappears from every read and leaves every plan. | | `billing_products_publish` | write | `write` | `products.update` | `POST /v1/products/:id/publish` | Move a draft product to `active`, making it sellable. | | `billing_products_archive` | write | `write` | `products.update` | `POST /v1/products/:id/archive` | Archive a product: it stops being sellable but existing subscriptions keep billing it. | | `billing_products_restore` | write | `write` | `products.update` | `POST /v1/products/:id/restore` | Bring an archived product back to `active`. | | `billing_products_reorder` | write | `write` | `products.update` | `POST /v1/products/reorder` | Set the catalog display order. | | `billing_products_bulk_archive` | destructive | `write` | `products.update` | `POST /v1/products/bulk-archive` | Archive up to 100 products in one call. | | `billing_products_bulk_delete` | destructive | `delete` | `products.delete` | `DELETE /v1/products/bulk` | Soft-delete up to 100 products in one call. | | `billing_products_bulk_move_group` | write | `write` | `products.update` | `POST /v1/products/bulk-move-group` | Move products to a product group. | | `billing_products_bulk_change_company` | write | `write` | `products.update` | `POST /v1/products/bulk-change-company` | Reassign the issuing legal entity of several products. | | `billing_products_bulk_visibility` | write | `write` | `products.update` | `POST /v1/products/bulk-visibility` | Set several products public or private at once. | | `billing_product_groups_list` | read | `read` | `products.list` | `GET /v1/product_groups` | List product groups — the catalog sections products are filed under. | | `billing_product_groups_get` | read | `read` | `products.show` | `GET /v1/product_groups/:id` | Fetch one product group with its display order. | | `billing_product_groups_create` | write | `write` | `products.create` | `POST /v1/product_groups` | Create a product group to file products under. | | `billing_product_groups_upsert` | write | `write` | `products.create` | `PUT /v1/product_groups` | Create or update a product group matched on `id` → `external_id` → `slug`. | | `billing_product_groups_update` | write | `write` | `products.update` | `PATCH /v1/product_groups/:id` | Update a product group — name, slug, company or display order. | | `billing_product_groups_delete` | destructive | `delete` | `products.delete` | `DELETE /v1/product_groups/:id` | Soft-delete a product group. | | `billing_product_groups_archive` | write | `write` | `products.update` | `POST /v1/product_groups/:id/archive` | Archive a product group, hiding it from the catalog. | | `billing_product_groups_unarchive` | write | `write` | `products.update` | `POST /v1/product_groups/:id/unarchive` | Bring an archived product group back into the catalog. | | `billing_product_groups_reorder` | write | `write` | `products.update` | `POST /v1/product_groups/reorder` | Set the display order of product groups. | ## `plans`[​](#plans "Direct link to plans") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ------------------------------- | ----------- | -------- | -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------ | | `billing_plans_list` | read | `read` | `plans.list` | `GET /v1/plans` | List plans — the bundles of products a subscription can point at. | | `billing_plans_get` | read | `read` | `plans.show` | `GET /v1/plans/:id` | Fetch one plan with its items. | | `billing_plans_create` | write | `write` | `plans.create` | `POST /v1/plans` | Create a plan, optionally with its items in the same call. | | `billing_plans_upsert` | write | `write` | `plans.create` | `PUT /v1/plans` | Create or update a plan matched on `id` → `external_id` → `slug`. | | `billing_plans_update` | write | `write` | `plans.update` | `PATCH /v1/plans/:id` | Update a plan in place. | | `billing_plans_delete` | destructive | `delete` | `plans.delete` | `DELETE /v1/plans/:id` | Delete a plan: it disappears from every read. | | `billing_plans_archive` | write | `write` | `plans.update` | `POST /v1/plans/:id/archive` | Archive a plan: it closes to new subscriptions but stays listed, and existing subscriptions keep billing it. | | `billing_plans_duplicate` | write | `write` | `plans.create` | `POST /v1/plans/:id/duplicate` | Copy a plan and its items into a new draft plan. | | `billing_plans_items_list` | read | `read` | `plans.show` | `GET /v1/plans/:id/items` | List the items of a plan — which product, at which price, in which quantity. | | `billing_plans_items_replace` | write | `write` | `plans.update` | `PUT /v1/plans/:id/items` | Replace every item of a plan atomically. | | `billing_plans_bulk_archive` | destructive | `write` | `plans.update` | `POST /v1/plans/bulk-archive` | Archive up to 100 plans in one call. | | `billing_plans_bulk_delete` | destructive | `delete` | `plans.delete` | `DELETE /v1/plans/bulk` | Soft-delete up to 100 plans in one call. | | `billing_plans_bulk_move_group` | write | `write` | `plans.update` | `POST /v1/plans/bulk-move-group` | Move plans to a plan group. | | `billing_plan_groups_list` | read | `read` | `plans.list` | `GET /v1/plan_groups` | List plan groups — the sections plans are filed under in the catalog. | | `billing_plan_groups_get` | read | `read` | `plans.show` | `GET /v1/plan_groups/:id` | Fetch one plan group with its display order. | | `billing_plan_groups_create` | write | `write` | `plans.create` | `POST /v1/plan_groups` | Create a plan group to file plans under. | | `billing_plan_groups_upsert` | write | `write` | `plans.create` | `PUT /v1/plan_groups` | Create or update a plan group matched on `id` → `external_id` → `slug`. | | `billing_plan_groups_update` | write | `write` | `plans.update` | `PATCH /v1/plan_groups/:id` | Update a plan group — name, slug, description or display order. | | `billing_plan_groups_delete` | destructive | `delete` | `plans.delete` | `DELETE /v1/plan_groups/:id` | Soft-delete a plan group. | | `billing_plan_groups_archive` | write | `write` | `plans.update` | `POST /v1/plan_groups/:id/archive` | Archive a plan group, hiding it from the catalog without touching its plans. | | `billing_plan_groups_reorder` | write | `write` | `plans.update` | `POST /v1/plan_groups/reorder` | Set the display order of plan groups. | ## `services`[​](#services "Direct link to services") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ------------------------------ | ----------- | -------- | ----------------- | ------------------------------ | -------------------------------------------------------------------------------------------- | | `billing_service_items_list` | read | `read` | `services.list` | `GET /v1/service_items` | List fiscal service items — the LC 116 / NBS classification an invoice line is issued under. | | `billing_service_items_get` | read | `read` | `services.show` | `GET /v1/service_items/:id` | Fetch one service item with its fiscal codes and default ISS rate. | | `billing_service_items_create` | write | `write` | `services.create` | `POST /v1/service_items` | Create a fiscal service item for products to be invoiced under. | | `billing_service_items_upsert` | write | `write` | `services.create` | `PUT /v1/service_items` | Create or update a service item matched on `id` → `external_id` → `internal_code`. | | `billing_service_items_update` | write | `write` | `services.update` | `PATCH /v1/service_items/:id` | Update a service item. | | `billing_service_items_delete` | destructive | `delete` | `services.delete` | `DELETE /v1/service_items/:id` | Soft-delete a service item. | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Customers and access Customers, their billing accounts, the users who sign in to the portal, and the team that uses the organization dashboard. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | -------------------------------------------- | ----- | ---- | ----- | ----------- | | `customers` — Customers and billing accounts | 19 | 6 | 9 | 4 | | `portal-users` — Portal users | 9 | 4 | 2 | 3 | | `users` — Dashboard users | 6 | 2 | 1 | 3 | | `roles` — Team roles | 6 | 2 | 3 | 1 | ## `customers`[​](#customers "Direct link to customers") | Tool | Kind | Scope | Permission | Endpoint | What it does | | --------------------------------------- | ----------- | -------- | ---------------------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `billing_customers_list` | read | `read` | `customers.list` | `GET /v1/customers` | List the customers of the token organization. | | `billing_customers_get` | read | `read` | `customers.show` | `GET /v1/customers/:id` | Fetch one customer by id, `public_id` or `external_id`. | | `billing_customers_create` | write | `write` | `customers.create` | `POST /v1/customers` | Create a customer and, unless `create_billing_account` is false, the billing account that bills it. | | `billing_customers_upsert` | write | `write` | `customers.create` | `PUT /v1/customers` | Create or update a customer, matched on `id` → `public_id` → `external_id` → `document_number`, stopping at the first hit. | | `billing_customers_update` | write | `write` | `customers.update` | `PATCH /v1/customers/:id` | Update a customer in place. | | `billing_customers_delete` | destructive | `delete` | `customers.delete` | `DELETE /v1/customers/:id` | Soft-delete a customer (`deleted_at`). | | `billing_customers_recalculate_mrr` | write | `write` | `customers.update` | `POST /v1/customers/:id/recalculate-mrr` | Recompute the customer MRR from its active subscriptions. | | `billing_customers_statement` | read | `read` | `customers.show` | `GET /v1/customers/:id/statement` | Account statement for a customer: invoices, payments, credits and the running balance. | | `billing_customers_statement_sync` | write | `write` | `customers.update` | `POST /v1/customers/:id/statement/sync` | Recompute and persist the customer statement snapshot. | | `billing_billing_accounts_list` | read | `read` | `customers.list` | `GET /v1/billing_accounts` | List billing accounts. | | `billing_billing_accounts_get` | read | `read` | `customers.show` | `GET /v1/billing_accounts/:id` | Fetch one billing account by id, `public_id` or `external_id`. | | `billing_billing_accounts_create` | write | `write` | `customers.create` | `POST /v1/billing_accounts` | Open a billing account for an existing customer. | | `billing_billing_accounts_upsert` | write | `write` | `customers.create` | `PUT /v1/billing_accounts` | Create or update a billing account matched on `id` → `public_id` → `external_id`. | | `billing_billing_accounts_update` | write | `write` | `customers.update` | `PATCH /v1/billing_accounts/:id` | Update a billing account in place. | | `billing_billing_accounts_delete` | destructive | `delete` | `customers.delete` | `DELETE /v1/billing_accounts/:id` | Delete a billing account, with its payment methods, cards, portal users and files: they disappear from every read. | | `billing_billing_accounts_suspend` | destructive | `write` | `customers.suspend` | `POST /v1/billing_accounts/:id/suspend` | Suspend a billing account. | | `billing_billing_accounts_reactivate` | write | `write` | `customers.reactivate` | `POST /v1/billing_accounts/:id/reactivate` | Lift a suspension and resume collection on a billing account. | | `billing_billing_accounts_close` | destructive | `write` | `customers.delete` | `POST /v1/billing_accounts/:id/close` | Close a billing account for good. | | `billing_billing_accounts_entitlements` | read | `read` | `customers.show` | `GET /v1/billing_accounts/:id/entitlements` | What this billing account is entitled to right now, derived from its active subscriptions — the answer to "can this customer use feature X?". | ## `portal-users`[​](#portal-users "Direct link to portal-users") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------------------- | ----------- | -------- | --------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `billing_customer_users_list` | read | `read` | `portal-users.list` | `GET /v1/customers/:id/users` | List the portal users attached to a customer. | | `billing_customer_users_create` | write | `write` | `portal-users.create` | `POST /v1/customers/:id/users` | Attach a portal user to a customer without sending an invitation e-mail. | | `billing_customer_users_invite` | destructive | `write` | `portal-users.create` | `POST /v1/customers/:id/users/invite` | Invite a portal user to a customer — creates the user and sends the invitation e-mail. | | `billing_customer_users_get` | read | `read` | `portal-users.show` | `GET /v1/customers/:id/users/:user_id` | Fetch one portal user of a customer. | | `billing_customer_users_update` | write | `write` | `portal-users.update` | `PATCH /v1/customers/:id/users/:user_id` | Update a portal user of a customer (name, role, status). | | `billing_customer_users_delete` | destructive | `delete` | `portal-users.delete` | `DELETE /v1/customers/:id/users/:user_id` | Delete a portal user (a pending invitation included): the user loses portal access immediately and the email can be invited again. | | `billing_customer_users_resend_invite` | destructive | `write` | `portal-users.update` | `POST /v1/customers/:id/users/:user_id/resend` | Re-send the portal invitation e-mail to a customer user. | | `billing_customer_users_email_preview` | read | `read` | `portal-users.show` | `GET /v1/customers/:id/users/:user_id/email-preview` | Render the invitation e-mail for a customer user without sending it — subject and HTML, as the recipient would see it. | | `billing_portal_users_list` | read | `read` | `portal-users.list` | `GET /v1/portal_users` | List every portal user of the organization, across customers. | ## `users`[​](#users "Direct link to users") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------------- | ----------- | -------- | -------------- | -------------------------------- | ---------------------------------------------------------------------------- | | `billing_dashboard_users_list` | read | `read` | `users.list` | `GET /v1/dashboard_users` | List the dashboard (team) users of the organization. | | `billing_dashboard_users_get` | read | `read` | `users.show` | `GET /v1/dashboard_users/:id` | Fetch one dashboard user with the roles they hold. | | `billing_dashboard_users_create` | destructive | `write` | `users.create` | `POST /v1/dashboard_users` | Add a dashboard user to the organization and assign a role. | | `billing_dashboard_users_upsert` | destructive | `write` | `users.create` | `PUT /v1/dashboard_users` | Create or update a dashboard user matched on `id` → `external_id` → `email`. | | `billing_dashboard_users_update` | write | `write` | `users.update` | `PATCH /v1/dashboard_users/:id` | Update a dashboard user — name, role or status. | | `billing_dashboard_users_delete` | destructive | `delete` | `users.delete` | `DELETE /v1/dashboard_users/:id` | Remove a dashboard user. | ## `roles`[​](#roles "Direct link to roles") | Tool | Kind | Scope | Permission | Endpoint | What it does | | --------------------------- | ----------- | -------- | -------------- | --------------------------- | --------------------------------------------------------------------- | | `billing_team_roles_list` | read | `read` | `roles.list` | `GET /v1/team_roles` | List the roles a dashboard user can hold, with their permission sets. | | `billing_team_roles_get` | read | `read` | `roles.show` | `GET /v1/team_roles/:id` | Fetch one role with its permissions. | | `billing_team_roles_create` | write | `write` | `roles.create` | `POST /v1/team_roles` | Create a custom role with an explicit permission list. | | `billing_team_roles_upsert` | write | `write` | `roles.create` | `PUT /v1/team_roles` | Create or update a role matched on `id` → `external_id` → `slug`. | | `billing_team_roles_update` | write | `write` | `roles.update` | `PATCH /v1/team_roles/:id` | Update a custom role. | | `billing_team_roles_delete` | destructive | `delete` | `roles.delete` | `DELETE /v1/team_roles/:id` | Delete a custom role. | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Tax and invoicing (NF-e) NF-e issuance, the issuing companies and their digital certificates, tax rules and computation periods, and taxes withheld at source. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | ------------------------------------- | ----- | ---- | ----- | ----------- | | `nfes` — Tax invoices (NF-e) | 24 | 8 | 10 | 6 | | `companies` — Issuing companies | 12 | 4 | 6 | 2 | | `certificates` — Digital certificates | 3 | 2 | 0 | 1 | | `tax-rules` — Tax rules | 6 | 2 | 3 | 1 | | `tax-periods` — Tax periods | 5 | 2 | 2 | 1 | | `withholdings` — Withholdings | 8 | 2 | 3 | 3 | ## `nfes`[​](#nfes "Direct link to nfes") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------------- | ----------- | -------- | ------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | | `billing_invoices_issue_nfe` | destructive | `write` | `nfes.create` | `POST /v1/invoices/:id/issue-nfe` | Issue the NFe for an invoice now, outside the automatic issuance policy. | | `billing_nfes_list` | read | `read` | `nfes.list` | `GET /v1/nfes` | List NFes. | | `billing_nfes_get` | read | `read` | `nfes.show` | `GET /v1/nfes/:id` | Fetch one NFe with its status and tax breakdown. | | `billing_nfes_create` | write | `write` | `nfes.create` | `POST /v1/nfes` | Create an NFe record. | | `billing_nfes_upsert` | write | `write` | `nfes.create` | `PUT /v1/nfes` | Create or update an NFe matched on `id` → `external_id`. | | `billing_nfes_update` | write | `write` | `nfes.update` | `PATCH /v1/nfes/:id` | Update an NFe. | | `billing_nfes_delete` | destructive | `delete` | `nfes.update` | `DELETE /v1/nfes/:id` | Soft-delete an NFe record. | | `billing_nfes_issue` | destructive | `write` | `nfes.create` | `POST /v1/nfes/:id/issue` | Transmit an NFe to the municipality. | | `billing_nfes_cancel` | destructive | `write` | `nfes.cancel` | `POST /v1/nfes/:id/cancel` | Cancel an issued NFe at the municipality. | | `billing_nfes_retry_cancel` | destructive | `write` | `nfes.retry` | `POST /v1/nfes/:id/retry-cancel` | Retry a cancellation that failed at the municipality. | | `billing_nfes_sync` | write | `write` | `nfes.update` | `POST /v1/nfes/:id/sync` | Re-read one NFe from the provider and update its local status. | | `billing_nfes_sync_all` | write | `write` | `nfes.update` | `POST /v1/nfes/sync` | Re-read every pending NFe of the organization from the provider. | | `billing_nfes_validate_barueri` | write | `write` | `nfes.show` | `POST /v1/nfes/:id/validate-barueri` | Validate an NFe against the Barueri municipal service before issuing it. | | `billing_nfes_pdf` | read | `read` | `nfes.show` | `GET /v1/nfes/:id/pdf` | Metadata for the NFe PDF (DANFSe). | | `billing_nfes_xml` | read | `read` | `nfes.show` | `GET /v1/nfes/:id/xml` | Metadata for the NFe XML. | | `billing_nfes_requests_list` | read | `read` | `nfes.show` | `GET /v1/nfes/:id/requests` | Request/response log between this service and the NFe provider for one note — the first place to look when an issuance fails. | | `billing_nfes_requests_get` | read | `read` | `nfes.show` | `GET /v1/nfes/:id/requests/:requestId` | Fetch one provider request/response pair in full. | | `billing_nfes_request_tries` | read | `read` | `nfes.show` | `GET /v1/nfes/:id/request-tries` | Issuance attempts for one NFe, with the error that stopped each. | | `billing_nfes_request_tries_all` | read | `read` | `nfes.list` | `GET /v1/nfes/request-tries` | Issuance attempts across every NFe of the organization, newest first. | | `billing_nfes_bulk_link_invoice` | write | `write` | `nfes.update` | `POST /v1/nfes/bulk` | Link up to 100 NFes to an invoice, or unlink them with `invoice_id: null`. | | `billing_nfes_bulk_delete` | destructive | `delete` | `nfes.update` | `DELETE /v1/nfes/bulk` | Soft-delete up to 100 NFe records in one call. | | `billing_nfes_fetch_from_sefaz` | write | `write` | `nfes.create` | `POST /v1/nfes/fetch-from-sefaz` | Fetch an NFe from SEFAZ by its access key, signed with one of the organization certificates. | | `billing_nfes_fetch_barueri` | write | `write` | `nfes.show` | `POST /v1/nfes/fetch-barueri` | Look a Barueri NFSe up by its authenticity code without importing it — use to check before `billing_nfes_import_barueri`. | | `billing_nfes_import_barueri` | write | `import` | `nfes.create` | `POST /v1/nfes/import-barueri` | Import a Barueri NFSe into the organization. | ## `companies`[​](#companies "Direct link to companies") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ----------------------------------------- | ----------- | -------- | ------------------ | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | | `billing_companies_list` | read | `read` | `companies.list` | `GET /v1/companies` | List the legal entities that issue invoices and NFes for this organization. | | `billing_companies_get` | read | `read` | `companies.show` | `GET /v1/companies/:id` | Fetch one legal entity with its addresses and default flag. | | `billing_companies_matriz` | read | `read` | `companies.show` | `GET /v1/companies/matriz` | Fetch the head office (matriz) — the company with no parent. | | `billing_companies_create` | write | `write` | `companies.create` | `POST /v1/companies` | Create a legal entity. | | `billing_companies_upsert` | write | `write` | `companies.create` | `PUT /v1/companies` | Create or update a company matched on `id` → `external_id` → `document_number`. | | `billing_companies_update` | write | `write` | `companies.update` | `PATCH /v1/companies/:id` | Update a company. | | `billing_companies_delete` | destructive | `delete` | `companies.delete` | `DELETE /v1/companies/:id` | Delete a company: it disappears from every read (its invoices and NFes keep naming it). | | `billing_companies_set_default` | write | `write` | `companies.update` | `POST /v1/companies/:id/set-default` | Make this the default issuing entity — used whenever an invoice or NFe names no company. | | `billing_companies_deactivate` | destructive | `write` | `companies.update` | `POST /v1/companies/:id/deactivate` | Deactivate a company: no new invoice or NFe can be issued under it. | | `billing_companies_reactivate` | write | `write` | `companies.update` | `POST /v1/companies/:id/reactivate` | Reactivate a company so invoices and NFes can be issued under it again. | | `billing_companies_fiscal_profile_get` | read | `read` | `companies.show` | `GET /v1/companies/:id/fiscal` | Read the fiscal profile of a company: taxation regime, Simples annex, RBT12, factor R and every tax rate used to price an invoice. | | `billing_companies_fiscal_profile_update` | write | `write` | `companies.update` | `PATCH /v1/companies/:id/fiscal` | Upsert the fiscal profile of a company. | ## `certificates`[​](#certificates "Direct link to certificates") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ----------------------------- | ----------- | -------- | --------------------- | ----------------------------- | ------------------------------------------------------------------ | | `billing_certificates_list` | read | `read` | `certificates.list` | `GET /v1/certificates` | List the digital certificates used to sign NFes. | | `billing_certificates_get` | read | `read` | `certificates.show` | `GET /v1/certificates/:id` | Fetch one certificate: subject, serial number and validity window. | | `billing_certificates_delete` | destructive | `delete` | `certificates.delete` | `DELETE /v1/certificates/:id` | Remove a certificate. | ## `tax-rules`[​](#tax-rules "Direct link to tax-rules") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------- | ----------- | -------- | ------------------ | -------------------------- | ------------------------------------------------------------ | | `billing_tax_rules_list` | read | `read` | `tax-rules.list` | `GET /v1/tax_rules` | List tax rules, most specific scope first. | | `billing_tax_rules_get` | read | `read` | `tax-rules.show` | `GET /v1/tax_rules/:id` | Fetch one tax rule with its items. | | `billing_tax_rules_create` | write | `write` | `tax-rules.create` | `POST /v1/tax_rules` | Create a tax rule with its items. | | `billing_tax_rules_upsert` | write | `write` | `tax-rules.create` | `PUT /v1/tax_rules` | Create or update a tax rule matched on `id` → `external_id`. | | `billing_tax_rules_update` | write | `write` | `tax-rules.update` | `PATCH /v1/tax_rules/:id` | Update a tax rule. | | `billing_tax_rules_delete` | destructive | `delete` | `tax-rules.delete` | `DELETE /v1/tax_rules/:id` | Delete a tax rule. | ## `tax-periods`[​](#tax-periods "Direct link to tax-periods") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ----------------------------------- | ----------- | -------- | -------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------- | | `billing_tax_periods_list` | read | `read` | `tax-periods.list` | `GET /v1/tax_periods` | List fiscal periods (apurações) with their gross revenue and estimated DAS. | | `billing_tax_periods_get` | read | `read` | `tax-periods.show` | `GET /v1/tax_periods/:id` | Fetch one fiscal period with its computed taxes. | | `billing_tax_periods_process_month` | write | `write` | `tax-periods.create` | `POST /v1/tax_periods` | Compute (or recompute) the monthly fiscal period of a company. | | `billing_tax_periods_action` | write | `write` | `tax-periods.update` | `PATCH /v1/tax_periods/:id` | Act on a fiscal period: `recalculate` (monthly only), `close` to freeze it, or `reopen` to unfreeze. | | `billing_tax_periods_delete` | destructive | `delete` | `tax-periods.update` | `DELETE /v1/tax_periods/:id` | Delete a fiscal period. | ## `withholdings`[​](#withholdings "Direct link to withholdings") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ----------------------------------------- | ----------- | -------- | --------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | `billing_withholdings_list` | read | `read` | `withholdings.list` | `GET /v1/withholdings` | List tax withholdings (retenções). | | `billing_withholdings_get` | read | `read` | `withholdings.show` | `GET /v1/withholdings/:id` | Fetch one tax withholding with how much of it has been compensated. | | `billing_withholdings_create` | write | `write` | `withholdings.create` | `POST /v1/withholdings` | Record a tax withheld at source by a customer, against an invoice or an NFe. | | `billing_withholdings_upsert` | write | `write` | `withholdings.create` | `PUT /v1/withholdings` | Create or update a withholding matched on `id` → `external_id`. | | `billing_withholdings_update` | write | `write` | `withholdings.update` | `PATCH /v1/withholdings/:id` | Update a withholding — its base, amount or competence period. | | `billing_withholdings_delete` | destructive | `delete` | `withholdings.delete` | `DELETE /v1/withholdings/:id` | Soft-delete a withholding. | | `billing_withholdings_convert_to_credit` | destructive | `write` | `withholdings.update` | `POST /v1/withholdings/:id/convert-to-credit` | Turn one retained withholding into a credit on the customer billing account, so it offsets the next invoice. | | `billing_withholdings_convert_to_credits` | destructive | `write` | `withholdings.update` | `POST /v1/withholdings/convert-to-credits` | Convert several retained withholdings into credits in one call. | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Invoices and receivables Invoices and their line items, payments and payment methods, the bank accounts and Pix keys that receive transfer charges, account credits and discount coupons. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | ---------------------------------------------------- | ----- | ---- | ----- | ----------- | | `invoices` — Invoices | 23 | 8 | 5 | 10 | | `payments` — Payments and payment methods | 19 | 4 | 6 | 9 | | `transfer-destinations` — Bank accounts and Pix keys | 11 | 5 | 0 | 6 | | `credits` — Credits | 7 | 3 | 1 | 3 | | `coupons` — Coupons and discount codes | 8 | 3 | 4 | 1 | ## `invoices`[​](#invoices "Direct link to invoices") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ----------------------------------------- | ----------- | -------- | ----------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | `billing_billing_accounts_invoices` | read | `read` | `invoices.list` | `GET /v1/billing_accounts/:id/invoices` | List the invoices of one billing account. | | `billing_subscriptions_create_invoice` | write | `write` | `invoices.create` | `POST /v1/subscriptions/:id/create-invoice` | Raise an invoice for the current period of a subscription now, instead of waiting for the billing worker. | | `billing_invoices_list` | read | `read` | `invoices.list` | `GET /v1/invoices` | List invoices. | | `billing_invoices_get` | read | `read` | `invoices.show` | `GET /v1/invoices/:id` | Fetch one invoice with its line items and totals. | | `billing_invoices_create` | write | `write` | `invoices.create` | `POST /v1/invoices` | Create a draft invoice with its line items. | | `billing_invoices_upsert` | write | `write` | `invoices.create` | `PUT /v1/invoices` | Create or update an invoice matched on `id` → `external_id`. | | `billing_invoices_update` | write | `write` | `invoices.update` | `PATCH /v1/invoices/:id` | Update an invoice. | | `billing_invoices_delete` | destructive | `delete` | `invoices.update` | `DELETE /v1/invoices/:id` | Soft-delete a `draft`, `open` or `void` invoice (credits applied to an open one go back to the customer). | | `billing_invoices_finalize` | destructive | `write` | `invoices.update` | `POST /v1/invoices/:id/finalize` | Finalize a draft invoice: it becomes `open`, gets its number, and — with `charge_automatically` — is charged immediately. | | `billing_invoices_pay` | destructive | `write` | `payments.create` | `POST /v1/invoices/:id/pay` | Settle an invoice. | | `billing_invoices_undo_payment` | destructive | `write` | `invoices.update` | `POST /v1/invoices/:id/undo-payment` | Reverse a manual settlement, sending the invoice back to `open`. | | `billing_invoices_void` | destructive | `write` | `invoices.void` | `POST /v1/invoices/:id/void` | Void an open invoice. | | `billing_invoices_apply_credits` | destructive | `write` | `invoices.update` | `POST /v1/invoices/:id/apply-credits` | Apply credits of the billing account to an open invoice, reducing the amount due. | | `billing_invoices_remove_credits` | destructive | `write` | `invoices.update` | `POST /v1/invoices/:id/remove-credits` | Undo every credit application on an open invoice, returning the credits to the billing account balance. | | `billing_invoices_installments_list` | read | `read` | `invoices.show` | `GET /v1/invoices/:id/installments` | List the installment schedule of an invoice. | | `billing_invoices_installments_create` | write | `write` | `invoices.update` | `POST /v1/invoices/:id/installments` | Split an invoice into installments. | | `billing_invoices_installments_pay` | destructive | `write` | `payments.create` | `POST /v1/invoices/:id/installments/:installmentId/pay` | Charge one installment: through the gateway (`pix`, `bank_slip`, `card`), or as a `bank_transfer` to an organization bank account or Pix key. | | `billing_invoices_installments_mark_paid` | destructive | `write` | `payments.create` | `POST /v1/invoices/:id/installments/:installmentId/mark-paid` | Mark one installment paid out of band, without touching a gateway. | | `billing_invoices_payment_methods` | read | `read` | `invoices.show` | `GET /v1/invoices/:id/payment-methods` | Payment methods usable to settle this invoice, in the order the portal offers them. | | `billing_invoices_send_reminder` | destructive | `write` | `invoices.send` | `POST /v1/invoices/:id/send-reminder` | E-mail the customer a payment reminder for an open invoice. | | `billing_invoices_pdf` | read | `read` | `invoices.show` | `GET /v1/invoices/:id/pdf` | Metadata for the invoice PDF. | | `billing_invoices_pending_nfe` | read | `read` | `invoices.list` | `GET /v1/invoices/pending-nfe` | Invoices that are due an NFe and have not had one issued yet. | | `billing_invoices_pending_payment` | read | `read` | `invoices.list` | `GET /v1/invoices/pending-payment` | Open invoices still awaiting payment. | ## `payments`[​](#payments "Direct link to payments") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------------------- | ----------- | -------- | ----------------- | ------------------------------------------ | ------------------------------------------------------------------- | | `billing_payments_list` | read | `read` | `payments.list` | `GET /v1/payments` | List payments — every charge attempt, successful or not. | | `billing_payments_get` | read | `read` | `payments.show` | `GET /v1/payments/:id` | Fetch one payment with its gateway status. | | `billing_payments_create` | destructive | `write` | `payments.create` | `POST /v1/payments` | Charge an invoice through a gateway. | | `billing_payments_delete` | destructive | `delete` | `payments.update` | `DELETE /v1/payments/:id` | Soft-delete a payment record. | | `billing_payments_retry` | destructive | `write` | `payments.retry` | `POST /v1/payments/:id/retry` | Retry a failed payment with the same method. | | `billing_payments_refund` | destructive | `write` | `payments.refund` | `POST /v1/payments/:id/refund` | Refund a succeeded payment at the gateway. | | `billing_payments_cancel` | destructive | `write` | `payments.update` | `POST /v1/payments/:id/cancel` | Cancel a pending payment. | | `billing_payments_change_due_date` | destructive | `write` | `payments.update` | `POST /v1/payments/:id/change-due-date` | Move the due date of an open boleto/PIX charge. | | `billing_payments_change_card` | write | `write` | `payments.update` | `POST /v1/payments/:id/change-card` | Point a card payment at a different stored card before retrying it. | | `billing_payments_send_email` | destructive | `write` | `payments.update` | `POST /v1/payments/:id/send-email` | E-mail the charge (boleto/PIX link) to an address. | | `billing_payments_sync` | write | `write` | `payments.update` | `POST /v1/payments/:id/sync` | Re-read a payment from the gateway and update the local status. | | `billing_payments_bulk_update_invoice` | destructive | `write` | `payments.update` | `POST /v1/payments/bulk-update-invoice` | Re-link up to 100 payments to another invoice. | | `billing_payment_methods_list` | read | `read` | `payments.list` | `GET /v1/payment_methods` | List stored payment methods. | | `billing_payment_methods_get` | read | `read` | `payments.show` | `GET /v1/payment_methods/:id` | Fetch one payment method. | | `billing_payment_methods_create` | write | `write` | `payments.create` | `POST /v1/payment_methods` | Attach a payment method to a billing account. | | `billing_payment_methods_upsert` | write | `write` | `payments.create` | `PUT /v1/payment_methods` | Create or update a payment method matched on `id` → `external_id`. | | `billing_payment_methods_update` | write | `write` | `payments.update` | `PATCH /v1/payment_methods/:id` | Update a payment method — the default flag and its metadata. | | `billing_payment_methods_delete` | destructive | `delete` | `payments.update` | `DELETE /v1/payment_methods/:id` | Detach a payment method. | | `billing_payment_methods_set_default` | write | `write` | `payments.update` | `POST /v1/payment_methods/:id/set-default` | Make this the default payment method of its billing account. | ## `transfer-destinations`[​](#transfer-destinations "Direct link to transfer-destinations") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ------------------------------ | ----------- | ------------------------ | ----------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------- | | `billing_banks_list` | read | `read` · `billing/all` | `settings.view` | `GET /v1/banks` | List the Brazilian banks (COMPE code and name) a bank account can be registered under. | | `billing_bank_accounts_list` | read | `read` · `billing/all` | `settings.view` | `GET /v1/bank_accounts` | List the organization bank accounts customers can be told to transfer to on a `bank_transfer` charge. | | `billing_bank_accounts_get` | read | `read` · `billing/all` | `settings.view` | `GET /v1/bank_accounts/:id` | Fetch one organization bank account, with its bank. | | `billing_bank_accounts_create` | destructive | `write` · `billing/all` | `settings.update` | `POST /v1/bank_accounts` | Register an organization bank account to receive `bank_transfer` charges. | | `billing_bank_accounts_update` | destructive | `write` · `billing/all` | `settings.update` | `PATCH /v1/bank_accounts/:id` | Update an organization bank account. | | `billing_bank_accounts_delete` | destructive | `delete` · `billing/all` | `settings.update` | `DELETE /v1/bank_accounts/:id` | Soft-delete an organization bank account. | | `billing_pix_keys_list` | read | `read` · `billing/all` | `settings.view` | `GET /v1/pix_keys` | List the organization Pix keys customers can be told to transfer to on a `bank_transfer` charge. | | `billing_pix_keys_get` | read | `read` · `billing/all` | `settings.view` | `GET /v1/pix_keys/:id` | Fetch one organization Pix key. | | `billing_pix_keys_create` | destructive | `write` · `billing/all` | `settings.update` | `POST /v1/pix_keys` | Register an organization Pix key to receive `bank_transfer` charges. | | `billing_pix_keys_update` | destructive | `write` · `billing/all` | `settings.update` | `PATCH /v1/pix_keys/:id` | Update an organization Pix key. | | `billing_pix_keys_delete` | destructive | `delete` · `billing/all` | `settings.update` | `DELETE /v1/pix_keys/:id` | Soft-delete an organization Pix key. | ## `credits`[​](#credits "Direct link to credits") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ---------------------------------- | ----------- | -------- | ---------------- | -------------------------------------- | ---------------------------------------------------------- | | `billing_billing_accounts_credits` | read | `read` | `credits.list` | `GET /v1/billing_accounts/:id/credits` | List the credits of one billing account. | | `billing_credits_list` | read | `read` | `credits.list` | `GET /v1/credits` | List credits. | | `billing_credits_get` | read | `read` | `credits.show` | `GET /v1/credits/:id` | Fetch one credit with what is left of it. | | `billing_credits_create` | destructive | `write` | `credits.create` | `POST /v1/credits` | Grant a credit to a billing account. | | `billing_credits_upsert` | destructive | `write` | `credits.create` | `PUT /v1/credits` | Create or update a credit matched on `id` → `external_id`. | | `billing_credits_update` | write | `write` | `credits.create` | `PATCH /v1/credits/:id` | Update a credit. | | `billing_credits_delete` | destructive | `delete` | `credits.delete` | `DELETE /v1/credits/:id` | Soft-delete a credit. | ## `coupons`[​](#coupons "Direct link to coupons") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ----------------------------- | ----------- | -------- | ---------------- | --------------------------------- | ----------------------------------------------------------------------- | | `billing_coupons_list` | read | `read` | `coupons.list` | `GET /v1/coupons` | List discount coupons with their validity window and usage counters. | | `billing_coupons_get` | read | `read` | `coupons.show` | `GET /v1/coupons/:id` | Fetch one coupon with its usage counters. | | `billing_coupons_create` | write | `write` | `coupons.create` | `POST /v1/coupons` | Create a discount coupon. | | `billing_coupons_upsert` | write | `write` | `coupons.create` | `PUT /v1/coupons` | Create or update a coupon matched on `id` → `external_id` → `code`. | | `billing_coupons_update` | write | `write` | `coupons.update` | `PATCH /v1/coupons/:id` | Update a coupon. | | `billing_coupons_delete` | destructive | `delete` | `coupons.delete` | `DELETE /v1/coupons/:id` | Soft-delete a coupon. | | `billing_coupons_deactivate` | write | `write` | `coupons.update` | `POST /v1/coupons/:id/deactivate` | Stop a coupon being redeemable, keeping its history intact. | | `billing_coupons_redemptions` | read | `read` | `coupons.show` | `GET /v1/coupons/:id/redemptions` | List the redemptions of a coupon — who used it, when, and for how much. | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Organization and schemas The organization profile itself, `billing_schemas_get` — the field catalogue that tells you what to ask for in `fields` and in `sort_by` — and your approval-link approvals: `billing_operation_approvals_get` tells what came of a destructive operation after you decided on the approval screen. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | -------------------------------------- | ----- | ---- | ----- | ----------- | | `settings` — Organization and schemas | 4 | 3 | 1 | 0 | | `operation-approvals` — Approval links | 2 | 2 | 0 | 0 | ## `settings`[​](#settings "Direct link to settings") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ----------------------------- | ----- | -------- | -------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | | `billing_me` | read | — (none) | — (active membership only) | `GET /v1/me` | Return the identity behind this connection's token: the person, the organization and the token's own scopes, access level and expiry. | | `billing_organization_get` | read | `read` | `settings.view` | `GET /v1/organization` | Fetch the organization the access token acts for — name, contact details and settings. | | `billing_organization_update` | write | `write` | `settings.update` | `PATCH /v1/organization` | Update the organization profile. | | `billing_schemas_get` | read | `read` | `settings.view` | — (local) | Describe the fields of a resource: every field name, its type, whether it is nullable, its enum values and what it means. | ## `operation-approvals`[​](#operation-approvals "Direct link to operation-approvals") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ---------------------------------- | ---- | -------- | -------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `billing_operation_approvals_get` | read | — (none) | — (active membership only) | `GET /v1/operation_approvals/:id` | Read one of your operation approvals: what came of a destructive tool call that answered `approval_required`. | | `billing_operation_approvals_list` | read | — (none) | — (active membership only) | `GET /v1/operation_approvals` | List your operation approvals in this organization, most recent first — the destructive tool calls that waited for an approval link, with what came of each (`status`, `title`, `amount`, `error`, masked `result` — the last three only where this token can read the approval’s `resource`, else `result_hidden`). | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Tools The server exposes **296 tools** over **26 resource families**. Each one dispatches in-process to the `/v1` endpoint that already implements the operation, so filters, validation, upsert matching and tenant isolation are exactly the REST API's — the tool *is* the endpoint. The one exception, `billing_schemas_get`, answers locally and is marked as such. ## How to read these pages[​](#how-to-read-these-pages "Direct link to How to read these pages") Every tool carries five facts, in this order: > `billing_invoices_void` · **destructive** · scope `write` · resource `invoices` · permission `invoices.void` · `POST /v1/invoices/:id/void` | Field | Meaning | | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **read** / **write** / **destructive** | The annotation the MCP client reads. A `destructive` tool (deletes, voids, cancels, charges, pays, refunds, applies credit, issues or cancels a fiscal document, sends an e-mail, invite or public link) runs only after the user confirms: in the form the server sends, on revision 2026-07-28 with elicitation, or through an approval link they open signed in to the dashboard, on any other client ([Confirming destructive tools](https://docs.billing.kobana.com.br/en/en/mcp/overview/resources-and-prompts.md#confirming-destructive-tools)). | | **scope** | The scope verb the token must carry for the tool: `read`, `write`, `delete` (the `*_delete` tools) or `import` (`billing_nfes_import_barueri`). None stands in for another — see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). Marked `billing/all`, the tool calls an endpoint outside the resource catalogue (bank accounts, banks, Pix keys), and only a token holding `billing/all` reaches it. Since the AS does not grant `billing/all` to an OAuth client and refuses a verb alongside `billing/all` on a personal token, these tools are, over MCP, read-only and personal-token-only: the ones that write or delete cannot run today. | | **resource** | The resource family of the tool — what groups the tools in these docs. | | **permission** | The dashboard permission the person who authorized the client must hold in the organization. `billing_me` and the `billing_operation_approvals_*` tools (which read the person’s own approvals) need none — only an active membership. | | **`METHOD /path`** | The `/v1` endpoint the tool dispatches to, to cross-reference with the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1). | ## Common arguments[​](#common-arguments "Direct link to Common arguments") These appear across many tools and always mean the same thing. | Argument | Type | Description | | ----------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `page` | integer | 1-based page number. Default `1`. | | `per_page` | integer | Page size. Default `20`, max `100`. | | `sort_by` | string | Sort column, snake\_case. `billing_schemas_get` lists the accepted ones. | | `sort_order` | `asc` \| `desc` | Direction. A value that is not a direction is an error, not a silent `desc`. | | `fields` | string\[] | Columns to return. Omit for the whole resource; `id` always comes back. | | `filters` | object | Additional filters, forwarded to the endpoint. Does not take pagination, sorting (`page`, `per_page`, `sort_by`, `sort_order`, `limit`, `cursor`, `sort`) or a filter the tool already names — pass those as named arguments; inside `filters` they are refused with `VALIDATION_ERROR`. | | `idempotency_key` | string | Replay guard, sent as `X-Idempotency-Key`. | | `custom_metadata` | object | Free-form JSON owned by you, echoed on every read and webhook. | ## The catalogue[​](#the-catalogue "Direct link to The catalogue") | Family | Tools | read | write | destructive | | ---------------------------------------------------------------------------------------------------------------------- | ----- | ---- | ----- | ----------- | | [`certificates` — Digital certificates](https://docs.billing.kobana.com.br/en/en/mcp/tools/fiscal.md) | 3 | 2 | 0 | 1 | | [`companies` — Issuing companies](https://docs.billing.kobana.com.br/en/en/mcp/tools/fiscal.md) | 12 | 4 | 6 | 2 | | [`coupons` — Coupons and discount codes](https://docs.billing.kobana.com.br/en/en/mcp/tools/invoices.md) | 8 | 3 | 4 | 1 | | [`credits` — Credits](https://docs.billing.kobana.com.br/en/en/mcp/tools/invoices.md) | 7 | 3 | 1 | 3 | | [`customers` — Customers and billing accounts](https://docs.billing.kobana.com.br/en/en/mcp/tools/customers.md) | 19 | 6 | 9 | 4 | | [`invoices` — Invoices](https://docs.billing.kobana.com.br/en/en/mcp/tools/invoices.md) | 23 | 8 | 5 | 10 | | [`nfes` — Tax invoices (NF-e)](https://docs.billing.kobana.com.br/en/en/mcp/tools/fiscal.md) | 24 | 8 | 10 | 6 | | [`operation-approvals` — Approval links](https://docs.billing.kobana.com.br/en/en/mcp/tools/organization.md) | 2 | 2 | 0 | 0 | | [`payments` — Payments and payment methods](https://docs.billing.kobana.com.br/en/en/mcp/tools/invoices.md) | 19 | 4 | 6 | 9 | | [`plan-changes` — Plan changes](https://docs.billing.kobana.com.br/en/en/mcp/tools/subscriptions.md) | 11 | 6 | 3 | 2 | | [`plans` — Plans, prices and groups](https://docs.billing.kobana.com.br/en/en/mcp/tools/catalog.md) | 21 | 5 | 12 | 4 | | [`portal-users` — Portal users](https://docs.billing.kobana.com.br/en/en/mcp/tools/customers.md) | 9 | 4 | 2 | 3 | | [`products` — Products and product groups](https://docs.billing.kobana.com.br/en/en/mcp/tools/catalog.md) | 24 | 4 | 16 | 4 | | [`proposals` — Proposals](https://docs.billing.kobana.com.br/en/en/mcp/tools/proposals.md) | 25 | 7 | 7 | 11 | | [`roles` — Team roles](https://docs.billing.kobana.com.br/en/en/mcp/tools/customers.md) | 6 | 2 | 3 | 1 | | [`services` — Service items](https://docs.billing.kobana.com.br/en/en/mcp/tools/catalog.md) | 6 | 2 | 3 | 1 | | [`settings` — Organization and schemas](https://docs.billing.kobana.com.br/en/en/mcp/tools/organization.md) | 4 | 3 | 1 | 0 | | [`subscription-changes` — Subscription changes](https://docs.billing.kobana.com.br/en/en/mcp/tools/subscriptions.md) | 5 | 3 | 1 | 1 | | [`subscriptions` — Subscriptions](https://docs.billing.kobana.com.br/en/en/mcp/tools/subscriptions.md) | 16 | 4 | 6 | 6 | | [`tax-periods` — Tax periods](https://docs.billing.kobana.com.br/en/en/mcp/tools/fiscal.md) | 5 | 2 | 2 | 1 | | [`tax-rules` — Tax rules](https://docs.billing.kobana.com.br/en/en/mcp/tools/fiscal.md) | 6 | 2 | 3 | 1 | | [`templates` — Proposal templates](https://docs.billing.kobana.com.br/en/en/mcp/tools/proposals.md) | 9 | 2 | 6 | 1 | | [`transfer-destinations` — Bank accounts and Pix keys](https://docs.billing.kobana.com.br/en/en/mcp/tools/invoices.md) | 11 | 5 | 0 | 6 | | [`usage` — Metered usage](https://docs.billing.kobana.com.br/en/en/mcp/tools/usage.md) | 7 | 4 | 3 | 0 | | [`users` — Dashboard users](https://docs.billing.kobana.com.br/en/en/mcp/tools/customers.md) | 6 | 2 | 1 | 3 | | [`withholdings` — Withholdings](https://docs.billing.kobana.com.br/en/en/mcp/tools/fiscal.md) | 8 | 2 | 3 | 3 | A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Proposals Commercial proposals — from draft to acceptance, where a signature becomes a subscription — and the templates they are rendered from. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | -------------------------------- | ----- | ---- | ----- | ----------- | | `proposals` — Proposals | 25 | 7 | 7 | 11 | | `templates` — Proposal templates | 9 | 2 | 6 | 1 | ## `proposals`[​](#proposals-1 "Direct link to proposals-1") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------------- | ----------- | -------- | ------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | `billing_proposals_list` | read | `read` | `proposals.list` | `GET /v1/proposals` | List commercial proposals. | | `billing_proposals_get` | read | `read` | `proposals.show` | `GET /v1/proposals/:id` | Fetch one proposal with its items and totals. | | `billing_proposals_create` | write | `write` | `proposals.create` | `POST /v1/proposals` | Create a draft proposal. | | `billing_proposals_upsert` | write | `write` | `proposals.create` | `PUT /v1/proposals` | Create or update a proposal matched on `id` → `external_id` → `code`. | | `billing_proposals_update` | write | `write` | `proposals.update` | `PATCH /v1/proposals/:id` | Update a proposal. | | `billing_proposals_delete` | destructive | `delete` | `proposals.delete` | `DELETE /v1/proposals/:id` | Soft-delete a proposal. | | `billing_proposals_publish` | destructive | `write` | `proposals.update` | `POST /v1/proposals/:id/publish` | Publish a proposal, making its public link reachable by the prospect. | | `billing_proposals_unpublish` | destructive | `write` | `proposals.update` | `POST /v1/proposals/:id/unpublish` | Take a proposal offline; the public link stops resolving. | | `billing_proposals_send` | destructive | `write` | `proposals.send` | `POST /v1/proposals/:id/send` | E-mail a proposal to its contact and move it to `sent`. | | `billing_proposals_accept` | destructive | `write` | `proposals.approve` | `POST /v1/proposals/:id/accept` | Accept a proposal on behalf of the customer. | | `billing_proposals_undo_accept` | destructive | `write` | `proposals.approve` | `POST /v1/proposals/:id/undo-accept` | Undo an acceptance, sending the proposal back to `sent`. | | `billing_proposals_cancel` | destructive | `write` | `proposals.update` | `POST /v1/proposals/:id/cancel` | Cancel a proposal. | | `billing_proposals_duplicate` | write | `write` | `proposals.create` | `POST /v1/proposals/:id/duplicate` | Copy a proposal and its items into a new draft. | | `billing_proposals_generate_pdf` | write | `write` | `proposals.update` | `POST /v1/proposals/:id/generate-pdf` | Render the proposal PDF from its template and store it. | | `billing_proposals_pricing` | read | `read` | `proposals.show` | `GET /v1/proposals/:id/pricing` | Price breakdown of a proposal on every billing cycle: setup, monthly, cycle discount and total — what the prospect sees before picking one. | | `billing_proposals_json` | read | `read` | `proposals.show` | `GET /v1/proposals/:id/json` | The full proposal payload as the template renderer receives it — the merge data behind the PDF. | | `billing_proposals_stats` | read | `read` | `proposals.list` | `GET /v1/proposals/stats` | Aggregate proposal counts and values by status, for the whole organization. | | `billing_proposals_items_list` | read | `read` | `proposals.show` | `GET /v1/proposals/:id/items` | List the items of a proposal. | | `billing_proposals_items_create` | write | `write` | `proposals.update` | `POST /v1/proposals/:id/items` | Add an item to a draft proposal. | | `billing_proposals_items_get` | read | `read` | `proposals.show` | `GET /v1/proposals/:id/items/:itemId` | Fetch one proposal item with its negotiated pricing. | | `billing_proposals_items_update` | write | `write` | `proposals.update` | `PATCH /v1/proposals/:id/items/:itemId` | Update one item of a draft proposal. | | `billing_proposals_items_delete` | destructive | `delete` | `proposals.update` | `DELETE /v1/proposals/:id/items/:itemId` | Remove an item from a draft proposal. | | `billing_proposals_bulk_send` | destructive | `write` | `proposals.send` | `POST /v1/proposals/bulk-send` | Send up to 100 proposals in one call. | | `billing_proposals_bulk_cancel` | destructive | `write` | `proposals.update` | `POST /v1/proposals/bulk-cancel` | Cancel up to 100 proposals in one call. | | `billing_proposals_bulk_delete` | destructive | `delete` | `proposals.delete` | `DELETE /v1/proposals/bulk` | Soft-delete up to 100 proposals in one call. | ## `templates`[​](#templates "Direct link to templates") | Tool | Kind | Scope | Permission | Endpoint | What it does | | --------------------------------------- | ----------- | -------- | ------------------ | -------------------------------------------- | ------------------------------------------------------------------------------ | | `billing_proposal_templates_list` | read | `read` | `templates.list` | `GET /v1/proposal_templates` | List the templates proposals are rendered from. | | `billing_proposal_templates_get` | read | `read` | `templates.show` | `GET /v1/proposal_templates/:id` | Fetch one proposal template. | | `billing_proposal_templates_create` | write | `write` | `templates.create` | `POST /v1/proposal_templates` | Create a proposal template. | | `billing_proposal_templates_upsert` | write | `write` | `templates.create` | `PUT /v1/proposal_templates` | Create or update a proposal template matched on `id` → `external_id` → `name`. | | `billing_proposal_templates_update` | write | `write` | `templates.update` | `PATCH /v1/proposal_templates/:id` | Update a proposal template. | | `billing_proposal_templates_delete` | destructive | `delete` | `templates.delete` | `DELETE /v1/proposal_templates/:id` | Soft-delete a proposal template. | | `billing_proposal_templates_activate` | write | `write` | `templates.update` | `POST /v1/proposal_templates/:id/activate` | Make a template selectable on new proposals. | | `billing_proposal_templates_deactivate` | write | `write` | `templates.update` | `POST /v1/proposal_templates/:id/deactivate` | Hide a template from new proposals. | | `billing_proposal_templates_duplicate` | write | `write` | `templates.create` | `POST /v1/proposal_templates/:id/duplicate` | Copy a proposal template into a new one, ready to be edited. | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Subscriptions The subscription lifecycle — trial, activation, pause, cancellation — and plan changes, with the proration each one produces. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | --------------------------------------------- | ----- | ---- | ----- | ----------- | | `subscriptions` — Subscriptions | 16 | 4 | 6 | 6 | | `plan-changes` — Plan changes | 11 | 6 | 3 | 2 | | `subscription-changes` — Subscription changes | 5 | 3 | 1 | 1 | ## `subscriptions`[​](#subscriptions-1 "Direct link to subscriptions-1") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ------------------------------------------- | ----------- | -------- | ---------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `billing_billing_accounts_subscriptions` | read | `read` | `subscriptions.list` | `GET /v1/billing_accounts/:id/subscriptions` | List the subscriptions of one billing account. | | `billing_subscriptions_list` | read | `read` | `subscriptions.list` | `GET /v1/subscriptions` | List subscriptions. | | `billing_subscriptions_get` | read | `read` | `subscriptions.show` | `GET /v1/subscriptions/:id` | Fetch one subscription with its items and current period. | | `billing_subscriptions_create` | write | `write` | `subscriptions.create` | `POST /v1/subscriptions` | Create a subscription. | | `billing_subscriptions_upsert` | write | `write` | `subscriptions.create` | `PUT /v1/subscriptions` | Create or update a subscription matched on `id` → `external_id`. | | `billing_subscriptions_update` | write | `write` | `subscriptions.update` | `PATCH /v1/subscriptions/:id` | Update a subscription in place. | | `billing_subscriptions_delete` | destructive | `delete` | `subscriptions.delete` | `DELETE /v1/subscriptions/:id` | Soft-delete a subscription. | | `billing_subscriptions_activate` | write | `write` | `subscriptions.update` | `POST /v1/subscriptions/:id/activate` | Activate a draft/confirmed subscription and open its first billing period. | | `billing_subscriptions_cancel` | destructive | `write` | `subscriptions.cancel` | `POST /v1/subscriptions/:id/cancel` | Cancel a subscription. | | `billing_subscriptions_pause` | destructive | `write` | `subscriptions.pause` | `POST /v1/subscriptions/:id/pause` | Pause a subscription. | | `billing_subscriptions_resume` | write | `write` | `subscriptions.resume` | `POST /v1/subscriptions/:id/resume` | Resume a paused subscription and reopen billing. | | `billing_subscriptions_revert_to_confirmed` | destructive | `write` | `subscriptions.update` | `POST /v1/subscriptions/:id/revert-to-confirmed` | Send an active subscription back to `confirmed`, undoing an activation. | | `billing_subscriptions_change_plan` | destructive | `write` | `subscriptions.update` | `POST /v1/subscriptions/:id/change-plan` | Move a subscription to another plan, computing proration: an upgrade charges the prorated difference now, a downgrade credits the next invoice. | | `billing_subscriptions_items_list` | read | `read` | `subscriptions.show` | `GET /v1/subscriptions/:id/items` | List the items of a subscription. | | `billing_subscriptions_items_change` | destructive | `write` | `subscriptions.update` | `POST /v1/subscriptions/:id/items` | Apply up to 50 item operations to a subscription in one transaction, with proration. | | `billing_subscriptions_sync_plan_items` | write | `write` | `subscriptions.update` | `POST /v1/subscriptions/:id/sync-plan-items` | Re-align a subscription with its plan: adds items the plan gained and removes items it dropped. | ## `plan-changes`[​](#plan-changes "Direct link to plan-changes") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ------------------------------------ | ----------- | -------- | ---------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | | `billing_plan_changes_list` | read | `read` | `plan-changes.list` | `GET /v1/plan_changes` | List plan changes — the audit trail of every plan swap, with its proration. | | `billing_plan_changes_get` | read | `read` | `plan-changes.show` | `GET /v1/plan_changes/:id` | Fetch one plan change with the proration it produced. | | `billing_plan_changes_execute` | destructive | `write` | `subscriptions.update` | `POST /v1/plan_changes` | Execute a plan change against the organization rules. | | `billing_plan_changes_stats` | read | `read` | `plan-changes.list` | `GET /v1/plan_changes/stats` | Aggregate plan-change counts and amounts over the last `days` (default 30). | | `billing_plan_changes_config_get` | read | `read` | `plan-changes.config` | `GET /v1/plan_changes/config` | Read the organization plan-change policy: whether upgrades/downgrades are allowed, and how each is prorated and timed. | | `billing_plan_changes_config_update` | write | `write` | `plan-changes.config` | `PATCH /v1/plan_changes/config` | Update the organization plan-change policy. | | `billing_plan_changes_rules_list` | read | `read` | `plan-changes.config` | `GET /v1/plan_changes/rules` | List the per-plan-pair rules that override the global policy — which moves are allowed, and with which discount or bonus. | | `billing_plan_changes_rules_get` | read | `read` | `plan-changes.config` | `GET /v1/plan_changes/rules/:id` | Fetch one plan-change rule. | | `billing_plan_changes_rules_create` | write | `write` | `plan-changes.config` | `POST /v1/plan_changes/rules` | Create a plan-change rule. | | `billing_plan_changes_rules_update` | write | `write` | `plan-changes.config` | `PATCH /v1/plan_changes/rules/:id` | Update a plan-change rule. | | `billing_plan_changes_rules_delete` | destructive | `delete` | `plan-changes.config` | `DELETE /v1/plan_changes/rules/:id` | Delete a plan-change rule; the pair falls back to the global policy. | ## `subscription-changes`[​](#subscription-changes "Direct link to subscription-changes") | Tool | Kind | Scope | Permission | Endpoint | What it does | | -------------------------------------------- | ----------- | ------- | ----------------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `billing_subscription_item_changes_list` | read | `read` | `subscription-changes.list` | `GET /v1/subscription_item_changes` | List item changes applied to subscriptions, with the proration each produced and who initiated it. | | `billing_subscription_item_changes_get` | read | `read` | `subscription-changes.show` | `GET /v1/subscription_item_changes/:id` | Fetch one subscription item change. | | `billing_subscription_item_changes_cancel` | destructive | `write` | `subscription-changes.update` | `POST /v1/subscription_item_changes/:id/cancel` | Cancel a scheduled item change before it takes effect. | | `billing_subscription_changes_config_get` | read | `read` | `subscription-changes.list` | `GET /v1/subscription_changes/config` | Read the organization item-change policy: which item operations are allowed, how each is prorated and timed, and what the customer portal may do by itself. | | `billing_subscription_changes_config_update` | write | `write` | `subscription-changes.update` | `PUT /v1/subscription_changes/config` | Replace the organization item-change policy. | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- # Usage Metered usage for usage-based billing: raw records, the aggregated summary per subscription item, and the daily and monthly snapshots. ## Families on this page[​](#families-on-this-page "Direct link to Families on this page") | Family | Tools | read | write | destructive | | ----------------------- | ----- | ---- | ----- | ----------- | | `usage` — Metered usage | 7 | 4 | 3 | 0 | ## `usage`[​](#usage-1 "Direct link to usage-1") | Tool | Kind | Scope | Permission | Endpoint | What it does | | ---------------------------------------- | ----- | ------- | ------------ | ---------------------------------- | -------------------------------------------------------------------------------------------- | | `billing_usage_list` | read | `read` | `usage.view` | `GET /v1/usage` | List raw usage records for metered billing. | | `billing_usage_report` | write | `write` | `usage.view` | `POST /v1/usage` | Report metered usage. | | `billing_usage_summary` | read | `read` | `usage.view` | `GET /v1/usage/summary` | Aggregated usage for a period: total quantity per subscription item, against its plan limit. | | `billing_usage_snapshots_daily_list` | read | `read` | `usage.view` | `GET /v1/usage/snapshots/daily` | List daily usage snapshots. | | `billing_usage_snapshots_daily_create` | write | `write` | `usage.view` | `POST /v1/usage/snapshots/daily` | Push daily usage snapshots — one inline, or up to 100 in `records`. | | `billing_usage_snapshots_monthly_list` | read | `read` | `usage.view` | `GET /v1/usage/snapshots/monthly` | List monthly usage snapshots. | | `billing_usage_snapshots_monthly_create` | write | `write` | `usage.view` | `POST /v1/usage/snapshots/monthly` | Push monthly usage snapshots — one inline, or a batch in `records`. | *** The fields of each resource are in the [API reference](https://docs.billing.kobana.com.br/en/en/api/v1) and in `billing_schemas_get`. A tool you cannot run is not listed by `tools/list` at all. If one from this page is missing, see [Authentication](https://docs.billing.kobana.com.br/en/en/mcp/overview/authentication.md). --- ## [📄️Digital Certificates](https://docs.billing.kobana.com.br/en/en/nota-fiscal/certificados.md) [The /dashboard/certificates page manages the A1 digital certificates used to sign NF-e and to authenticate with the municipal web services. Each certificate is linked to a registered company and is stored encrypted at rest.](https://docs.billing.kobana.com.br/en/en/nota-fiscal/certificados.md) --- ## [📄️Digital Certificates](https://docs.billing.kobana.com.br/en/en/nota-fiscal/certificados.md) [The /dashboard/certificates page manages the A1 digital certificates used to sign NF-e and to authenticate with the municipal web services. Each certificate is linked to a registered company and is stored encrypted at rest.](https://docs.billing.kobana.com.br/en/en/nota-fiscal/certificados.md) --- # Digital Certificates The `/dashboard/certificates` page manages the **A1 digital certificates** used to sign NF-e and to authenticate with the municipal web services. Each certificate is linked to a registered company and is stored encrypted at rest. ## How it works[​](#how-it-works "Direct link to How it works") 1. **Upload the `.pfx` file** — the operator uploads the certificate and enters its password. 2. **Automatic validation** — the system checks the CNPJ, the validity and the certification chain. 3. **Encrypted storage** — the `.pfx` content and the password are encrypted with AES-256-GCM before going into the database. 4. **Link to the company** — a company can have only one active certificate at a time. ## Information shown[​](#information-shown "Direct link to Information shown") * **Associated company** and **CNPJ** * **Validity** — expiration date and a warning when fewer than 30 days are left * **Issuer** — the Certificate Authority that issued it (Serasa, Certisign, Soluti, etc.) * **Status** — `active`, `expired` or `revoked` * **Last use** — date of the last signed NF-e ## Alerts and renewal[​](#alerts-and-renewal "Direct link to Alerts and renewal") The system notifies administrators when a certificate is close to expiring. Once it expires, the NF-e provider stops accepting the signature and new issuances fail until a new certificate is uploaded. Renewal replaces the file without losing the history of NF-e issued with the previous certificate. ## Security[​](#security "Direct link to Security") * Passwords and `.pfx` bytes are encrypted at rest (see `lib/crypto.ts`). * Access to the page is restricted to members with the appropriate fiscal permission. * Every creation, replacement or removal creates an entry in the [Audit Log](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![List of digital certificates with company, validity and status](/en/assets/images/certificados-7ae7aed048fb6049f52ac7e661cb87e3.png) --- # NF-e Configuration Each organization can enable and configure automatic invoice issuance. ## Configuration Fields[​](#configuration-fields "Direct link to Configuration Fields") | Field | Description | | ----------------------------- | ----------------------------------------------- | | **Provider** | `mock`, `nfe_io`, or `kobana` | | **Environment** | `sandbox` or `production` | | **Enabled** | Whether NF-e issuance is active | | **Issuance policy** | When the NF-e is issued automatically | | **NFe.io API key** | Authentication key (encrypted) | | **NFe.io companies** | Cache of companies registered with the provider | | **Service description** | Default description added to invoices | | **Max issuance attempts** | Default: 5 | | **Max cancellation attempts** | Default: 5 | | **Retry intervals (minutes)** | Default: \[0, 30, 60, 180, 360] | ## Issuance Policies[​](#issuance-policies "Direct link to Issuance Policies") | Policy | Description | | ----------------- | ---------------------------------------------- | | `disabled` | NF-e issuance disabled | | `on_finalization` | Issue when the invoice is finalized | | `on_full_payment` | Issue when the invoice is fully paid (default) | | `per_installment` | Issue one NF-e for each installment paid | ### Examples[​](#examples "Direct link to Examples") **`on_full_payment`**: A R$ 1,000 invoice generates **one** NF-e for R$ 1,000 when fully paid. **`per_installment`**: A R$ 1,000 invoice split into 3 installments generates **three** NF-e of R$ 333.33 as each installment is paid. **`on_finalization`**: The NF-e is issued at the time of invoice finalization, regardless of payment. ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/nfe-settings` screen brings together the NF-e configuration per company: provider (NFe.io, Kobana), environment (sandbox/production), API key encrypted at rest, service code mapping, issuance policy (`per_payment`, `per_installment`, `on_finalization`), callback webhooks and email sending flags. ![NF-e configuration per company with provider and policies](/en/assets/images/configuracao-nfe-e495ee17f57b0bd6f385a8b51e1f08eb.png) --- # NF-e Issuance ## NF-e Statuses[​](#nf-e-statuses "Direct link to NF-e Statuses") ``` draft → pending → processing → issued ↓ (error) → error issued → pending_cancel → canceling → canceled ↓ (error) → error ``` | Status | Description | | ------------------- | ------------------------------------------------------ | | **draft** | Draft, not yet submitted | | **pending** | Queued for issuance | | **processing** | Being processed by the provider (async) | | **issued** | Successfully issued | | **pending\_cancel** | Marked for cancellation | | **canceling** | Cancellation in progress | | **canceled** | Successfully canceled | | **error** | Issuance/cancellation failed after exhausting attempts | ## NF-e Fields[​](#nf-e-fields "Direct link to NF-e Fields") ### Identification[​](#identification "Direct link to Identification") | Field | Description | | ------------------- | ------------------ | | **Invoice** | Associated invoice | | **Billing account** | Customer | | **Company** | Issuing company | ### Numbers and Keys[​](#numbers-and-keys "Direct link to Numbers and Keys") | Field | Description | | --------------------- | --------------------------- | | **NF-e number** | Sequential number | | **Series** | NF-e series | | **Key** | 44-digit key | | **Verification code** | For lookup | | **RPS number** | Provisional Service Receipt | ### Service[​](#service "Direct link to Service") | Field | Description | | ------------------ | ----------------------------------- | | **Amount (cents)** | Service amount | | **Service code** | LC 116/2003 code | | **Description** | Description of the service provided | | **CNAE code** | Activity classification | | **NBS code** | Brazilian Nomenclature of Services | ### Taxes[​](#taxes "Direct link to Taxes") The NF-e stores the breakdown of calculated taxes: * ISS (rate and amount) * PIS, COFINS, CSLL * IRRF * INSS ### URLs[​](#urls "Direct link to URLs") | Field | Description | | ----------- | ------------------------- | | **XML URL** | Download the invoice XML | | **PDF URL** | Download the DANFE in PDF | ## Customer Snapshot[​](#customer-snapshot "Direct link to Customer Snapshot") The NF-e stores a **snapshot** of the customer data at the time of issuance: * Name, document, email, phone * Full address with IBGE city code This ensures the invoice reflects the correct data even if the customer updates their information later. ## Audit Trail[​](#audit-trail "Direct link to Audit Trail") Each HTTP request made to the provider is recorded in `NfeRequestTry`: * Action (issue, cancel, query) * Endpoint called * Complete request and response * HTTP status * Duration in milliseconds * Result (success/failure) ## Screenshots[​](#screenshots "Direct link to Screenshots") ### NF-e list[​](#nf-e-list "Direct link to NF-e list") The `/dashboard/nfes` screen lists all issued fiscal invoices, with filters by status (`pending`, `processing`, `issued`, `error`, `canceled`), company, customer, range and number. Each row shows number, amount, calculated taxes, invoice/origin and actions (download XML, PDF, resend, cancel). ![List of NF-e with status, amount and taxes](/en/assets/images/notas-fiscais-8299b9c6e7bef3589652dcf00998656f.png) ### NF-e detail[​](#nf-e-detail "Direct link to NF-e detail") The `/dashboard/nfes/[id]` page brings together the complete fiscal data: issuer, recipient, items (with LC 116/municipal codes), calculated taxes, withholdings, XML returned by the municipality, PDF and history of attempts at the provider. ![NF-e detail with taxes, XML and provider attempts](/en/assets/images/nota-fiscal-detalhe-f132512cf71424db422879e3e4b614b4.png) --- # NF-e Providers The system abstracts communication with NF-e providers through a common interface. ## Available Providers[​](#available-providers "Direct link to Available Providers") ### NFe.io (`nfe_io`)[​](#nfeio-nfe_io "Direct link to nfeio-nfe_io") Integration with the NFe.io platform for NFS-e issuance. * **API**: * **Documentation**: * **Support**: NFS-e (services) **Status Mapping:** | NFe.io Status | Internal Status | | --------------------------------------------------------------------------- | --------------- | | Created, WaitingCalculateTaxes, WaitingSend, WaitingReturn, WaitingDownload | `processing` | | Issued | `issued` | | Cancelled | `canceled` | | Error | `error` | ### Kobana NF-e (`kobana`)[​](#kobana-nf-e-kobana "Direct link to kobana-nf-e-kobana") Integration with Kobana's internal NF-e service. * **API**: (configurable) * **Version**: /api/v1 * **Support**: Issuance and cancellation ### Mock (`mock`)[​](#mock-mock "Direct link to mock-mock") Development provider that simulates issuances with fictitious data. * No external calls * In-memory storage * Generates realistic keys and verification codes ## Common Interface[​](#common-interface "Direct link to Common Interface") All providers implement: | Operation | Description | | ------------- | --------------------------- | | `issue` | Issue an NF-e | | `cancel` | Cancel an issued NF-e | | `query` | Query the status of an NF-e | | `downloadXml` | Download the invoice XML | | `downloadPdf` | Download the PDF (DANFE) | --- # NF-e Retries The system implements automatic retry for failed issuances. ## Automatic Worker[​](#automatic-worker "Direct link to Automatic Worker") Runs **every 30 minutes** and performs: 1. **Process retries**: Pending or errored NF-e that still have attempts remaining 2. **Update status**: Query the provider for NF-e in `processing` status (last 7 days) 3. **Auto-issue on payment**: Issue NF-e for paid invoices (`on_full_payment` policy) 4. **Auto-issue on finalization**: Issue for finalized invoices (`on_finalization` policy) 5. **Auto-issue per installment**: Issue for paid installments (`per_installment` policy) ## Retry Logic[​](#retry-logic "Direct link to Retry Logic") ### Default Intervals[​](#default-intervals "Direct link to Default Intervals") | Attempt | Interval | Cumulative Time | | ------- | --------- | --------------- | | 1st | Immediate | 0 min | | 2nd | +30 min | 30 min | | 3rd | +60 min | 1h30 | | 4th | +180 min | 4h30 | | 5th | +360 min | \~10h30 | The intervals are configurable per organization via `retryDelaysMinutes`. ### Maximum Attempts[​](#maximum-attempts "Direct link to Maximum Attempts") * Issuance: 5 attempts (configurable via `maxIssueAttempts`) * Cancellation: 5 attempts (configurable via `maxCancelAttempts`) After exhausting attempts, the status changes to `error`. ## Error Handling[​](#error-handling "Direct link to Error Handling") * Auto-issuance errors are **non-blocking** (expected when NF-e is not enabled) * Detailed logs for each attempt * Process and error counters per worker execution --- ## [📄️Plan Groups](https://docs.billing.kobana.com.br/en/en/planos-e-produtos/grupos-de-planos/.md) [Plan groups allow you to organize related plans to simplify management and visualization in the dashboard.](https://docs.billing.kobana.com.br/en/en/planos-e-produtos/grupos-de-planos/.md) --- ## [📄️Plan Groups](https://docs.billing.kobana.com.br/en/en/planos-e-produtos/grupos-de-planos/.md) [Plan groups allow you to organize related plans to simplify management and visualization in the dashboard.](https://docs.billing.kobana.com.br/en/en/planos-e-produtos/grupos-de-planos/.md) --- # Plan Groups Plan groups allow you to organize related plans to simplify management and visualization in the dashboard. ## Fields[​](#fields "Direct link to Fields") | Field | Description | | ----------------- | ------------------------------------------------- | | **Name** | Group name (unique per organization) | | **Slug** | URL-friendly identifier (unique per organization) | | **Display order** | Controls the group's position in the interface | ## Features[​](#features "Direct link to Features") * Auto-generates the slug from the name if not provided * Prevents archiving if there are still plans linked to the group * Display order controls the organization of groups in the interface ## Operations[​](#operations "Direct link to Operations") * **Create**: Provide name and organization * **Update**: Name and slug are editable * **Archive**: Deactivates the group (soft delete) * **Unarchive**: Reactivates the group * **Move plans**: Plans can be moved between groups or removed from a group (set to `null`) --- # Product Groups Product groups allow you to categorize products to simplify organization, dashboard filtering, and linking with proposal templates. ## Fields[​](#fields "Direct link to Fields") | Field | Description | | --------------------- | -------------------------------------------- | | **Name** | Group name (unique per organization) | | **Slug** | URL-friendly identifier | | **Company** | Specific company (optional) | | **Proposal template** | Default template for proposals in this group | | **Service item** | Default fiscal service item for the group | | **Display order** | Position in the interface | ## Operations[​](#operations "Direct link to Operations") * **Create**: Provide name, organization, and optionally company/template/service item * **Update**: All fields are editable * **Archive/Unarchive**: Activate and deactivate groups * **Reorder**: Control the display order of groups ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Group list[​](#group-list "Direct link to Group list") The `/dashboard/product-groups` screen lists the catalog groups with name, number of linked products, status and display order. Groups define how the catalog appears in the customer portal. ![List of product groups with name and number of items](/en/assets/images/grupos-de-produtos-309ac7de9370ed3952813c0dd9ae26a7.png) ### Group detail[​](#group-detail "Direct link to Group detail") The `/dashboard/product-groups/[id]` page lets you organize the group's products, set the description shown in the portal, choose the default fiscal template/service item and archive it. ![Product group detail with list of items](/en/assets/images/grupo-de-produtos-detalhe-54f2b40c3005b17f5fe6ed122377c45d.png) --- # Service Items Service items (`/dashboard/service-items`) are the catalog of **fiscal descriptions** used on service invoices and NF-e. Each item carries the information the municipality requires at issuance: municipal service code, LC 116 code, national tax code, and default ISS, PIS, COFINS, IR, INSS and CSLL rates. Unlike a commercial product, a service item has no price of its own — it is linked to a product, plan or invoice line to provide the correct fiscal metadata. When an NF-e is generated, the tax engine looks up the linked item to fill in the required fields and calculate the taxes. ## What each item stores[​](#what-each-item-stores "Direct link to What each item stores") * **Name and description** — used in the body of the invoice. * **Municipal code** — service code of the issuing municipality (varies by municipality). * **LC 116 code** — national code defined by Complementary Law 116/2003. * **NBS / NCM** — when applicable to services involving products. * **Default rates** — used as the calculation base when there is no specific tax rule. * **Associated company** (optional) — limits the item to one of the registered companies, useful for groups with branches in different municipalities. ## When to use them[​](#when-to-use-them "Direct link to When to use them") * SaaS catalog with few distinct services: register a single item ("Software license") and reuse it in every product. * Multi-company operation across different municipalities: register the same service once per company, with each one's correct municipal code. * One-off consulting, training or setup sales: create dedicated items so the NF-e comes out with the correct description and code. ## Relationship with tax rules[​](#relationship-with-tax-rules "Direct link to Relationship with tax rules") When a [tax rule](https://docs.billing.kobana.com.br/en/en/impostos/regras-fiscais/.md) is evaluated, it can filter by service item to apply specific rates — for example, an IR withholding only on consulting services. This lets you keep default rates on the item and exceptions in the rule. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![List of service items with municipal code and rates](/en/assets/images/itens-de-servico-af866c87455d4d712695c45ac42618ce.png) --- # Plans Plans are the templates that define how your customers will be billed. Each plan groups products with specific prices and configures the billing cycle, trial period, and included features. ## Plan Fields[​](#plan-fields "Direct link to Plan Fields") | Field | Description | | ------------------------- | ----------------------------------------------------------------------------------------------- | | **Name** | Display name of the plan (1-255 characters) | | **Slug** | URL-friendly unique identifier (1-100 characters, lowercase letters, numbers, and hyphens only) | | **Description** | Descriptive text about what the plan includes | | **Type** | `standard` (default), `custom` (negotiated), or `promotional` | | **Visibility** | `public` (visible in listings) or `private` (direct link only) | | **Default billing cycle** | `monthly`, `quarterly`, `semiannual`, or `annual` | | **Available cycles** | Which cycles the customer can choose when subscribing | | **Trial period** | 0 to 90 days of free trial | | **Features** | List of features included in the plan | | **Limits** | Quotas and restrictions (e.g., users, sub-accounts, API requests/day) | ## Status and Lifecycle[​](#status-and-lifecycle "Direct link to Status and Lifecycle") ``` draft → active → archived ↓ ↓ DELETE RESTORE (draft only) (back to active) ``` | Status | Description | | ------------ | ------------------------------------------------------------------ | | **draft** | Under construction. Can be published or deleted | | **active** | Available for new subscriptions | | **archived** | Disabled for new subscriptions, but existing ones continue to work | ### Transition Rules[​](#transition-rules "Direct link to Transition Rules") * **Archive**: Not possible if there are active or trialing subscriptions * **Restore**: Available only for archived plans; returns to `active` status * **Delete**: Available only for plans in `draft` with no associated subscriptions ## Plan Items[​](#plan-items "Direct link to Plan Items") Each plan contains **items** that link a product to a specific price: | Field | Description | | ------------ | ------------------------------------------------------------------- | | **Product** | The included product (root products only, no children) | | **Price** | The selected price variant for the product | | **Quantity** | Included quantity (minimum 1) | | **Included** | Whether the item is part of the base price or is an optional add-on | ### Item Rules[​](#item-rules "Direct link to Item Rules") * Only **root products** can be added (child products are inherited automatically) * Duplicating the same product in a plan is not allowed * All products must belong to the same organization and company as the plan ## Creating a Plan[​](#creating-a-plan "Direct link to Creating a Plan") 1. Go to **Plans** in the dashboard 2. Click **New Plan** 3. Fill in the required fields (name, slug) 4. Add products and their prices as plan items 5. Configure the available billing cycles 6. Optionally set a trial period 7. Save as draft or publish directly ## Duplicate Plan[​](#duplicate-plan "Direct link to Duplicate Plan") Use the duplication function to copy all details of a plan. The system automatically adds "(Copy)" to the name and "-copy" to the slug. The duplicated plan is created with `draft` status. ## Bulk Operations[​](#bulk-operations "Direct link to Bulk Operations") * **Bulk archive**: Archives multiple plans at once (skips plans in use) * **Bulk delete**: Removes multiple draft plans (skips plans with subscriptions) * **Move to group**: Moves multiple plans to a specific group ## Company and Organization[​](#company-and-organization "Direct link to Company and Organization") * Every plan belongs to an **organization** (required) * Optionally can be linked to a specific **company** (for billing by legal entity) * All products in the plan must belong to the same company/organization ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Plan list[​](#plan-list "Direct link to Plan list") The `/dashboard/plans` screen lists the catalog plans with name, cycle, recurring amount, number of active subscriptions, status (`active`/`archived`) and actions (edit, duplicate, archive). ![List of plans with cycle, amount and active subscriptions](/en/assets/images/planos-26babf9fb6bb242e6de899483864da75.png) ### Plan detail[​](#plan-detail "Direct link to Plan detail") The `/dashboard/plans/[id]` page shows the plan's items (products, prices, quantities), proration rules, cancellation policy, list of linked subscriptions and audit. ![Plan detail with items, rules and subscriptions](/en/assets/images/plano-detalhe-123fec57173035a5bd404a221272a2c7.png) --- # Prices and Pricing Models Each product can have multiple prices, allowing variants by currency, billing interval, or pricing model. Prices are **largely immutable** after creation — only the name and metadata can be changed. To change values, deactivate the old price and create a new one. ## Price Fields[​](#price-fields "Direct link to Price Fields") | Field | Description | | ----------------------- | ----------------------------------------------- | | **Name** | Variant name (e.g., "Standard", "Pro") | | **Currency** | ISO 4217 code (default: BRL) | | **Active** | Whether the price is available for use | | **Billing Scheme** | Pricing model | | **Unit amount** | Price per unit, in BRL (up to 4 decimal places) | | **Recurrence interval** | `month` or `year` | | **Interval count** | Repetitions (e.g., 3 months) | | **Usage type** | `licensed` (fixed) or `metered` (measured) | ## Monetary Values — Subcents[​](#monetary-values--subcents "Direct link to Monetary Values — Subcents") Prices are decimal numbers in BRL and accept up to **4 decimal places**, which allows fractional unit prices: | Value | Meaning | | ------- | --------- | | `100` | R$ 100.00 | | `50.5` | R$ 50.50 | | `0.999` | R$ 0.999 | > **Important**: prices are the only place where all 4 decimals are preserved. Every other monetary value (invoice, payment, credit) is rounded to 2 decimals. ## Pricing Models[​](#pricing-models "Direct link to Pricing Models") ### 1. Per Unit (`per_unit`)[​](#1-per-unit-per_unit "Direct link to 1-per-unit-per_unit") The simplest model: fixed price per unit. ``` Price: R$ 5.00/user/month 10 users = R$ 50.00/month ``` ### 2. Graduated (`tiered` + `graduated`)[​](#2-graduated-tiered--graduated "Direct link to 2-graduated-tiered--graduated") Each tier has a different price, and **only the units within each tier** are charged at that rate. ``` Tier 1: 1-10 units → R$ 10.00/unit Tier 2: 11-50 units → R$ 8.00/unit Tier 3: 51+ units → R$ 5.00/unit For 25 units: (10 x R$ 10.00) + (15 x R$ 8.00) = R$ 220.00 ``` ### 3. Volume (`tiered` + `volume`)[​](#3-volume-tiered--volume "Direct link to 3-volume-tiered--volume") When the customer reaches a tier, **all units** are charged at that tier's rate. ``` Tier 1: 1-10 units → R$ 10.00/unit Tier 2: 11-50 units → R$ 8.00/unit Tier 3: 51+ units → R$ 5.00/unit For 25 units: 25 x R$ 8.00 = R$ 200.00 (all in tier 2) ``` ### 4. Package (`package`)[​](#4-package-package "Direct link to 4-package-package") Fixed price for a defined package of items. ### Tier Configuration[​](#tier-configuration "Direct link to Tier Configuration") Each tier defines: | Field | Description | | ------------- | -------------------------------------------------------- | | `up_to` | Upper limit of the tier (`null` = unlimited, final tier) | | `unit_amount` | Price per unit in this tier | | `flat_amount` | Additional flat amount per tier (default: 0) | ## Usage Type[​](#usage-type "Direct link to Usage Type") | Type | Description | | ---------- | --------------------------------------------------- | | `licensed` | Fixed quantity defined in the subscription | | `metered` | Quantity measured and reported throughout the cycle | --- # Products Products represent the billable services or resources of your organization. Each product can have multiple prices and supports a one-level hierarchy (root product with children/add-ons). ## Product Fields[​](#product-fields "Direct link to Product Fields") | Field | Description | | --------------- | ----------------------------------------------------------- | | **Name** | Display name (1-255 characters) | | **Slug** | URL-friendly unique identifier | | **Description** | Details about the product | | **Type** | Determines the usage model (see table below) | | **Visibility** | `public` or `private` | | **Unit label** | Name of the unit (e.g., "users", "GB") | | **Increment** | Minimum quantity step (e.g., 10 = quantities 10, 20, 30...) | | **Required** | Whether it is required to subscribe | | **Website URL** | Link to documentation/product page | ## Product Types[​](#product-types "Direct link to Product Types") | Type | Description | Recurrence | | ------------------- | -------------------------------- | ---------------------- | | `base` | Standard recurring product | Recurring | | `addon_quantity` | Add-on with per-quantity pricing | Recurring | | `addon_fixed` | Add-on with fixed pricing | Recurring | | `metered` | Usage-based billing | Recurring (in arrears) | | `one_time_fixed` | Fixed one-time fee | One-time | | `one_time_quantity` | Per-unit one-time fee | One-time | ## Product Hierarchy[​](#product-hierarchy "Direct link to Product Hierarchy") Products support **one level** of hierarchy: ``` Root Product (parentProductId = null) ├── Child product 1 (add-on) ├── Child product 2 (setup fee) └── Child product 3 (optional module) ``` ### Hierarchy Rules[​](#hierarchy-rules "Direct link to Hierarchy Rules") * Nesting more than 1 level is not possible (children cannot have children) * Child products inherit the organization/company from the parent * Only root products can be added to plans * Child products appear as add-ons/options of the parent product ## Status and Lifecycle[​](#status-and-lifecycle "Direct link to Status and Lifecycle") ``` draft → active → archived ↓ ↑ ↓ DELETE PUBLISH RESTORE ``` | Status | Description | | ------------ | ------------------------------------------------ | | **draft** | Under development, not visible to plans | | **active** | Available for plans and subscriptions | | **archived** | Deactivated; cannot be used in new subscriptions | ### Rules[​](#rules "Direct link to Rules") * **Archive**: Not possible if used by active, trialing, or past\_due subscriptions. Automatically deactivates all prices * **Restore**: Returns to `active` status * **Publish**: Moves from `draft` to `active` ## Bulk Operations[​](#bulk-operations "Direct link to Bulk Operations") * **Bulk archive**: Archives multiple products * **Bulk delete**: Removes products not used in subscriptions * **Move to group**: Moves products to a product group * **Change visibility**: Changes the visibility of multiple products * **Change company**: Moves products to another company ## Reordering[​](#reordering "Direct link to Reordering") Products have a `display_order` field to control the display order in the dashboard and portal. Reordering is possible via drag-and-drop or API. ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Product list[​](#product-list "Direct link to Product list") The `/dashboard/products` screen lists the catalog with name, type (recurring, one-time, metered), base price, status and visibility in the portal. It supports drag-and-drop reordering and bulk actions. ![List of products with type, price and visibility](/en/assets/images/produtos-e56e5c795c38ea61375af3ba956e9353.png) ### Product detail[​](#product-detail "Direct link to Product detail") The `/dashboard/products/[id]` page brings together the linked prices (with currency and cycle), fiscal service items, plans that include the product, usage events and audit. ![Product detail with linked prices and plans](/en/assets/images/produto-detalhe-0ed8b4bd47f79a723bb1a63af415e6e3.png) --- ## [📄️Customer Portal](https://docs.billing.kobana.com.br/en/en/portal.md) [The Customer Portal is the self-service area that end customers (subscribers) use to manage their relationship with the company that uses Automatic Billing. Each portal runs at https:///portal (or on the platform's default domain) and shows only the data of the authenticated billing account.](https://docs.billing.kobana.com.br/en/en/portal.md) --- ## [📄️Customer Portal](https://docs.billing.kobana.com.br/en/en/portal.md) [The Customer Portal is the self-service area that end customers (subscribers) use to manage their relationship with the company that uses Automatic Billing. Each portal runs at https:///portal (or on the platform's default domain) and shows only the data of the authenticated billing account.](https://docs.billing.kobana.com.br/en/en/portal.md) --- # Subscriptions The `/portal/subscriptions` page lists the subscriptions linked to the authenticated billing account. Each row shows the plan, status, recurring amount, next cycle and available actions. ## Information shown[​](#information-shown "Direct link to Information shown") * **Plan and items** — main product and add-ons. * **Status** — `trialing`, `active`, `past_due`, `paused` or `canceled`. * **Cycle** — monthly, quarterly, semiannual or annual. * **Recurring amount** — in reais, formatted as `R$ 1.234,56`. * **Start of the current period** and **next cycle**. * **Payment method** — card ending, boleto or PIX. ## Available actions[​](#available-actions "Direct link to Available actions") Depending on the organization's configuration, the customer can: * **Change plan** — guided flow with a proration preview before confirming. * **Cancel** — schedule cancellation at the end of the cycle or cancel immediately (if allowed). * **Pause** — temporarily stop billing. * **Update method** — change the card without affecting the subscription. ## Subscription detail[​](#subscription-detail "Direct link to Subscription detail") When clicking a subscription, the customer sees the detail page (`/portal/subscriptions/[id]`) with: * History of invoices generated by the subscription * History of changes (plan, items, pauses) * Event timeline * Related documents (contract, original proposal) ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Subscription list[​](#subscription-list "Direct link to Subscription list") ![List of subscriptions in the customer portal](/en/assets/images/portal-assinaturas-e8f8d47fa34ae1b843bb5d1b09a30c03.png) ### Subscription detail[​](#subscription-detail-1 "Direct link to Subscription detail") ![Subscription detail with invoice and change history](/en/assets/images/portal-assinatura-detalhe-e8f8d47fa34ae1b843bb5d1b09a30c03.png) --- # Settings The `/portal/settings` page groups billing account preferences that affect **how the customer receives charges and communications**. ## Billing preferences[​](#billing-preferences "Direct link to Billing preferences") * **Default payment method** — used for automatic charges. * **Preferred due day** (when the plan allows it). * **Email for receiving invoices** — can be different from the sign-in email. * **Communication language** — `pt-BR` or `en-US`. ## Notifications[​](#notifications "Direct link to Notifications") Toggles to enable/disable: * Reminder before the invoice due date * Payment confirmation * Failed payment notice * End of trial * Plan change * Card about to expire * Receive NF-e by email Each toggle controls a specific channel (email). Webhooks for integrations are configured in the organization's administrative dashboard. ## Company details[​](#company-details "Direct link to Company details") Shortcuts to [Account](https://docs.billing.kobana.com.br/en/en/portal/conta.md) (fiscal data) and [Payment Methods](https://docs.billing.kobana.com.br/en/en/portal/metodos-de-pagamento.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Portal settings with billing and notification preferences](/en/assets/images/portal-configuracoes-bbe9bdf387bf83332f06ef45a1f1c3d0.png) --- # Account At `/portal/account` the customer manages the **billing account details** (`BillingAccount`) — legal name, CNPJ/CPF, state and municipal registration, address, finance contact and emails for receiving invoices. ## Editable data[​](#editable-data "Direct link to Editable data") * **Legal name** and **trade name** * **Document** (CNPJ or CPF) * **State registration** and **municipal registration** (when applicable) * **Full address** — used for NF-e issuance and billing * **Emails for receiving invoices and charges** * **Contact phone** ## Validations[​](#validations "Direct link to Validations") * CNPJ and CPF are validated through their check digits. * The CEP looks up the address automatically when possible. * Changes to the CNPJ require reissuing open invoices (the organization can lock this field). ## NF-e[​](#nf-e "Direct link to NF-e") When NF-e is enabled, the data on this page is copied into the issued fiscal document. Keeping the registration up to date avoids rejections due to mismatches at SEFAZ or the municipality. ## Restricted updates[​](#restricted-updates "Direct link to Restricted updates") Some fields (document, fiscal address) may be locked for direct editing depending on the organization's policy — in those cases, the customer sees instructions to open a support ticket. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Editing the billing account details in the portal](/en/assets/images/portal-conta-d5a2559cfbc23d8e55f82928bb72e499.png) --- # Credits The `/portal/credits` page shows the billing account's **credit balance** and the history of applications. Credits arise for various reasons — downgrade proration, invoice refund, manual adjustment by the organization, promotion — and are automatically applied to upcoming invoices. ## Balance[​](#balance "Direct link to Balance") The top of the page shows the total available balance in reais. When there are credits with an expiration date, the page warns about the ones close to expiring. ## History[​](#history "Direct link to History") Each credit record shows: * **Date** it was generated * **Origin** — `downgrade_proration`, `refund`, `manual_adjustment`, `promotion`, etc. * **Amount** * **Status** — `available`, `partially_applied`, `fully_applied`, `expired` * **Applications** — invoices on which the credit was consumed (partially or fully) ## How credit is applied[​](#how-credit-is-applied "Direct link to How credit is applied") When an invoice is finalized (`open`), the billing engine consumes available credits in FIFO order (oldest first), until the credit is used up or the invoice is covered. The consumed amount appears as a negative line on the invoice and the remaining balance stays available. ## When credit is **not** applied[​](#when-credit-is-not-applied "Direct link to when-credit-is-not-applied") * Invoices with `void` status or already `paid` * When the plan configuration disables the use of credit * Expired credits ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Credit balance and history in the portal](/en/assets/images/portal-creditos-07521f56b3e8dc10977bde1b5293cb88.png) --- # Invoices The `/portal/invoices` page lists all invoices of the billing account, with filters by status and period. The customer can view them, download the PDF, copy the boleto's typeable line or the PIX QR code, pay online and check the related NF-e. ## Statuses visible in the portal[​](#statuses-visible-in-the-portal "Direct link to Statuses visible in the portal") * **Open** — generated, awaiting payment. * **Paid** — settled (partially or in full). * **Overdue** — past the due date without payment. * **Canceled** — invalidated by the organization. * **Processing** — payment submitted, awaiting gateway confirmation. ## Actions per invoice[​](#actions-per-invoice "Direct link to Actions per invoice") * **Pay** — opens the payment flow with the enabled methods. * **Download PDF** — generates the invoice document. * **Copy typeable line** (boleto) — barcode ready to pay. * **Copy PIX** — copy-and-paste code or QR code. * **View NF-e** — link to the linked fiscal invoice, when issued. * **Payment history** — all attempts and refunds. ## Invoice detail[​](#invoice-detail "Direct link to Invoice detail") The detail page (`/portal/invoices/[id]`) shows: * **Line-by-line** items (description, quantity, unit price, total) * **Gross total, discounts, credits applied, taxes withheld, amount due** * **History of payment attempts** (gateway, method, status, error) * **NF-e** when there is one, with a link to download the XML and the PDF ## Screenshot — list[​](#screenshot--list "Direct link to Screenshot — list") ![List of invoices in the portal with status and actions](/en/assets/images/portal-faturas-0afcd6454adfb9dc9e95e98d02f37176.png) ## Screenshot — detail[​](#screenshot--detail "Direct link to Screenshot — detail") ![Invoice detail with items, totals and payment history](/en/assets/images/portal-fatura-detalhe-e672d7eb6fbb51759b856185eb497d9d.png) --- # Payment Methods At `/portal/payment-methods` the customer manages the payment methods associated with the billing account. The page supports multiple methods at once and defines which one is the default for automatic charges. ## Supported methods[​](#supported-methods "Direct link to Supported methods") * **Credit card** — Visa, Mastercard, Elo, Amex and Hipercard, depending on the gateway. Stores the token, brand, last 4 digits and expiration. * **Boleto** — generated for each invoice when the customer chooses boleto as the default. * **PIX** — payment via QR code or copy-and-paste, generated invoice by invoice. * **Bank transfer** — when enabled by the organization, with account details for the deposit. ## Actions[​](#actions "Direct link to Actions") * **Add card** — form tokenized by the gateway; sensitive data never goes through the platform's servers. * **Set as default** — method used for automatic charges (charge\_automatically). * **Remove** — deletes the token; future charges depend on another method. ## Expiring card[​](#expiring-card "Direct link to Expiring card") The `card-expiring` worker (weekly) detects cards about to expire and sends a notification so the customer updates it before the next charge fails. ## Security[​](#security "Direct link to Security") * Card tokens are stored at the gateway, not on the platform. * The customer never sees the full card number after registering it. * Additions and removals are recorded in the [Audit Log](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Payment methods screen with registered cards](/en/assets/images/portal-metodos-de-pagamento-f1b69d3f267da248484eea26583c9fa1.png) --- # Payments The `/portal/payments` page shows the **history of payments** already processed on the billing account — regardless of method or originating invoice. It is the statement view, useful for accounting checks and billing questions. ## Information per payment[​](#information-per-payment "Direct link to Information per payment") * **Date** of processing * **Amount** * **Method** — card, boleto, PIX, transfer * **Status** — `succeeded`, `pending`, `failed`, `refunded`, `chargeback` * **Related invoice** — link to the originating invoice * **Gateway** — when relevant (for support only) ## Filters[​](#filters "Direct link to Filters") * **Status** * **Method** * **Date range** ## Payment detail[​](#payment-detail "Direct link to Payment detail") At `/portal/payments/[id]` the customer sees the **receipt**: * Payment identifier * Paying customer, billing account * Invoice settled and its items * Method used (last 4 digits of the card, boleto bank, PIX key) * Detailed status and gateway message * Button to download the receipt as PDF ## Refunds and reversals[​](#refunds-and-reversals "Direct link to Refunds and reversals") When a payment is refunded by the organization, the status becomes `refunded` and a link points to the refund record. The corresponding credit (if any) appears in [Credits](https://docs.billing.kobana.com.br/en/en/portal/creditos.md). ## Screenshot — list[​](#screenshot--list "Direct link to Screenshot — list") ![Payment history in the portal](/en/assets/images/portal-pagamentos-d52bd0d090ce3bd1c8b1d43da478c691.png) ## Screenshot — detail[​](#screenshot--detail "Direct link to Screenshot — detail") ![Payment detail with receipt and related invoice](/en/assets/images/portal-pagamento-detalhe-c4144270c8b2a1cbbdca7162113f1192.png) --- # Profile The `/portal/profile` page gathers the **personal preferences of the user** signed in to the portal. Unlike [Account](https://docs.billing.kobana.com.br/en/en/portal/conta.md), which covers the paying legal entity or individual, the profile is per person who uses the portal. ## What the user can adjust[​](#what-the-user-can-adjust "Direct link to What the user can adjust") * **Display name** * **Email** — used for magic-link sign-in and notifications * **Theme** — light, dark or automatic * **Language** — `pt-BR` or `en-US` * **Notification preferences** — which emails to receive (invoice reminder, payment receipt, end of trial, etc.) ## Multiple users per account[​](#multiple-users-per-account "Direct link to Multiple users per account") The same billing account can have several portal users (partners, finance, accountant). Each has their own profile and email preference, but all see the same billing data. ## Security[​](#security "Direct link to Security") * Changing the email triggers a confirmation to both the old and the new email. * The confirmation token is stored encrypted (`lib/crypto.ts`). * Every change is recorded in the [Audit Log](https://docs.billing.kobana.com.br/en/en/configuracoes/auditoria.md). ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Portal user profile settings](/en/assets/images/portal-perfil-fbe7a3d3c7b0b464ee0a9dab51fea849.png) --- # Products The `/portal/products` page is the **self-service storefront** of the products and plans the organization has published for direct sale in the portal. The customer can purchase new products without going through the sales team, with checkout integrated with the payment methods already registered. ## What appears[​](#what-appears "Direct link to What appears") Only products marked as **published** (`is_published = true`) and with at least one active price. The presentation follows the grouping configured in [Product Groups](https://docs.billing.kobana.com.br/en/en/planos-e-produtos/grupos-de-produtos/.md), with cards, descriptions and a price table. ## Purchase flow[​](#purchase-flow "Direct link to Purchase flow") 1. The customer selects the product/plan. 2. Confirms quantity and add-ons. 3. Chooses or registers a payment method. 4. Confirms — a subscription is created (or a one-off order, depending on the product). 5. The first invoice is generated and charged according to the method. The whole flow follows the cycle, trial and proration settings defined by the organization. When the customer already has an active subscription, the system offers the option to add the item to the existing subscription. ## Custom catalog[​](#custom-catalog "Direct link to Custom catalog") The organization can hide products from the portal while keeping them available via the API or commercial proposals. This makes it possible to use the portal only for controlled upsell, or to offer everything as self-service. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Product storefront in the customer portal](/en/assets/images/portal-produtos-142a377c30ea893081d8c19c183d5dfc.png) --- # Proposals At `/portal/proposals` the customer sees the **commercial proposals** sent by the organization's team. Each proposal details plans, items, discounts, terms and conditions — and can be accepted directly in the portal, becoming an active subscription. ## Proposal states[​](#proposal-states "Direct link to Proposal states") * **draft** — being edited internally; not visible in the portal. * **sent** — sent to the customer, awaiting action. * **viewed** — the customer opened the proposal in the portal (recorded with a timestamp). * **accepted** — the customer accepted; creates the subscription, the first invoice and an audit entry. * **declined** — the customer declined; an optional reason is recorded. * **expired** — past its validity. ## Proposal content[​](#proposal-content "Direct link to Proposal content") * Customer and billing details * Items (plans, products, add-ons) with quantity and amount * Discounts applied, total amount and taxes * Commercial terms (term, cycle, trial) * PDF generated automatically for printing and filing ## Accept a proposal[​](#accept-a-proposal "Direct link to Accept a proposal") 1. The customer clicks **Accept**. 2. Confirms the payment method (registered or new). 3. The system creates the subscription, issues the first invoice and triggers the `proposal.accepted` webhook. 4. The customer is redirected to the newly created subscription. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![List of commercial proposals in the customer portal](/en/assets/images/portal-propostas-f16f58b4557d08b3a2fb14308c27a694.png) --- # Usage The `/portal/usage` page shows the customer the **metered consumption** accumulated in the current cycle — how many API calls, messages sent, events processed or GBs stored, according to the metrics defined by the organization. ## What is displayed[​](#what-is-displayed "Direct link to What is displayed") * **List of active metered products** on the account * **Consumption in the period** with the correct unit of measure * **Comparison** with the previous period (when available) * **Estimated charge** for the next invoice, based on consumption so far * **Limits and alerts** when the product has a cap or tiers configured ## Filters[​](#filters "Direct link to Filters") * **Date range** — defaults to the start of the current cycle through today * **Product** — when there are several metrics ## Updates[​](#updates "Direct link to Updates") The data reflects the same backend used by the administrative dashboard. Events arrive via the Usage Records API, integrations or the `usage-sync` worker (hourly). The delay is typically a few minutes. ## What it is for[​](#what-it-is-for "Direct link to What it is for") * **Predictability** — the customer knows what they will pay before the cycle turns over. * **Anomaly detection** — suspicious spikes become evident. * **Support** — billing discussions start from the same numbers the dashboard shows. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Usage/consumption metrics for the current cycle in the portal](/en/assets/images/portal-uso-93b95a4757f90041a7621721a0ae77c9.png) --- # Overview The portal home page (`/portal`) gives a **summary of the customer's financial relationship** with the organization: active subscription, next invoice, last payment, available credits and shortcuts to the most common actions. ## Main cards[​](#main-cards "Direct link to Main cards") * **Next charge** — date, amount and method (card, boleto, PIX). * **Active subscription** — plan, cycle and status. * **Last payment** — date, amount and status (succeeded, processing, failed). * **Available credit** — total balance and a link to the history. * **Open invoices** — alert when there are overdue boletos or boletos close to their due date. ## Shortcuts[​](#shortcuts "Direct link to Shortcuts") The page offers shortcuts to: * Pay the next invoice * Change the default payment method * Update billing details * Contact support ## Customization[​](#customization "Direct link to Customization") The logo, colors and texts follow the configuration defined by the organization in [Customer Portal](https://docs.billing.kobana.com.br/en/en/contas/portal-do-cliente/.md). The customer can switch between light and dark theme. ## Screenshot[​](#screenshot "Direct link to Screenshot") ![Customer portal overview with next charge and active subscription](/en/assets/images/portal-visao-geral-d5a2559cfbc23d8e55f82928bb72e499.png) --- ## [📄️PDF Generation](https://docs.billing.kobana.com.br/en/en/propostas/geracao-de-pdf/.md) [The system generates proposal PDFs by integrating with Google Docs/Slides via Google Apps Script.](https://docs.billing.kobana.com.br/en/en/propostas/geracao-de-pdf/.md) --- ## [📄️PDF Generation](https://docs.billing.kobana.com.br/en/en/propostas/geracao-de-pdf/.md) [The system generates proposal PDFs by integrating with Google Docs/Slides via Google Apps Script.](https://docs.billing.kobana.com.br/en/en/propostas/geracao-de-pdf/.md) --- # PDF Generation The system generates proposal PDFs by integrating with Google Docs/Slides via Google Apps Script. ## Generation Flow[​](#generation-flow "Direct link to Generation Flow") 1. The service creates a **temporary data token** (valid for 10 minutes) 2. Builds the secure URL with the proposal data 3. Calls the **Google Apps Script** with the data 4. The Apps Script populates the template in Google Drive 5. Returns the document ID and URLs ## Data Sent to the Template[​](#data-sent-to-the-template "Direct link to Data Sent to the Template") ### Basic Information[​](#basic-information "Direct link to Basic Information") * Generation and expiration dates * Proposal code, title, and description ### Customer Data[​](#customer-data "Direct link to Customer Data") * Name, document number, legal name * Contact (email, phone) * Responsible person (portal user) ### Products[​](#products "Direct link to Products") For each item: * Name, description, quantity * Unit price and total * Setup per unit and total * Recurring per unit and total * Whether it is a one-time product ### Prices by Cycle[​](#prices-by-cycle "Direct link to Prices by Cycle") For each cycle (monthly, quarterly, semiannual, annual): * Cycle total * Discount and percentage * First payment * Equivalent monthly amount ### Coupon[​](#coupon "Direct link to Coupon") * Code, type, and discount value ### Setup[​](#setup "Direct link to Setup") * Whether there is a setup fee, total and first payment ### Organization[​](#organization "Direct link to Organization") * Organization name and document number ## Generated URLs[​](#generated-urls "Direct link to Generated URLs") | Type | Format | | ----------------- | ----------------------------------------------------------- | | **Google Docs** | `https://docs.google.com/document/d/{id}/edit` | | **Google Slides** | `https://docs.google.com/presentation/d/{id}/edit` | | **PDF (Docs)** | `https://docs.google.com/document/d/{id}/export?format=pdf` | | **PDF (Slides)** | `https://docs.google.com/presentation/d/{id}/export/pdf` | ## Security[​](#security "Direct link to Security") Proposal data is accessed via a temporary 10-minute token. After use or expiration, the token is invalidated. --- # Proposals Proposals are commercial documents sent to customers or prospects containing items, prices, and payment terms. ## Lifecycle[​](#lifecycle "Direct link to Lifecycle") ``` draft → sent → viewed → accepted ↓ rejected ``` | Status | Description | | ------------ | --------------------------------------------------------- | | **draft** | Draft, editable | | **sent** | Sent to the customer | | **viewed** | Viewed by the customer | | **accepted** | Accepted — subscription and invoice created automatically | | **rejected** | Rejected by the customer (reason stored) | | **expired** | Expired without response | | **canceled** | Canceled by the organization | ## Proposal Fields[​](#proposal-fields "Direct link to Proposal Fields") | Field | Description | | ------------------- | ----------------------------------------------------- | | **Code** | Automatically generated unique identifier | | **Title** | Proposal title (default: "Commercial Proposal") | | **Description** | Proposal details | | **Billing account** | For existing customers | | **Prospect** | For new customers (Person with type=customer) | | **Coupon** | Applied discount coupon | | **Template** | Document template for PDF generation | | **Expiration date** | Configurable (default: according to billing settings) | | **Notes** | Internal observations | ## Proposal Items[​](#proposal-items "Direct link to Proposal Items") Each proposal contains items with products and prices: | Field | Description | | --------------- | ---------------------- | | **Product** | Quoted product | | **Price** | Selected price variant | | **Quantity** | Quantity (default: 1) | | **Unit amount** | Price per unit | Restriction: Duplicating the same product in a proposal is not allowed. ## Price Calculation[​](#price-calculation "Direct link to Price Calculation") The system automatically calculates prices per billing cycle: | Cycle | Default Discount | | ---------- | ---------------- | | Monthly | 0% | | Quarterly | 5% | | Semiannual | 10% | | Annual | 15% | Cycle discounts are configurable in the organization's billing settings. For each cycle, the system calculates: * Subtotal (sum of recurring items x months) * Cycle discount * Coupon discount * Total with discounts * Price per month * First payment (including one-time/setup fees) ## Operations[​](#operations "Direct link to Operations") ### Send (`draft` → `sent`)[​](#send-draft--sent "Direct link to send-draft--sent") Requires at least 1 item. Records `sent_at`. ### Unpublish (`sent`/`viewed` → `draft`)[​](#unpublish-sentviewed--draft "Direct link to unpublish-sentviewed--draft") Allows re-editing a previously sent proposal. ### Accept[​](#accept "Direct link to Accept") When the customer accepts: 1. Status changes to `accepted` 2. **Subscription is created** automatically with the proposal items 3. **Invoice is created and finalized** 4. The billing cycle is chosen by the customer at the time of acceptance ### Reject[​](#reject "Direct link to Reject") The customer can reject by providing an optional reason. ### Undo Acceptance[​](#undo-acceptance "Direct link to Undo Acceptance") Reverts the proposal from `accepted` to `sent` and deletes the linked subscription. ### Cancel[​](#cancel "Direct link to Cancel") Available in any state except `accepted` and `canceled`. ## PDF and Document[​](#pdf-and-document "Direct link to PDF and Document") ### Automatic Invalidation[​](#automatic-invalidation "Direct link to Automatic Invalidation") When items are modified after PDF generation, the `pdf_outdated_at` field is set, signaling that the PDF needs to be regenerated. ## Proposals in the Portal[​](#proposals-in-the-portal "Direct link to Proposals in the Portal") Customers access proposals through the portal using the unique code. They can view, accept, or reject them. ## Screenshots[​](#screenshots "Direct link to Screenshots") ### Proposal list[​](#proposal-list "Direct link to Proposal list") The `/dashboard/proposals` screen lists all commercial proposals with filters by status (`draft`, `sent`, `viewed`, `accepted`, `declined`, `expired`), customer, validity and amount. Each row shows customer, amount, days to expire and actions (send, duplicate, cancel, download PDF). ![List of commercial proposals with status and validity](/en/assets/images/propostas-d1c81604048d0b54d8b60414d953d026.png) ### Proposal detail[​](#proposal-detail "Direct link to Proposal detail") The `/dashboard/proposals/[id]` page brings together items (plans and products with quantity and amount), discounts, totals, conditions, validity, event timeline (sent, viewed, accepted) and actions to resend, duplicate or manually convert into a subscription. ![Proposal detail with items, totals and timeline](/en/assets/images/proposta-detalhe-8fa942fa9875caa438990bf62bdb7f00.png) --- # Proposal Templates Templates define the document model used to generate proposal PDFs. ## Template Fields[​](#template-fields "Direct link to Template Fields") | Field | Description | | ------------------- | ------------------------------------------------------- | | **Name** | Template name (unique per organization) | | **Description** | Details about the template | | **Google Doc ID** | ID of the template document in Google Drive | | **Document type** | `google_doc` or `google_slides` | | **Apps Script URL** | URL of the Google Apps Script deployment for generation | | **Drive folder** | ID of the folder where generated documents are saved | | **Default** | Whether it is the organization's default template | | **Active** | Whether it is available for use | ## Operations[​](#operations "Direct link to Operations") * **Create**: Provide name, Google Doc ID, and optionally Apps Script URL * **Update**: All editable fields * **Set as default**: Automatically unsets the previous default * **Activate/Deactivate**: Controls availability (cannot deactivate the only active template) * **Delete**: Only if not used by any proposal ## Google Integration[​](#google-integration "Direct link to Google Integration") The template is a Google Docs or Google Slides document containing placeholders for proposal data. Google Apps Script processes the data and generates the final document. ## Screenshot[​](#screenshot "Direct link to Screenshot") The `/dashboard/proposal-templates` screen lists the organization's proposal templates, with name, type (Google Docs, Google Slides), last update and number of proposals using each template. It includes a preview of the placeholder structure and actions to duplicate or archive. ![List of proposal templates with placeholders](/en/assets/images/templates-de-proposta-6cbef2ee229d686c013a6b7e6028aa07.png) --- ## [📄️Webhook Endpoints](https://docs.billing.kobana.com.br/en/en/webhooks/endpoints/.md) [Each organization can configure multiple endpoints to receive event notifications.](https://docs.billing.kobana.com.br/en/en/webhooks/endpoints/.md) --- ## [📄️Webhook Endpoints](https://docs.billing.kobana.com.br/en/en/webhooks/endpoints/.md) [Each organization can configure multiple endpoints to receive event notifications.](https://docs.billing.kobana.com.br/en/en/webhooks/endpoints/.md) --- # Webhook Endpoints Each organization can configure multiple endpoints to receive event notifications. ## Endpoint Fields[​](#endpoint-fields "Direct link to Endpoint Fields") | Field | Description | | --------------- | --------------------------------------------- | | **URL** | HTTPS address that will receive notifications | | **Description** | Endpoint description (max 255 characters) | | **Events** | List of subscribed event types | | **Secret** | HMAC-SHA256 key for signature validation | | **Active** | Whether the endpoint is enabled | ## Creating an Endpoint[​](#creating-an-endpoint "Direct link to Creating an Endpoint") Upon creation, the system automatically generates a **secret** (`whsec_...`) that is shown **only at creation time**. Store it securely — it is required to validate webhook signatures. ## Webhook Signature[​](#webhook-signature "Direct link to Webhook Signature") Every delivery carries the Kobana standard headers (`X-Kobana-App`, `X-Kobana-Environment`, `X-Kobana-Webhook-Id`, `X-Kobana-Event`, `X-Kobana-Event-Id`, `X-Kobana-Delivery-Id`, `X-Kobana-Timestamp`, `X-Kobana-Signature`) plus the `webhook-id` / `webhook-timestamp` / `webhook-signature` trio in the Standard Webhooks layout: ``` X-Kobana-Signature: v1, ``` ### Verification[​](#verification "Direct link to Verification") 1. Read `webhook-id`, `webhook-timestamp` and `webhook-signature` 2. Reject if the timestamp is more than 5 minutes away from your clock 3. Rebuild `delivery_id.timestamp.raw_body` and compute HMAC-SHA256 with the key (base64-decoded secret without the `whsec_` prefix) 4. Compare with each `v1,` token of the header in constant time The full algorithm, with Node.js and Python examples, is in [API Reference — Webhooks](https://docs.billing.kobana.com.br/en/en/api/overview/webhooks.md#headers-and-signature-kobana-standard). The legacy `X-Signature` header (`t=,v1=`) is still sent, deprecated. ## Secret Rotation[​](#secret-rotation "Direct link to Secret Rotation") When you suspect the secret has been compromised, use secret rotation. A new secret is generated and the previous one is invalidated immediately. ## Webhook Test[​](#webhook-test "Direct link to Webhook Test") Send a test payload to verify that the endpoint is configured correctly. The result includes the HTTP status and the received response. ## Automatic Deactivation[​](#automatic-deactivation "Direct link to Automatic Deactivation") After **10 consecutive delivery failures**, the endpoint is **automatically deactivated**. To reactivate, fix the issue and update the endpoint to active. ## SSRF Protection[​](#ssrf-protection "Direct link to SSRF Protection") URLs are validated to reject private IPs and localhost, preventing Server-Side Request Forgery attacks. --- # Webhook Deliveries Each notification sent to an endpoint is recorded as a delivery, enabling monitoring and retry. ## Delivery Status[​](#delivery-status "Direct link to Delivery Status") | Status | Description | | ----------- | --------------------------------- | | `pending` | Awaiting delivery | | `delivered` | Successfully delivered (HTTP 2xx) | | `failed` | Delivery failed | | `retrying` | Awaiting retry | ## Delivery Fields[​](#delivery-fields "Direct link to Delivery Fields") | Field | Description | | -------------------- | ----------------------------------- | | **Endpoint** | Destination webhook | | **Event** | Event that triggered the delivery | | **HTTP Status** | Destination response code | | **Request headers** | Headers sent | | **Request body** | Payload sent (JSON) | | **Response headers** | Headers received | | **Response body** | Response body (max 2000 characters) | | **Error** | Error message (if failed) | | **Attempts** | Number of attempts | | **Next retry** | Date/time of the next attempt | | **Delivered at** | Success timestamp | ## Processing Pipeline[​](#processing-pipeline "Direct link to Processing Pipeline") ### Step 1: Event Creation[​](#step-1-event-creation "Direct link to Step 1: Event Creation") ``` Operation on resource (e.g., payment created) → Event created in database → Job enqueued: EVENT_DISPATCH ``` ### Step 2: Event Dispatch[​](#step-2-event-dispatch "Direct link to Step 2: Event Dispatch") ``` Worker processes EVENT_DISPATCH → Fetches active webhooks for the organization → Filters by subscribed events → For each matching webhook: → Creates WebhookDelivery record → Enqueues job: WEBHOOK_DELIVERY ``` ### Step 3: Delivery[​](#step-3-delivery "Direct link to Step 3: Delivery") ``` Worker processes WEBHOOK_DELIVERY → Generates payload + signature → POST to webhook URL (timeout: 30s) → Success (2xx): marks as delivered, resets failure counter → Failure: updates stats, schedules retry → After 10 consecutive failures: deactivates endpoint ``` ## Automatic Retry[​](#automatic-retry "Direct link to Automatic Retry") * Failed deliveries are retried automatically * Exponential backoff (1s, 2s, 4s, 8s...) * Maximum attempts configurable per job ## Manual Retry[​](#manual-retry "Direct link to Manual Retry") Individual deliveries can be retried manually from the dashboard. ## Monitoring[​](#monitoring "Direct link to Monitoring") For each organization: * Total active/inactive webhooks * Total deliveries * Failed deliveries * Consecutive failure counters --- # Webhook Events The system emits events for all significant operations. Each organization can subscribe to the relevant types. ## Payload Format[​](#payload-format "Direct link to Payload Format") ``` { "id": "9f8b2c14-3a5d-4e77-9b10-2c6e5f0a1d33", "type": "payment.succeeded", "created_at": "2026-04-05T10:30:00.000Z", "data": { }, "changes": { "status": { "from": "open", "to": "paid" } }, "environment": "production", "version": "2026-03-01" } ``` * `id` is the event UUID and `created_at` is ISO 8601 (UTC). Every envelope field uses `snake_case`. * `data` carries the resource serialized in the same format as the v1 API, also in `snake_case`. * `changes` is optional: it shows up on events that carry field changes (`.db.updated` and `*.status_changed`), in the format `{"field": {"from": oldValue, "to": newValue}}`. ## Event Types[​](#event-types "Direct link to Event Types") ### Subscriptions (11 types)[​](#subscriptions-11-types "Direct link to Subscriptions (11 types)") | Event | Description | | ----------------------------- | --------------------- | | `subscription.db.created` | Subscription created | | `subscription.db.updated` | Subscription updated | | `subscription.db.deleted` | Subscription deleted | | `subscription.status_changed` | Status changed | | `subscription.canceled` | Canceled | | `subscription.paused` | Paused | | `subscription.resumed` | Resumed | | `subscription.renewed` | Renewed | | `subscription.trial_ending` | Trial about to expire | | `subscription.past_due` | Past due | ### Invoices (10 types)[​](#invoices-10-types "Direct link to Invoices (10 types)") | Event | Description | | ------------------------ | ----------------------- | | `invoice.db.created` | Invoice created | | `invoice.db.updated` | Invoice updated | | `invoice.db.deleted` | Invoice deleted | | `invoice.status_changed` | Status changed | | `invoice.finalized` | Finalized | | `invoice.paid` | Paid | | `invoice.payment_failed` | Payment failed | | `invoice.voided` | Voided | | `invoice.uncollectible` | Marked as uncollectible | | `invoice.overdue` | Overdue | ### Payments (8 types)[​](#payments-8-types "Direct link to Payments (8 types)") | Event | Description | | ------------------------ | --------------- | | `payment.db.created` | Payment created | | `payment.db.updated` | Payment updated | | `payment.db.deleted` | Payment deleted | | `payment.status_changed` | Status changed | | `payment.processing` | Processing | | `payment.succeeded` | Succeeded | | `payment.failed` | Failed | | `payment.refunded` | Refunded | ### Payment Methods (5 types)[​](#payment-methods-5-types "Direct link to Payment Methods (5 types)") | Event | Description | | ------------------------------- | -------------- | | `payment_method.db.created` | Method created | | `payment_method.db.updated` | Method updated | | `payment_method.db.deleted` | Method removed | | `payment_method.status_changed` | Status changed | | `payment_method.expired` | Expired | ### Plans (4 types)[​](#plans-4-types "Direct link to Plans (4 types)") | Event | Description | | ----------------- | ------------- | | `plan.db.created` | Plan created | | `plan.db.updated` | Plan updated | | `plan.db.deleted` | Plan deleted | | `plan.archived` | Plan archived | ### Products (6 types)[​](#products-6-types "Direct link to Products (6 types)") | Event | Description | | ------------------------ | --------------- | | `product.db.created` | Product created | | `product.db.updated` | Product updated | | `product.db.deleted` | Product deleted | | `product.status_changed` | Status changed | | `product.archived` | Archived | | `product.restored` | Restored | ### Billing Accounts (5 types)[​](#billing-accounts-5-types "Direct link to Billing Accounts (5 types)") | Event | Description | | -------------------------------- | ----------------- | | `billing_account.db.created` | Account created | | `billing_account.db.updated` | Account updated | | `billing_account.db.deleted` | Account deleted | | `billing_account.status_changed` | Status changed | | `billing_account.suspended` | Account suspended | ### Company, Customers, and Others[​](#company-customers-and-others "Direct link to Company, Customers, and Others") * `company.db.created` / `db.updated` / `db.deleted` / `status_changed` * `customer.db.created` / `db.updated` / `db.deleted` **Total: 56 event types** --- # Automatic Billing — Documentation ![Automatic Billing Getting Started panel](/img/screenshots/en/primeiros-passos.png) Welcome to the Automatic Billing documentation, the B2B2C platform for billing, subscriptions, and recurring payments for the Brazilian market. ## Getting Started[​](#getting-started "Direct link to Getting Started") Automatic Billing allows organizations to manage subscriptions, invoices, payments, and fiscal compliance (NF-e - Brazilian electronic invoices) for their customers through a complete platform with a dashboard, customer portal, and administrative backoffice. ## Navigation[​](#navigation "Direct link to Navigation") ### Catalog[​](#catalog "Direct link to Catalog") * [Plans and Products](https://docs.billing.kobana.com.br/en/en/planos-e-produtos.md) — Manage subscription plans, products, prices, and groups ### Subscriptions[​](#subscriptions "Direct link to Subscriptions") * [Subscriptions](https://docs.billing.kobana.com.br/en/en/assinaturas.md) — Lifecycle, plan changes, pausing, billing terms ### Financial[​](#financial "Direct link to Financial") * [Invoices and Payments](https://docs.billing.kobana.com.br/en/en/faturas-e-pagamentos.md) — Invoices, payments, payment methods, credits, and installments * [Coupons and Discounts](https://docs.billing.kobana.com.br/en/en/cupons-e-descontos.md) — Promotional coupons and discount codes * [Delinquency Management](https://docs.billing.kobana.com.br/en/en/gestao-de-inadimplencia.md) — Dunning, payment retries, suspension, and recovery ### Integrations[​](#integrations "Direct link to Integrations") * [Payment Gateways](https://docs.billing.kobana.com.br/en/en/gateways-de-pagamento.md) — Providers, configuration, and callbacks * [Webhooks](https://docs.billing.kobana.com.br/en/en/webhooks.md) — Endpoints, events, and deliveries ### Fiscal[​](#fiscal "Direct link to Fiscal") * [Electronic Invoice](https://docs.billing.kobana.com.br/en/en/nota-fiscal.md) — Configuration, automatic issuance, and NF-e (Nota Fiscal Eletronica) providers * [Taxes](https://docs.billing.kobana.com.br/en/en/impostos.md) — Calculation engine, tax rules, withholdings, and Simples Nacional (simplified tax regime) ### Commercial[​](#commercial "Direct link to Commercial") * [Commercial Proposals](https://docs.billing.kobana.com.br/en/en/propostas.md) — Creation, sending, and acceptance of proposals ### Administration[​](#administration "Direct link to Administration") * [Accounts](https://docs.billing.kobana.com.br/en/en/contas.md) — Organizations, billing accounts, customers, and portal * [Export and Import](https://docs.billing.kobana.com.br/en/en/exportacao-e-importacao.md) — Bulk data export and import * [Settings](https://docs.billing.kobana.com.br/en/en/configuracoes.md) — Company, billing, rate limiting, notifications, and emails ---