Skip to main content
CRM writes are dangerous when state drifts between the time the agent resolves a customer record and when the write executes. Invoke verifies identity before the write lands.

The problem

Your agent resolves cust_123 at plan time. Between plan and execution, the record changes — the account is reassigned, merged, or the customer ID updates. Without state verification, the write hits the wrong entity.

Solution: state verification before write

Use POST /state/verify to confirm the customer record matches assumed state before executing the CRM update:
const result = await invoke.call({
  tool: "crm.update_customer",
  params: { customer_id: "cust_123", status: "qualified" },
  agentId: "sales-agent",
  idempotencyKey: "crm:update:cust_123:qualified"
})

if (result.status === "replan_required") {
  // customer state has drifted
  // agent should re-resolve the customer before proceeding
}

What Invoke checks

Before the CRM write executes, Invoke compares:
  • Customer ID — is the resolved entity still the same record?
  • Account status — has the status changed since the agent planned the action?
  • Required fields — are all fields the agent depended on still current?
If any condition fails, Invoke returns replan_required and the write never lands.

Direct API call

curl -X POST https://api.invokehq.run/state/verify \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "intent": "crm_update_customer",
    "required_fields": ["customer_id", "account_status"],
    "assumed_state": { "customer_id": "cust_123", "account_status": "qualified" },
    "current_state": { "customer_id": "cust_999", "account_status": "qualified" },
    "conditions": { "customer_id": "cust_123" },
    "on_mismatch": "replan"
  }'
Here customer_id drifted from cust_123 to cust_999 — Invoke blocks the write.

Next steps