SophtronSOPHTRON Docs
Home › API Documentation › What's new

What's new: Access & Action API

The same Customers → Members → Accounts interface you already use for data access, extended with Actions that take a free-form instruction, and a human-in-the-loop approval step that prompts the account holder to allow or deny before anything irreversible happens.

Sophtron-Api V2 endpointsOAS 3.0+ 8 new endpointsReleased October 2026Backward compatible
01 · SAME INTERFACE

Built on the v2 you know

Actions hang off /Customers/{customerID}/Members/{memberID} and reuse the AccountIDs returned by …/accounts. Existing endpoints are unchanged.

02 · FREE-FORM ACTION

Describe the task, not the clicks

One Instruction string in plain language, plus optional structured guardrails like MaxAmount. The engine plans the steps and classifies each as reversible or not.

03 · HUMAN-IN-THE-LOOP

Allow / deny before it's irreversible

Irreversible steps pause in awaiting_approval. The account holder is prompted via widget, SMS, email or push and must explicitly allow. Expired = denied. Agents cannot self-approve.

Action lifecycle

Every action moves through these states. Dashed box: a human decision is required before the irreversible step can run.

queued planning running awaiting_approvaluser prompted: allow / deny approved running completed denied expired failed → from any running state
# Quick start — link, then act with a free-form instruction (approval handled for you) POST /api/v2/Customers/cus_01HQ…/Members/mbr_5c10/actions { "AccountID": "acct_8f2a", "Instruction": "Pay the current electricity bill in full before the due date using my checking ••4821", "Parameters": { "MaxAmount": 250.00 }, "Mode": "execute", "RequireApproval": "auto" } # → 202 Status: "awaiting_approval" Approval.PromptURL: https://widget.sophtron.com/approve/apr_01J9… # user taps Allow → webhook approval.decided → action runs → action.completed (ConfirmationNumber DE-8827731)

Sophtron-Api V2 endpoints OAS 3.0

Servers 🔒 Authorize

Authentication is unchanged: send the same Authorization header you use for existing v2 endpoints. Action endpoints additionally require the action scope on your API key.

Customers

existing▾
GET/api/v2/Customers/{customerID}Get a customerunchanged from v2▾
Returns the customer record and its linked members.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
Responses
CodeDescription
200Customer record
Example Value
{
  "CustomerID": "cus_01HQ\u2026",
  "Name": "Acme Agent Co.",
  "Members": 3,
  "CreatedAt": "2025-11-04T09:12:00Z"
}
404Customer not found

Members

existing · link an institution with consent▾
POST/api/v2/Customers/{customerID}/MembersCreate a member (link an institution)▾
Links an institution to the customer on behalf of the end user. Use a ConsentToken from the Sophtron widget, or supply credentials directly for server-side flows. A member created this way carries both access and action capabilities when the institution supports actions.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
Request bodyapplication/json
Example Value | Schema
{
  "InstitutionID": "inst_duke_energy",
  "ConsentToken": "cst_2f9a\u2026",
  "UserName": "optional-if-using-widget",
  "Password": "optional-if-using-widget"
}
Responses
CodeDescription
201Member created
Example Value
{
  "MemberID": "mbr_5c10",
  "CustomerID": "cus_01HQ\u2026",
  "InstitutionID": "inst_duke_energy",
  "InstitutionName": "Duke Energy",
  "Status": "Linked",
  "MFARequired": false,
  "Capabilities": [
    "access",
    "action"
  ],
  "CreatedAt": "2026-10-02T14:01:08Z"
}
202MFA required — poll the member until Status is Linked
Example Value
{
  "MemberID": "mbr_5c10",
  "Status": "MFAPending",
  "MFAPrompt": "Enter the 6-digit code sent to \u2022\u2022\u2022\u20221234"
}
400Invalid request
GET/api/v2/Customers/{customerID}/Members/{memberID}Get member statusunchanged from v2▾
Returns login status, MFA state, and the capabilities (access, action) available for this member.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
Responses
CodeDescription
200Member record
Example Value
{
  "MemberID": "mbr_5c10",
  "CustomerID": "cus_01HQ\u2026",
  "InstitutionID": "inst_duke_energy",
  "InstitutionName": "Duke Energy",
  "Status": "Linked",
  "MFARequired": false,
  "Capabilities": [
    "access",
    "action"
  ],
  "CreatedAt": "2026-10-02T14:01:08Z"
}
404Member not found

