Composite tools
Multi-step flows packaged as one tool — fewer round-trips, atomic outcomes.
Composite tools wrap several underlying API operations behind one call. They reduce latency, simplify the agent’s reasoning, and let EPD coordinate retries and rollback semantics that would be hard to get right from outside.
There are 11 composite tools today. All write tools accept an optional idempotency_key; pass one whenever the client may retry the same intent.
Onboarding & charging
create_customer_and_charge
In one call: create a customer, attach a payment method via billing_id, and run a one-time charge.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | false | true | false |
Best for: signup-and-pay flows. See Onboard and charge recipe.
Required: customer (email, first_name, last_name, phone), billing_id, amount, currency.
Optional: metadata, idempotency_key.
Returns: customer_id, payment_method_id, order_id, order_status, or a payment error with the created customer/payment method ids.
create_customer_and_subscribe
Create a customer, attach a payment method, and start a subscription — all in one call.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | false | true | false |
Required: customer (email, first_name, last_name, phone), billing_id, plan_id, billing_cycle.
Optional: coupon_code, shipping_address_id, shipping_address, shipping_option_id, end_date, billing_cycles, metadata, idempotency_key.
Returns: customer_id, payment_method_id, subscription_id, subscription_status, and the initial order status.
process_order
Validate the customer, create the order, and run the charge as a single unit. Catches inconsistencies (e.g. a customer without payment methods) before any side effect happens.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | false | true | false |
Required: customer_id, payment_method_id, items (array of { product_id, quantity }).
Optional: currency, description, shipping_address_id, shipping_address, coupon_code, metadata, idempotency_key.
Returns: the created order with its final succeeded or failed status.
Refunds & cancellations
cancel_subscription_and_report
Cancel a subscription and return a billing summary in the same response — billed-to-date, refunded, period covered.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | true | true | false |
Required: subscription_id.
Optional: metadata, idempotency_key.
Returns: the canceled subscription status plus lifetime billing totals. Cancellation is immediate.
refund_transaction
Refund a transaction directly by transaction id (the underlying call is at the order level).
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | true | true | false |
Required: transaction_id.
Optional: amount (in cents; defaults to the full remaining balance), refund_reason, metadata, idempotency_key.
Returns: the refund transaction and updated order status.
refund_and_cancel
Cancel a subscription and refund the most recent order in one call. The most common “we’d like to make this right” flow.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | true | true | false |
Required: subscription_id.
Optional: refund_amount (in cents; null or omitted for full refund), refund_reason, metadata, idempotency_key.
Returns: refund id, refund amount, canceled subscription status, and any structured error. Cancellation is immediate.
retry_failed_charge
Re-attempt a failed transaction against a different payment method — it reconstructs the order from the failed transaction and creates a new order on the chosen card. To re-attempt on the same card (and to reconcile a failed subscription cycle so the billing cron won’t double-charge), use the primitive retry_order instead.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | true | true | false |
See Retry failed charge recipe.
Required: transaction_id.
Optional: payment_method_id (omit to retry the same card), idempotency_key.
Returns: the new transaction status, amount, and currency.
Reporting & insight
get_customer_financial_summary
Holistic financial overview of a single customer: lifetime value, subscriptions, recent payments, refunds, dispute count.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
true | false | true | false |
See Customer 360 recipe.
Required: customer_id.
Returns: customer details, lifetime totals, subscriptions, payment methods, recent orders, and open billing issues.
get_revenue_summary
Revenue metrics across a date range, broken down by currency and (optionally) by plan.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
true | false | true | false |
Required: start_date, end_date.
Optional: currency, plan_id, group_by.
Returns: gross revenue, refunds, net revenue, order count, and breakdowns for the selected range.
list_past_due_subscriptions
List subscriptions whose most recent renewal failed — input for dunning.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
true | false | true | false |
Optional: limit, starting_after, ending_before, plan_id, customer_id.
Returns: paginated subscriptions with the latest failed renewal details.
Convenience
setup_webhook_monitoring
Create a webhook endpoint with a sensible default event scope (all critical payment / subscription events) in one call.
| readOnly | destructive | idempotent | openWorld |
|---|---|---|---|
false | false | true | true |
Required: url.
Optional: description, api_version, idempotency_key.
Returns: the webhook endpoint and the whsec_... signing secret once.
When in doubt, prefer composite tools. They are designed to be the right answer for the most common multi-step flows.