API REST

Plan, moneda y facturación

El plan de la empresa, la moneda en que ve los precios y los datos de facturación.

  • Plan y moneda (la pantalla Empresa → Plan; solo admins y dueños, para los demás 403). Durante la beta no se cobra nada. Cada empresa tiene una moneda (BRL, USD, EUR, GBP, MXN, ARS, CLP o COP), que nace del país desde donde se creó (sin él, BRL), y cada plan tiene un precio definido en cada moneda, mensual y anual, sin conversión. Los valores vienen en amount_minor, entero en la unidad mínima de la moneda (4990 es R$ 49,90; el peso chileno no tiene decimales), con amount y formatted (como lo muestra la pantalla) al lado.
  • GET /billing (tracker:read): currency, currency_locked (con el cobro activado, solo el equipo de Aquarela cambia la moneda), currencies, plan (key, name, description, ai_credits_per_cycle, null para el de por defecto del servidor, storage_gb, el espacio de archivos en GB, null para el de por defecto, features, lo que incluye el plan, y prices en la moneda de la empresa), plan_source (subscription, o default cuando vale el plan por defecto), price (el actual), subscription (status: trialing, active, past_due o canceled; interval: month o year; current_period_start, current_period_end, trial_ends_at y billing_provider, null mientras no hay cobro), plans (los que la empresa puede tener, con el precio en su moneda), billing_details y plan_request (el pedido de plan pago esperando al equipo de Aquarela: plan, interval, requested_by y created_at; null sin pedido).
  • PATCH /billing (tracker:write), en JSON: {"currency": "USD"} cambia la moneda; {"billing_details": {...}} cambia los datos de facturación, solo los campos enviados (null borra): kind (company o individual), legal_name, email, country (ISO de dos letras), address_line1, address_line2, city, state, postal_code, tax_id_type y tax_id. El documento sigue al país, con los tipos de Stripe: br_cnpj (empresa) y br_cpf (persona física), con los dígitos verificados, us_ein, eu_vat, gb_vat, mx_rfc, ar_cuit, cl_tin y co_nit; sin tax_id_type, vale el del país. Devuelve lo mismo que el GET; una regla rechazada vuelve 422.
  • POST /billing/plan (tracker:write), en JSON: {"plan": "pro", "interval": "year"} (plan es la key o el id de uno de los plans; interval, month por defecto). Un plan gratuito en la moneda de la empresa cambia al instante (outcome: changed); un plan pago, o sin precio en la moneda, se vuelve un pedido al equipo de Aquarela (requested), que acuerda el pago y pone la empresa en el plan; el actual devuelve unchanged. Pedir otro plan reemplaza el pedido. Devuelve outcome, plan, interval y billing (lo mismo que el GET). DELETE /billing/plan-request (tracker:write) cancela el pedido ({"cancelled": true}; false sin pedido). En el MCP: get_billing, update_billing, change_plan y cancel_plan_request.
  • Espacio de archivos: cada plan da un espacio para los adjuntos de la empresa (storage_gb; el de por defecto es 10 GB), que suma los adjuntos de las tareas (con los de los comentarios y las versiones de la aprobación), de la mesa de ayuda y de los Chats, también los directos. La foto de perfil, el logo y el ícono de proyecto no cuentan. Cuando se acaba el espacio, el envío de un adjunto nuevo (pantalla, API y MCP) devuelve 422 con el mensaje del límite; los archivos que el cliente manda a la mesa de ayuda entran igual, para que ningún ticket se pierda. El GET /billing trae storage: used_bytes, limit_bytes, plan_storage_gb (null en el de por defecto), state (ok, warning con 90% o más, full) y la suma por lugar en tasks, tickets, chat y direct_messages (bytes y files).
  • Archivos de la empresa (la pantalla Empresa → Archivos; solo admins y dueño, para los demás 403): GET /files (tracker:read) trae storage (como en el GET /billing), total, has_more y files, del más nuevo al más antiguo (?sort=size, los más grandes primero), cada uno con id, origin (task, ticket o chat), name, type, size_bytes, created_at, uploaded_by, project (id, slug, name), issue (id, code, title, comment_id), ticket (id, number, subject) o chat_message (id, thread_id), según el origen, url (dónde está en el tracker), download_url, can_delete y locked (proof: versión enviada para aprobación; trash: tarea o proyecto en la papelera; null cuando se puede eliminar). Filtros: ?origin=, ?query= (parte del nombre), ?limit= hasta 100 y ?offset=. Los archivos de las conversaciones directas cuentan en el espacio, pero no aparecen: solo las dos personas de la conversación los ven. GET /files/{id} (tracker:read) descarga el archivo; DELETE /files/{id} (tracker:write) elimina el archivo de donde está y libera el espacio ({"deleted": true, "origin": ..., "name": ...}; un archivo bloqueado devuelve 422). En el MCP: list_files y delete_file.