Accounts

Access · read data (unchanged)▾
GET/api/v2/Customers/{customerID}/Members/{memberID}/accountsList accounts for a memberunchanged from v2▾
Returns all accounts discovered under the member. This endpoint is unchanged; the Action endpoints below reuse the same AccountID values.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
Responses
CodeDescription
200Array of accounts
Example Value
[
  {
    "AccountID": "acct_8f2a",
    "MemberID": "mbr_5c10",
    "AccountName": "Electric Service \u2022\u20227731",
    "AccountType": "Utility",
    "Balance": 142.18,
    "Currency": "USD",
    "DueDate": "2026-10-15",
    "Status": "Active",
    "LastUpdated": "2026-10-02T14:03:21Z"
  },
  {
    "AccountID": "acct_9b11",
    "MemberID": "mbr_5c10",
    "AccountName": "Gas Service \u2022\u20222209",
    "AccountType": "Utility",
    "Balance": 38.4,
    "Currency": "USD",
    "DueDate": "2026-10-20",
    "Status": "Active",
    "LastUpdated": "2026-10-02T14:03:21Z"
  }
]
401Unauthorized
404Member not found
GET/api/v2/Customers/{customerID}/Members/{memberID}/accounts/{accountID}/transactionsList transactionsunchanged from v2▾
Returns normalized transactions for the account.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
accountID*
string
(path)
Account identifier.
startDate
date
(query)
ISO date (inclusive).
endDate
date
(query)
ISO date (inclusive).
Responses
CodeDescription
200Array of transactions
Example Value
[
  {
    "TransactionID": "txn_4a\u2026",
    "Date": "2026-09-15",
    "Description": "Payment - Thank You",
    "Amount": -139.9,
    "Currency": "USD"
  }
]

Actions

Action · free-form instructionNEW▾
POST/api/v2/Customers/{customerID}/Members/{memberID}/actionsCreate an action (free-form instruction)NEW▾
Creates an action on the member's account. The Instruction field is free-form natural language: describe what you want done, the way you would brief a human assistant. Sophtron's engine turns the instruction into a concrete plan, classifies each step as reversible or irreversible, and either executes it or pauses for a human decision.
  • Mode — plan returns the plan without executing anything; execute runs it.
  • Parameters — optional structured guardrails (MaxAmount, Currency, NotAfter, …) the engine must respect.
  • RequireApproval — auto (default) pauses only when a step is irreversible; always pauses on every action; never is rejected if the plan contains an irreversible step.
  • IdempotencyKey — retries with the same key never create a second action.
