Tool Reference
The complete tool surface of mcp.elasticpay.co. The five documentation and
schema tools need no authentication and are also served alone at
https://mcp.elasticpay.co/mcp/docs; everything else requires a
connection and operates on your sandbox account.
The live read-only server at /mcp/live is a separate, smaller
surface: the docs tools plus the same read tools as sandbox — whoami,
list_customers, get_customer, list_customer_payment_intents,
list_payment_methods, get_payment_intent, list_payment_plans,
get_payment_plan, list_plan_payment_intents, and
list_webhook_events — with identical parameters, live data, and no write
tools at all. Anything an agent reads on a live account it can rehearse on
sandbox first. See
Operate a live account.
Each tool wraps one call to the REST API, so responses are
the API’s JSON verbatim — statuses, references (cus_…, pm_…, pi_…),
and error shapes match the API documentation
exactly. The exceptions are the
customer-import and
payment-plan-import tools, whose
responses and error envelope follow their own shared contract, described
below.
Documentation and schema (no auth)
Section titled “Documentation and schema (no auth)”| Tool | What it does |
|---|---|
search_docs |
Search this documentation; returns the most relevant pages with snippets and Markdown URLs |
get_doc_page |
Fetch one documentation page as Markdown by path, e.g. api/getting-started/quick-start |
get_openapi_schema |
Return the full OpenAPI 3.1 schema — the authoritative request/response shapes |
list_endpoints |
List every API endpoint as method, path, and summary |
describe_endpoint |
Return the full OpenAPI operation (parameters, request body, responses) for one endpoint |
Connection
Section titled “Connection”| Tool | Parameters | What it does |
|---|---|---|
whoami |
— | Describe the current connection: auth kind (oauth or api_key), mode, and for OAuth the connected sandbox account |
Customers
Section titled “Customers”| Tool | Parameters | What it does |
|---|---|---|
create_customer |
name, email, billing_email?, reference?, test_clock? |
Create a sandbox customer. billing_email is where billing correspondence goes when it differs from email, and the list_customers email filter matches it too. Pass a test_clock (clk_…) at creation for plans that should follow simulated time |
list_customers |
limit?, starting_after?, email?, name?, reference?, status?, test_clock? |
List customers, newest first, with cursor pagination. name is a partial, case-insensitive match; email is an exact, case-insensitive match on email or billing_email; status is active, hold (created with a payment method still to be collected) or cancelled; it’s informational and doesn’t start or stop payments. reference is an exact, case-insensitive match on your candidate key, so it returns at most one customer. Customers created on a test clock appear only when test_clock names their clock; test_clock is sandbox only |
get_customer |
customer_id |
Fetch one customer in full: contact details, billing and shipping addresses, phones, notification and surcharge preferences, and additional_attributes |
list_customer_payment_intents |
customer_id, limit? |
List a customer’s payment intents, newest first |
Payment methods
Section titled “Payment methods”| Tool | Parameters | What it does |
|---|---|---|
create_payment_method |
fixture_token, customer_id?, card_name? |
Save a card or bank account using a sandbox fixture token — no widget, real card or real account involved. A card fixture’s outcome (succeed, decline, 3DS, timeout) travels with the saved method. tok_sandbox_au_becs_debit saves a bank account with an accepted mandate, whose debits settle on the test clock; the failing bank fixtures fail every debit |
list_payment_methods |
customer_id? |
List saved payment methods, optionally for one customer |
detach_payment_method |
payment_method_id |
Detach a payment method so it can no longer be charged |
Payment intents
Section titled “Payment intents”| Tool | Parameters | What it does |
|---|---|---|
create_payment_intent |
amount, currency?, customer_id?, payment_method?, metadata? |
Create a payment intent. Amounts are integer cents (minimum 200), currency AUD |
confirm_payment_intent |
payment_intent_id, payment_method? |
Confirm the intent, executing the charge. Pass payment_method — confirmation requires it even when one was given at creation. total_amount in the response is what was charged, and includes any surcharge added here |
get_payment_intent |
payment_intent_id |
Fetch an intent and its current status |
cancel_payment_intent |
payment_intent_id |
Cancel an intent that has not completed. A plan’s payment is skipped, as the dashboard’s Skip does, and the plan collects the amount at the end if it has a total. That’s refused with invalid_status_for_cancel, changing nothing, when the payment is dated today or earlier, falls inside a suspension period, belongs to a closing or closed plan, or has been claimed or sent for processing: see Canceling a plan’s payment |
refund_payment_intent |
payment_intent_id, amount?, reason? |
Refund a succeeded intent. What is refundable is total_amount, not the amount the intent was created for — omit amount for a full refund |
Payment plans
Section titled “Payment plans”| Tool | Parameters | What it does |
|---|---|---|
create_payment_plan |
customer_id, recurring_amount_cents, start_date, frequency_type?, number_of_payments?, until_further_notice?, payment_instrument_id?, name?, failure_behaviour? |
Create a recurring plan. Frequencies: weekly, fortnightly, monthly, quarterly, annual. failure_behaviour is NEW_AT_END (default), TRY_AGAIN, DOUBLE_UP or DO_NOTHING — see failure behaviours |
activate_payment_plan |
payment_plan_id |
Activate the plan so scheduled payments start |
suspend_payment_plan |
payment_plan_id |
Suspend an active payment plan until you resume it. Payments due meanwhile are skipped; a plan with a total runs longer. Not the same as add_plan_suspension_period, which has end dates. Safe to repeat |
resume_payment_plan |
payment_plan_id |
Resume a suspended payment plan, whatever suspended it, from today. Refused while the plan has no usable payment method. Safe to repeat |
list_payment_plans |
limit?, starting_after? |
List the account’s recurring payment plans |
get_payment_plan |
payment_plan_id |
Fetch a plan, its current status and its schedule changes (payment_adjustments, balance_adjustments, suspension_periods). state is draft, active, inactive, suspended, closing or closed. remaining_amount_cents is what it has left to schedule beyond what was collected or is in flight; 0 with no next_date means nothing more will be scheduled, not that its last payments were sent or settled (list_plan_payment_intents shows their status). A payment that fails later is collected again unless the plan is closed. pause says why a suspended plan isn’t collecting |
list_plan_payment_intents |
payment_plan_id, limit? |
List the intents a plan has generated — how you observe a renewal after advancing a clock |
adjust_plan_payment |
payment_plan_id, date, amount_cents, type, change_total_amount?, idempotency_key |
Set what one future date collects; 0 skips it. type is required: aligned (recommended) when the plan should now expect the new amount, manual when it should still expect the scheduled amount, so a shortfall shows as arrears |
remove_plan_payment_adjustment |
payment_plan_id, date, idempotency_key |
Undo the change to a date; the total never changes |
add_plan_balance_adjustment |
payment_plan_id, date, amount_cents, description?, external_reference?, idempotency_key |
Record money collected outside the plan’s debits (a non-debit payment in the dashboard). external_reference is your own free-form reference, not checked for uniqueness; a blank one is treated as absent |
remove_plan_balance_adjustment |
payment_plan_id, balance_adjustment_id, idempotency_key |
Remove a balance adjustment; the plan collects the amount again |
add_plan_suspension_period |
payment_plan_id, start_date, end_date, idempotency_key |
No payments between two dates, both included. Not suspend_payment_plan, which has no end date |
change_plan_suspension_period |
payment_plan_id, suspension_period_id, start_date, end_date, idempotency_key |
Move a suspension period |
remove_plan_suspension_period |
payment_plan_id, suspension_period_id, idempotency_key |
Remove a suspension period that hasn’t begun |
close_payment_plan |
payment_plan_id, closing_amount_cents, accept_large_closing_amount?, idempotency_key |
Close a plan for good, optionally collecting a final amount first, scheduled in instalments of up to $300. The plan is closing until its final payments have succeeded (a card payment when it’s approved, a bank debit once it clears), then closed. A final amount above 0 that equals or exceeds the remaining balance needs accept_large_closing_amount: true; after a refusal for want of it, call again with it and a new idempotency_key. See Close a plan |
The schedule tools and close_payment_plan are sandbox only, like every write tool. Each needs an idempotency_key: a new
unique value for each change, and the same value to retry it, which returns the original result
without applying the change twice. Reusing a key for a different request is refused. The rules are
the API’s: see Changing a plan’s schedule.
suspend_payment_plan and resume_payment_plan take no idempotency_key: they’re safe to repeat.
Setup intents
Section titled “Setup intents”| Tool | Parameters | What it does |
|---|---|---|
create_setup_intent |
customer_id?, metadata? |
Create a setup intent for saving a payment method without charging |
confirm_setup_intent |
setup_intent_id, payment_method_id |
Confirm a setup intent with a saved payment method |
Test clocks
Section titled “Test clocks”Sandbox time under programmatic control — the full concept is covered in Test clocks. Up to 3 clocks can be active at once.
| Tool | Parameters | What it does |
|---|---|---|
create_test_clock |
frozen_time, name? |
Create a clock frozen at an ISO 8601 time. Attach customers at creation via create_customer |
simulate_bank_dishonour |
payment_intent_id, code |
Dishonour one sandbox bank debit that has been sent and not yet settled, at the test clock’s time. See bank debit outcomes for the codes |
simulate_bank_late_return |
payment_intent_id, code |
Return one settled sandbox bank debit late, at the test clock’s time. late_return and late_return_insufficient_funds are collected again under the plan’s failure behaviour; dd_claim and recall stop the bank account and suspend every plan of the customer for your review, with no email to the customer |
advance_test_clock |
test_clock_id, frozen_time |
Advance to a future time. Asynchronous: status goes advancing then ready — poll get_test_clock, then inspect plans, intents, and events for what fired |
get_test_clock |
test_clock_id |
Fetch a clock and its status |
list_test_clocks |
— | List test clocks |
delete_test_clock |
test_clock_id |
Delete a clock and its simulated resources |
Webhook events
Section titled “Webhook events”| Tool | Parameters | What it does |
|---|---|---|
list_webhook_events |
event_type?, limit?, starting_after? |
List the account’s recent webhook events, newest first, each with its latest delivery status. Webhooks are the source of truth for payment outcomes — this is how an agent closes the loop without hosting an endpoint |
Customer imports (sandbox, OAuth only)
Section titled “Customer imports (sandbox, OAuth only)”Five tools that stage a bulk customer dataset, freeze it into a content-hashed manifest, and hand that manifest to the merchant for approval in their dashboard. Approval is never an API call, and neither are the merchant’s stop and rollback controls — the agent that proposed an import can never operate the controls that govern it. The walkthrough is Migrate customers with an agent.
These tools exist on the sandbox server only, and only for OAuth
connections: the merchant’s approval binds to the connected application,
which a raw sk_sandbox_ key does not identify. A call over an API-key
connection is refused with that explanation. Live enablement is gated on a
separate release; today the API answers sandbox_only for a non-sandbox
account.
Every import is bound at begin_customer_import to your sandbox account and
the connected application. The tool inputs carry no account or connection
identity — the server derives both from the token, and an import belonging to
another account or another application answers not_found.
| Tool | Parameters | What it does |
|---|---|---|
begin_customer_import |
import_key, source_reference, declared_count, field_mapping, requested_decide_by? |
Create a staging import with an exact row budget. Returns the cim_… reference, the limits in force, and staging_expires_at. Idempotent on import_key |
append_customer_import_rows |
customer_import, chunk_key, rows |
Stage one chunk of 1–500 rows. Atomic: accepted whole or rejected whole. Returns accepted and the running staged_total. Idempotent on chunk_key |
finalize_customer_import |
customer_import |
Freeze the rows, validate the complete dataset, and propose it to the merchant. Returns the action (aoa_…), dataset_hash, row_count, the projection the merchant will see, and decide_by |
get_customer_import |
customer_import |
Poll the combined state. The body is state-shaped: progress while executing, outcome once execution has ended, rollback_action once rolled back |
cancel_customer_import |
customer_import |
Withdraw an import that is staging or requires_approval. An approval, once given, belongs to the merchant and cannot be cancelled from here |
Inputs
Section titled “Inputs”begin_customer_import:
| Field | Type | Notes |
|---|---|---|
import_key |
string, 1–128 | Idempotency key, scoped to your connection and account |
source_reference |
string, 1–200 | Human label for where the rows came from; shown to the merchant |
declared_count |
integer, 1–10,000 | The exact number of rows you will stage — a budget, not a ceiling |
field_mapping |
object, ≥1 key | Display provenance: allow-listed target field → the source column it came from. It neither transforms rows nor gates validation; rows must already be in target shape |
requested_decide_by |
ISO 8601 date-time, optional | Ask for a decision deadline; capped at 7 days from finalisation |
append_customer_import_rows:
| Field | Type | Notes |
|---|---|---|
customer_import |
cim_… |
From begin_customer_import |
chunk_key |
string, 1–128 | Idempotency key, scoped to the import |
rows |
array, 1–500 | Rows in the shape below. Every source_row_key must be unique across the whole import |
The other three tools take only customer_import.
Row fields
Section titled “Row fields”Rows are validated for shape at append_customer_import_rows; unknown
fields are rejected, so this list is the whole surface.
| Field | Required | Type |
|---|---|---|
source_row_key |
yes | string, 1–120 — your stable id for the row, used in every error and failure report |
name |
yes | string, 1–200 |
email |
yes | email, ≤254 |
reference |
no | string, 1–60 — the merchant’s own customer id, a candidate key: unique per account (trimmed, case-insensitive). Set it; the payment-plan import names customers by it |
business_name |
no | string, 1–200 |
billing_email |
no | email, ≤254 |
currency |
no | 3-letter uppercase code |
timezone |
no | string, 1–64 |
sms_phone_raw |
no | string, 1–32 |
sms_phone_country |
no | 2-letter uppercase country code |
billing_address |
no | address object |
shipping_address |
no | address object |
An address object accepts line1, line2 (≤200 each), city_or_suburb,
state_or_region (≤100 each), postal_code (≤20), and country
(2-letter uppercase code), all optional, nothing else.
Excluded by construction: consent_authorised,
payment_amount_limit_exempt, fee_preferences, notification_preferences,
status, and test_clock cannot be imported. An import asserts no consent
and grants no exemptions on anyone’s behalf. additional_attributes is
reserved for a later release and rejected today.
State machine
Section titled “State machine”get_customer_import returns one status field carrying the combined
judgment and workflow state:
staging ──finalize──▶ requires_approval ──approve──▶ approved ─▶ executing │ │ │ │ │ cancel / staleness │cancel │ decide_by passes merchant │ ▼ ▼ ▼ stop │ │cancelled cancelled expired ▼ ▼ rejected ◀─ merchant rejects stopped completed | │ partially_completed | │ failed └──────┬──────┘ merchant rollback▼ rolled_back| Status | Meaning |
|---|---|
staging |
Rows are being appended. No manifest exists yet |
requires_approval |
Frozen and proposed; waiting for the merchant |
approved |
The merchant said yes. Transient — execution starts automatically |
executing |
Rows are being created; progress carries created, failed, remaining |
completed / partially_completed / failed |
Execution ended; outcome carries created, failed, and up to 20 failures_sample entries keyed by source_row_key |
stopped |
The merchant halted execution. Rows never claimed did not run; customers already created remain. Distinct from partially_completed so “some rows failed” and “I stopped it” stay separate facts |
rejected |
The merchant said no |
expired |
Nobody decided before decide_by. Silence never approves |
cancelled |
Withdrawn by the agent, by staging staleness, or by revocation of the connection while unapproved |
rolled_back |
The merchant ran the compensating rollback; rollback_action names it. Only import-created customers with no later records and no merchant edits are archived; every skip is reported to the merchant |
The poll body is state-shaped: staging has no action, dataset_hash, or
decide_by; executing carries progress and a null outcome; the four
terminal-executed states carry outcome and a null progress;
rolled_back additionally carries rollback_action. While executing,
created + failed + remaining equals the row count; at stopped,
created + failed can fall short of it by exactly the rows that never ran.
Revoking the connection while an import is staging or requires_approval
cancels it. Revoking after approval does not halt execution — the
merchant’s approval is the authority, and the merchant holds the stop
control — the agent merely loses the ability to poll.
Idempotency
Section titled “Idempotency”Every keyed call stores a fingerprint of the agent-supplied payload. Server-derived identity is excluded from the fingerprint, so a routine token refresh never breaks a replay.
begin_customer_importis idempotent onimport_keyper connection and account;append_customer_import_rowsonchunk_keyper import. The same key with a byte-identical payload replays the original response withreplayed: true. The same key with a different payload answersidempotency_conflict— corrected rows need a newchunk_key, never a reused one.- A chunk is atomic, so a replayed
chunk_keynever means half a chunk. finalize_customer_importreplays its original response only while the import is stillrequires_approval; in any later state it answersstate_conflict— pollget_customer_importinstead.cancel_customer_importreplays while the import iscancelled.- After finalisation, every mutation answers
post_finalisation_mutation. Any change to the dataset is a new import.
Validation
Section titled “Validation”append_customer_import_rowsrejects unknown row fields, duplicatesource_row_keys (duplicate_source_row_keys, with the offending keys indetails), and any chunk that would take the staged total pastdeclared_count(limit_exceeded).finalize_customer_importrequires staged rows to equaldeclared_countexactly (declared_count_mismatch) and refuses a dataset with zero valid rows (zero_valid_rows). Rows that pass shape checks but fail model validation — an email the API rejects, areferencealready taken — stay in the frozen dataset, are counted asinvalidin the projection with up to 20errors_sampleentries, and become per-row failures at execution.- A row valid at finalisation can still fail at execution if, say, its
referenceis taken in between; it appears inoutcome.failures_sample.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
declared_count |
1 – 10,000 |
| Rows per chunk | 1 – 500 |
decide_by |
72 hours from finalisation by default; requested_decide_by capped at 7 days |
| Staging TTL | A staging import untouched for 7 days is cancelled and its rows purged |
| Staged-row retention | Rows of a terminal import are purged 30 days after the terminal state; the manifest (hash, counts, projection) is permanent |
Errors
Section titled “Errors”Import errors return as a tool error whose text is code: message, followed
by any details and meta as JSON — the whole envelope, because the
details (duplicate keys, staged-versus-declared counts) are what an agent
needs to correct its request.
| Code | When |
|---|---|
not_found |
Unknown import, or one belonging to another account or another connected application |
inactive_biller |
The account is not active |
state_conflict |
The call is not allowed in the import’s current state — e.g. cancelling after approval, or finalising again after the merchant has decided |
idempotency_conflict |
A reused import_key or chunk_key whose payload differs from the original |
post_finalisation_mutation |
An append or other mutation after finalisation |
invalid_request |
The body does not match its request schema, outside the row-specific cases |
chunk_too_large |
More than 500 rows in one chunk |
invalid_rows |
Rows that fail shape validation |
duplicate_source_row_keys |
A source_row_key repeated within the import; details lists them |
declared_count_mismatch |
Finalising with staged rows ≠ declared_count |
zero_valid_rows |
Finalising a dataset in which no row would create its record (a customer, a payment plan) |
limit_exceeded |
A chunk that would exceed declared_count, or any other limit |
Payment plan imports (sandbox, OAuth only)
Section titled “Payment plan imports (sandbox, OAuth only)”Five tools that stage a bulk dataset of recurring schedules for customers who already exist on the account, freeze it into a content-hashed manifest, and hand it to the merchant for approval in their dashboard. The envelope is the customer import’s — the same calls, states, poll shape, idempotency rules, limits, and error codes — applied to plans, so this section states only what differs and points to the customer-import section for the rest. The walkthrough is Migrate payment plans with an agent.
The same gate applies: sandbox server only, OAuth connections only
(connected_app_required over an API key, sandbox_only for a non-sandbox
account), identity derived from the token, and not_found for an import
belonging to another account or application. References are pim_….
Every plan an import creates is a draft. It has no payment
instrument, generates no payment intents, and moves no money. It activates
when the customer adds a payment method or when the merchant activates it
in the dashboard — never by the import.
| Tool | Parameters | What it does |
|---|---|---|
begin_payment_plan_import |
import_key, source_reference, declared_count, field_mapping, requested_decide_by? |
Create a staging import with an exact row budget. Returns the pim_… reference, the limits in force, and staging_expires_at. Idempotent on import_key. Nothing binds it to a customer import: customers are resolved by reference at finalisation |
append_payment_plan_import_rows |
payment_plan_import, chunk_key, rows |
Stage one chunk of 1–500 plan rows. Atomic, idempotent on chunk_key; every source_row_key must be unique across the import. Rows are validated for shape here — including the two exactly-one rules below |
finalize_payment_plan_import |
payment_plan_import |
Freeze the rows, resolve each row’s customer, check start dates, and propose the dataset to the merchant. Returns the action, dataset_hash, row_count, projection, and decide_by |
get_payment_plan_import |
payment_plan_import |
Poll the combined state — the same state-shaped body as get_customer_import |
cancel_payment_plan_import |
payment_plan_import |
Withdraw an import that is staging or requires_approval |
Plan import inputs
Section titled “Plan import inputs”begin_payment_plan_import takes the same fields as begin_customer_import
with the same types and meanings; field_mapping keys are the plan row
fields below plus source_row_key. append_payment_plan_import_rows takes
payment_plan_import (pim_…), chunk_key, and rows. The other three
tools take only payment_plan_import.
Plan row fields
Section titled “Plan row fields”Unknown fields are rejected at append_payment_plan_import_rows, so this
list is the whole surface.
| Field | Required | Type |
|---|---|---|
source_row_key |
yes | string, 1–120 — your stable id for the row, used in every error and failure report |
customer_id |
one of two | cus_… — an existing customer on the account |
customer_reference |
one of two | string, 1–60 — the merchant’s own customer id, matched exactly as a candidate key (trimmed, case-insensitive). A customer with a blank reference can only be named by customer_id |
name |
yes | string, 1–50 |
category |
no | string, 1–50 |
frequency_type |
yes | W (weeks) or M (months) |
frequency_period |
yes | integer — 1–52 for W, 1–12 for M (fortnightly W×2, quarterly M×3, annual M×12). A longer cadence cannot be expressed and is rejected here, not approximated |
start_date |
yes | ISO 8601 date — the recurring anchor: the first recurring collection and the date later ones are counted from; the next collection when there is no first_date (for a migrated schedule, its next due date). Today or later at finalisation, and not before first_date |
first_date |
no | ISO 8601 date — a one-off first collection on or before start_date; when present it, not start_date, is the first collection. Requires first_amount_cents; today or later at finalisation |
first_amount_cents |
with first_date |
integer, 200–100,000 |
recurring_amount_cents |
yes | integer, 200–100,000 |
total_amount_cents |
one of three | integer, 200–99,999,999 ($999,999.99) — end when this total has been collected |
number_of_payments |
one of three | integer, ≥1 — end after this many recurring payments. A first payment (first_date + first_amount_cents) is in addition, so the total is number_of_payments × recurring_amount_cents + first_amount_cents. A total over $999,999.99 makes the row invalid at finalisation |
until_further_notice |
one of three | the literal true — no end condition |
failure_behaviour |
no | NEW_AT_END (default), TRY_AGAIN, DOUBLE_UP, or DO_NOTHING — see failure behaviours |
Two rules are enforced on every row at append: exactly one of
customer_id / customer_reference, and exactly one of
total_amount_cents / number_of_payments / until_further_notice. The
platform never infers an end condition and never guesses which customer a
row means.
Excluded by construction: payment_instrument_id, anything mandate- or
consent-shaped, state, payment_plan_template_id, and source cannot be
imported. An import asserts no instrument and no consent on anyone’s
behalf, which is why every plan it creates is a draft.
What the projection adds
Section titled “What the projection adds”finalize_payment_plan_import returns the customer import’s projection —
creates, invalid, fields_set, up to 20 errors_sample entries — plus
four plan-specific fields:
| Field | Meaning |
|---|---|
creates_as |
Always "draft". A constant, so the manifest itself records that no plan bills on approval |
unresolved_customers |
Rows whose customer was not found by customer_id or customer_reference — a subset of invalid |
lapsed_start_dates |
Rows whose start_date passed before finalisation — a subset of invalid. The agent re-dates in a new import; the platform never re-dates |
customers_referenced |
Distinct customers the valid rows attach plans to |
Customer resolution and the start-date check happen at finalisation, not at append: a row can pass shape validation and still be invalid here. Invalid rows stay in the frozen dataset, are shown to the merchant, and are skipped at execution.
State machine, idempotency, limits, and errors
Section titled “State machine, idempotency, limits, and errors”Identical to the customer import’s: the same twelve
statuses and state-shaped poll body, the same
idempotency rules on import_key and chunk_key, the same
limits (1–10,000 rows, 500 per chunk, 72-hour default
decide_by capped at 7 days, 7-day staging TTL, 30-day row retention), and
the same twelve error codes. No plan-specific code exists,
because everything that can go wrong with a plan row is a row problem —
reported in the projection and per row in outcome, not as a call error.
The one difference is rollback eligibility. The merchant’s rollback closes
and archives an import-created plan only while it is still draft, has
generated no payment intents, and has not been edited since creation; a
plan that has been activated, billed, or edited is skipped and reported.
And a customer that now owns an import-created plan has a subsequent
record, so a later customer rollback skips that customer too.
Not on this surface
Section titled “Not on this surface”There is no tool that accepts card numbers or CVV — card capture goes through the widget or hosted payment page only, exactly as in the REST API. And there are no live-mode write tools anywhere: the sandbox server writes sandbox data only, and the live server is read-only by construction. There is no tool that approves, stops, or rolls back a customer or payment-plan import — those are merchant controls in the dashboard, deliberately absent from the agent API.