Saltar al contenido principal

Idempotencia

Las tools que crean un recurso o mueven dinero aceptan un argumento opcional idempotency_key. Se envía al endpoint como la cabecera X-Idempotency-Key que la API REST ya honra.

{ "name": "billing_invoices_create",
"arguments": {
"billing_account_id": "…",
"total": 1250.00,
"idempotency_key": "7c4a8d09-ca37-4f21-b1f0-3d2f2b8c9a11"
} }
FormatoCadena opaca, de 1 a 255 caracteres. Un UUID es la elección habitual.
Repetición con el mismo cuerpoDevuelve la respuesta original, sin ejecutar la operación de nuevo.
Repetición con cuerpo distintoConflicto.

Por qué un agente necesita esto más que tu backend​

Un cliente MCP que agota el tiempo y reintenta, o un modelo que decide "no estoy seguro de que eso funcionó, lo rehago", es exactamente el patrón que crea la segunda factura, el segundo cobro y el segundo cliente. Tu backend tiene un bucle de reintento que escribiste tú; el agente tiene un juicio.

Envía una clave siempre que la operación cobre, emita o cree. Las lecturas y actualizaciones son naturalmente idempotentes y no piden clave.

Tools que la aceptan​

FamiliaTools
customersbilling_customers_create, billing_customers_upsert, billing_billing_accounts_create, billing_billing_accounts_upsert
portal-usersbilling_customer_users_create, billing_customer_users_invite
users, rolesbilling_dashboard_users_create, billing_dashboard_users_upsert, billing_team_roles_create, billing_team_roles_upsert
products, plans, servicesbilling_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-changesbilling_subscriptions_create, billing_subscriptions_upsert, billing_subscriptions_items_change, billing_plan_changes_execute, billing_plan_changes_rules_create
invoicesbilling_invoices_create, billing_invoices_upsert, billing_invoices_finalize, billing_invoices_pay, billing_invoices_installments_pay, billing_subscriptions_create_invoice
paymentsbilling_payments_create, billing_payments_retry, billing_payments_refund, billing_payment_methods_create, billing_payment_methods_upsert
credits, couponsbilling_credits_create, billing_credits_upsert, billing_coupons_create, billing_coupons_upsert
nfes, companiesbilling_nfes_create, billing_nfes_upsert, billing_nfes_issue, billing_companies_create, billing_companies_upsert
tax-rules, tax-periods, withholdingsbilling_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, templatesbilling_proposals_create, billing_proposals_upsert, billing_proposals_send, billing_proposals_accept, billing_proposal_templates_create, billing_proposal_templates_upsert
usagebilling_usage_report, billing_usage_snapshots_daily_create, billing_usage_snapshots_monthly_create

:::caution Las que cobran billing_invoices_pay, billing_payments_create, billing_payments_retry y billing_nfes_issue producen un efecto en el mundo — un cobro en la pasarela, una nota fiscal en la autoridad tributaria — que ningún _delete deshace. Envía idempotency_key en esas incluso cuando creas que no vas a repetir. :::

Upsert no es idempotencia​

*_upsert empareja un registro existente por id, luego external_id, luego por la clave de negocio del recurso, y crea solo si no encuentra ninguno. Eso resuelve "no sé si ya existe", que es un problema distinto de "no sé si mi llamada llegó". Las dos cosas se combinan bien: un upsert con idempotency_key es seguro en ambas dimensiones.