Irreversible-action policy. Any step that moves money, cancels or closes something, submits an application, or changes PII is classified Reversible: false. When a plan contains such a step the action stops in awaiting_approval and an approval request is created automatically. It only proceeds after an explicit allow from the account holder; a deny or expiry ends the action. This cannot be bypassed with RequireApproval: never.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
Request bodyapplication/json
Example Value | Schema
{
  "AccountID": "acct_8f2a",
  "Instruction": "Pay the current electricity bill in full before the due date, using my saved checking account ending in 4821.",
  "Parameters": {
    "MaxAmount": 250.0,
    "Currency": "USD",
    "NotAfter": "2026-10-15"
  },
  "Mode": "execute",
  "RequireApproval": "auto",
  "ApprovalChannel": "widget",
  "IdempotencyKey": "7d3e9c2a-4b1f-4d6e-9a0c-1f2e3d4c5b6a",
  "CallbackURL": "https://yourapp.com/hooks/sophtron"
}
Responses
CodeDescription
202Action accepted. If an irreversible step was planned, Status is awaiting_approval and an Approval object is included.
Example Value
{
  "ActionID": "act_01J9X7KQ2M",
  "MemberID": "mbr_5c10",
  "AccountID": "acct_8f2a",
  "Status": "awaiting_approval",
  "Plan": {
    "Summary": "Pay $142.18 to Duke Energy from Checking \u2022\u20224821 on or before 2026-10-15",
    "Steps": [
      {
        "Step": 1,
        "Description": "Sign in to Duke Energy",
        "Reversible": true
      },
      {
        "Step": 2,
        "Description": "Open current bill ($142.18, due 2026-10-15)",
        "Reversible": true
      },
      {
        "Step": 3,
        "Description": "Submit one-time payment of $142.18 from Checking \u2022\u20224821",
        "Reversible": false
      }
    ],
    "Irreversible": true,
    "RiskLevel": "medium",
    "EstimatedEffects": [
      {
        "Type": "payment",
        "Amount": 142.18,
        "Currency": "USD",
        "Payee": "Duke Energy"
      }
    ]
  },
  "Approval": {
    "ApprovalID": "apr_01J9X7KR8Z",
    "Status": "pending",
    "Channel": "widget",
    "PromptURL": "https://widget.sophtron.com/approve/apr_01J9X7KR8Z",
    "ExpiresAt": "2026-10-02T14:20:00Z"
  },
  "CreatedAt": "2026-10-02T14:10:00Z"
}
200Mode=plan: plan returned, nothing executed
Example Value
{
  "ActionID": "act_01J9X7KQ2M",
  "Status": "planned",
  "Plan": {
    "Summary": "Pay $142.18 to Duke Energy from Checking \u2022\u20224821 on or before 2026-10-15",
    "Steps": [
      {
        "Step": 1,
        "Description": "Sign in to Duke Energy",
        "Reversible": true
      },
      {
        "Step": 2,
        "Description": "Open current bill ($142.18, due 2026-10-15)",
        "Reversible": true
      },
      {
        "Step": 3,
        "Description": "Submit one-time payment of $142.18 from Checking \u2022\u20224821",
        "Reversible": false
      }
    ],
    "Irreversible": true,
    "RiskLevel": "medium",
    "EstimatedEffects": [
      {
        "Type": "payment",
        "Amount": 142.18,
        "Currency": "USD",
        "Payee": "Duke Energy"
      }
    ]
  },
  "Note": "Mode=plan: nothing was executed. Re-submit with Mode=execute to run."
}
409Idempotency conflict: an action with this key already exists
422Instruction could not be planned safely (e.g. exceeds MaxAmount, unsupported action for this institution)
Example Value
{
  "Error": "PlanRejected",
  "Reason": "Bill total $342.18 exceeds Parameters.MaxAmount 250.00"
}
GET/api/v2/Customers/{customerID}/Members/{memberID}/actions/{actionID}Get action status & resultNEW▾
Poll the action, or rely on webhooks. Terminal states: completed, failed, denied, cancelled, expired.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
actionID*
string
(path)
Action identifier returned when the action was created.
Responses
CodeDescription
200Action with plan, approval and timeline
Example Value
{
  "ActionID": "act_01J9X7KQ2M",
  "Status": "completed",
  "Result": {
    "ConfirmationNumber": "DE-8827731",
    "AmountPaid": 142.18,
    "Currency": "USD",
    "PaidAt": "2026-10-02T14:21:36Z",
    "Receipt": "https://api.sophtron.com/v2/files/rcpt_01J9\u2026"
  },
  "Approval": {
    "ApprovalID": "apr_01J9X7KR8Z",
    "Status": "approved",
    "DecidedAt": "2026-10-02T14:19:12Z",
    "DecidedBy": "user"
  },
  "Timeline": [
    {
      "At": "14:10:00Z",
      "Status": "queued"
    },
    {
      "At": "14:10:03Z",
      "Status": "planning"
    },
    {
      "At": "14:10:09Z",
      "Status": "awaiting_approval"
    },
    {
      "At": "14:19:12Z",
      "Status": "approved"
    },
    {
      "At": "14:19:13Z",
      "Status": "running"
    },
    {
      "At": "14:21:36Z",
      "Status": "completed"
    }
  ]
}
404Action not found
GET/api/v2/Customers/{customerID}/Members/{memberID}/actionsList actionsNEW▾
Lists actions for the member, newest first.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
status
string
(query)
Filter by status, e.g. awaiting_approval.
limit
integer
(query)
Default 25, max 100.
Responses
CodeDescription
200Array of actions
Example Value
[
  {
    "ActionID": "act_01J9X7KQ2M",
    "Status": "completed",
    "Summary": "Pay $142.18 to Duke Energy",
    "CreatedAt": "2026-10-02T14:10:00Z"
  }
]
POST/api/v2/Customers/{customerID}/Members/{memberID}/actions/{actionID}/cancelCancel an actionNEW▾
Cancels an action that is queued, planning or awaiting_approval. Running actions past an irreversible step cannot be cancelled.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
actionID*
string
(path)
Action identifier returned when the action was created.
Responses
CodeDescription
200Action cancelled
Example Value
{
  "ActionID": "act_01J9X7KQ2M",
  "Status": "cancelled",
  "CancelledAt": "2026-10-02T14:12:40Z"
}
409Action can no longer be cancelled

Approvals

Human-in-the-loop · prompt the user to allow or denyNEW▾
POST/api/v2/Customers/{customerID}/Members/{memberID}/actions/{actionID}/approvalRequest user approval (human-in-the-loop)NEW▾
Prompts the account holder to allow or deny an action before it proceeds. Sophtron creates one automatically when a plan is irreversible; call this endpoint to re-send a prompt, change the channel, or require approval for a reversible action. The user responds through the Sophtron widget, a hosted PromptURL, SMS, email or push. An approval that expires is treated as denied.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
actionID*
string
(path)
Action identifier returned when the action was created.
Request bodyapplication/json
Example Value | Schema
{
  "Channel": "sms",
  "Message": "Sophtron is about to pay $142.18 to Duke Energy from Checking \u2022\u20224821. Reply ALLOW or DENY.",
  "ExpiresIn": 600,
  "Locale": "en-US"
}
Responses
CodeDescription
201Approval request created and prompt delivered
Example Value
{
  "ApprovalID": "apr_01J9X7KR8Z",
  "ActionID": "act_01J9X7KQ2M",
  "Status": "pending",
  "Channel": "sms",
  "PromptURL": "https://widget.sophtron.com/approve/apr_01J9X7KR8Z",
  "ExpiresAt": "2026-10-02T14:20:00Z"
}
409An approval is already pending for this action
GET/api/v2/Customers/{customerID}/Members/{memberID}/approvals/{approvalID}Get approval statusNEW▾
Returns the current state of the approval request: pending, approved, denied or expired.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
approvalID*
string
(path)
Approval request identifier.
Responses
CodeDescription
200Approval record
Example Value
{
  "ApprovalID": "apr_01J9X7KR8Z",
  "ActionID": "act_01J9X7KQ2M",
  "Status": "approved",
  "Decision": "allow",
  "DecidedBy": "user",
  "DecidedAt": "2026-10-02T14:19:12Z",
  "Channel": "sms"
}
404Approval not found
POST/api/v2/Customers/{customerID}/Members/{memberID}/approvals/{approvalID}/decisionSubmit the user's decision (allow / deny)NEW▾
Record the account holder's decision when your own app rendered the prompt. Decisions made through the Sophtron widget, hosted link, SMS or push are recorded automatically and do not need this call. A ProofToken (widget session or one-time code) is required so a decision cannot be submitted on the user's behalf by the agent itself.
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
memberID*
string
(path)
Member (institution connection) identifier.
approvalID*
string
(path)
Approval request identifier.
Request bodyapplication/json
Example Value | Schema
{
  "Decision": "allow",
  "DecidedBy": "user",
  "ProofToken": "otp_6-digit-or-widget-session",
  "Reason": "Confirmed by account holder"
}
Responses
CodeDescription
200Decision recorded; on allow the action resumes
Example Value
{
  "ApprovalID": "apr_01J9X7KR8Z",
  "Status": "approved",
  "ActionID": "act_01J9X7KQ2M",
  "ActionStatus": "running"
}
401Invalid or missing ProofToken
410Approval expired

Webhooks

events for actions & approvalsNEW▾
POST/api/v2/Customers/{customerID}/webhooksRegister a webhook endpointNEW▾
Receive action and approval events instead of polling. Payloads are signed with HMAC-SHA256 using Secret (header X-Sophtron-Signature).
Example event
{
  "Event": "action.awaiting_approval",
  "At": "2026-10-02T14:10:09Z",
  "Data": {
    "ActionID": "act_01J9X7KQ2M",
    "ApprovalID": "apr_01J9X7KR8Z",
    "PromptURL": "https://widget.sophtron.com/approve/apr_01J9X7KR8Z",
    "Summary": "Pay $142.18 to Duke Energy from Checking \u2022\u20224821",
    "Irreversible": true
  }
}
Parameters
NameDescription
customerID*
string
(path)
Your Sophtron customer identifier.
Request bodyapplication/json
Example Value | Schema
{
  "URL": "https://yourapp.com/hooks/sophtron",
  "Events": [
    "action.planned",
    "action.awaiting_approval",
    "approval.decided",
    "action.completed",
    "action.failed"
  ],
  "Secret": "whsec_\u2026"
}
Responses
CodeDescription
201Webhook registered
Example Value
{
  "WebhookID": "wh_01J9\u2026",
  "URL": "https://yourapp.com/hooks/sophtron",
  "Events": 5
}

Schemas

▾
Account▾
AccountIDstring
MemberIDstring
AccountNamestring
AccountTypestringChecking, Savings, CreditCard, Loan, Utility, Telecom, Insurance, Payroll, Brokerage…
Balancenumber
CurrencystringISO 4217
DueDatedateBilling accounts only
StatusstringActive | Closed | Pending
ActionRequestNEW▾
AccountIDstringoptional — scope the instruction to one account
Instructionstringrequired — free-form natural language
Parametersobjectoptional guardrails: MaxAmount, Currency, NotAfter, Payee, …
Modeenumplan | execute (default execute)
RequireApprovalenumauto | always | never (never is rejected for irreversible plans)
ApprovalChannelenumwidget | sms | email | push
IdempotencyKeystringrecommended
CallbackURLstringoptional per-action webhook
ActionNEW▾
ActionIDstring
Statusenumqueued | planning | planned | awaiting_approval | approved | running | completed | failed | denied | cancelled | expired
PlanActionPlan
ApprovalApprovalpresent when approval was required
Resultobjectinstitution-specific result, e.g. ConfirmationNumber, Receipt
Timelinearraystatus transitions with timestamps
CreatedAtdatetime
ActionPlanNEW▾
Summarystringone-line human-readable description
Steps[]arrayStep, Description, Reversible (bool)
Irreversiblebooleantrue if any step is irreversible
RiskLevelenumlow | medium | high
EstimatedEffects[]arrayType (payment, transfer, update, cancel, submit), Amount, Currency, Payee…
ApprovalNEW▾
ApprovalIDstring
ActionIDstring
Statusenumpending | approved | denied | expired
Channelenumwidget | sms | email | push
PromptURLstringhosted allow/deny page
Decisionenumallow | deny
DecidedBystringuser
ExpiresAtdatetime
DecisionNEW▾
Decisionenumallow | deny
DecidedBystringmust be user
ProofTokenstringwidget session or one-time code; prevents agent self-approval
Reasonstringoptional