{"id":"ERC-8001","name":"Agent Coordination Framework","status":"Final","chain":"both","category":{"id":"ai","name":"AI & Agents","description":"AI-generated content and agent coordination"},"journeyStages":[{"id":"specialized","name":"Specialized Interactions","description":"Physical items, AI, social, gaming"}],"uxImpact":"ERC-8001 defines a coordination lifecycle in which an initiator proposes an intent, participants accept, and a ready coordination may be executed or cancelled. Execution data is opaque to the coordination interface and returns success/result; the standard does not guarantee atomic effects. Expiry becomes a status, but cancellation still requires an explicit cancelCoordination transaction.","officialUrl":"https://ercs.ethereum.org/ERCS/erc-8001","lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","kind":"proposal","hasDetailedContent":true,"content":{"id":"ERC-8001","specConstraints":[{"id":"coordination-lifecycle","constraint":"Read lifecycle status from the coordinator; expiry and cancellation are different outcomes.","appliesTo":"application","normativity":"normative","specQuote":"getCoordinationStatus(intentHash) MUST return: - None if the intent does not exist; - Proposed if not all participants have accepted and the intent has not expired; - Ready if all participants have accepted and expiries have not elapsed; - Executed if execution has occurred; - Cancelled if cancellation has occurred; - Expired if the intent has expired and was not executed or cancelled.","specSection":"Specification / Semantics / getCoordinationStatus","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#getcoordinationstatus","designImplication":"Use the returned status, participants, acceptedBy and expiry to render progress. Signing locally does not establish acceptance; reaching expiry does not prove a cancellation transaction occurred."},{"id":"all-participant-consent","constraint":"The core protocol requires acceptance from every participant.","appliesTo":"application","normativity":"normative","specQuote":"getRequiredAcceptances(intentHash) MUST equal the number of participants.","specSection":"Specification / Semantics / proposeCoordination","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#proposecoordination","designImplication":"Show the full participant set and required count, including the initiator. Do not present a majority threshold as the core rule or enable execution while required acceptance is missing."},{"id":"fresh-execution-consent","constraint":"Execution requires a ready intent, fresh acceptances, and the matching payload.","appliesTo":"application","normativity":"normative","specQuote":"executeCoordination MUST revert if: - the intent is not in Ready state; - intent.expiry <= block.timestamp; - any acceptance has expired; - the supplied payload does not hash to payloadHash.","specSection":"Specification / Semantics / executeCoordination","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#executecoordination","designImplication":"Track intent and acceptance expiry separately. Re-check readiness before execution, explain expired acceptance or changed payload, and request a supported new proposal or acceptance rather than silently reusing consent."},{"id":"execution-result","constraint":"The execution call returns an explicit success flag and result.","appliesTo":"application","normativity":"normative","specQuote":"the function MUST return (success, result);","specSection":"Specification / Semantics / executeCoordination","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#executecoordination","designImplication":"Distinguish the attempt, coordinator status, and returned outcome. Do not equate Ready or an emitted execution event with every intended effect succeeding, and do not promise atomic behavior without the implementation's policy."},{"id":"cancellation-authority","constraint":"Only the proposer can cancel an unexpired intent; after expiry any caller can cancel.","appliesTo":"application","normativity":"normative","specQuote":"If the intent has not expired, only the proposer MUST be permitted to cancel. - After expiry, any caller MUST be permitted to cancel.","specSection":"Specification / Semantics / cancelCoordination","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#cancelcoordination","designImplication":"Gate the cancel action by the current actor and expiry. Keep an explicit cancellation transaction separate from a local dismiss or an elapsed timer."},{"id":"coordination-security-scope","constraint":"Acceptance does not guarantee exclusive participation or confidential coordination data.","appliesTo":"application","normativity":"security-considerations","specQuote":"Equivocation: A participant can sign conflicting intents. Mitigate with module-level slashing or reputation. - Liveness: Enforce TTL on both intent and acceptances. Executors should ensure enough time remains. - MEV: If coordinationData reveals strategy, use a Privacy module with commit-reveal or encryption.","specSection":"Security Considerations","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#security-considerations","designImplication":"Explain whether the selected integration adds privacy, reputation or slashing and what it actually enforces. Do not label the core protocol as confidential or assume another participant cannot accept a conflicting intent."},{"id":"domain-exposure-recommendation","constraint":"Implementations should expose the signing domain through ERC-5267.","appliesTo":"account-implementation","normativity":"normative","specQuote":"Implementations SHOULD expose the domain via [ERC-5267](./eip-5267.md).","specSection":"Specification / EIP-712 Domain","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#eip-712-domain","designImplication":"Retrieve and validate the signing domain when the interface is available. Treat ERC-5267 exposure as a recommendation, not universal deployment support; explain unavailable signing context rather than silently inferring the domain."},{"id":"coordination-value-not-custody","constraint":"coordinationValue is informational in the core protocol; a module may bind it to value.","appliesTo":"application","normativity":"normative","specQuote":"uint256 coordinationValue;     // informational in Core; modules MAY bind value","specSection":"Specification / Primary Types","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#primary-types","designImplication":"Do not label coordinationValue as escrowed funds, a settled transfer, or a guaranteed reward. Only show those outcomes when the selected module actually enforces and reports them."},{"id":"descriptive-coordination-errors","constraint":"Implementations should expose descriptive errors and may add module-specific errors.","appliesTo":"application","normativity":"normative","specQuote":"Implementations SHOULD revert with descriptive custom errors (or equivalent revert strings) for the following baseline conditions, and MAY define additional errors for domain-specific modules (e.g. slashing, reputation, or privacy conditions):\n- Expired intent\n- Bad signature\n- Non-participant\n- Duplicate acceptance\n- Acceptance expired at execute\n- Payload hash mismatch","specSection":"Specification / Errors","specUrl":"https://ercs.ethereum.org/ERCS/erc-8001#errors","designImplication":"Translate the reported condition into a recovery action, such as renewing expired consent or reviewing a changed payload. Preserve a fallback for unknown module errors instead of promising one fixed error set."}],"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-8001","type":"official-spec"}],"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18","summary":"ERC-8001 defines a coordination lifecycle in which an initiator proposes an intent, participants accept, and a ready coordination may be executed or cancelled. Execution data is opaque to the coordination interface and returns success/result; the standard does not guarantee atomic effects. Expiry becomes a status, but cancellation still requires an explicit cancelCoordination transaction.","designerTakeaways":["Show intent, participants, acceptance expiry, and observed contract status separately.","Treat executeCoordination success/result as the outcome; do not label Ready as executed.","Explain that atomicity and execution semantics come from the implementation/module.","Offer an explicit executor and cancel path, including cancellation after expiry where permitted."],"applicability":{"whenToUse":["A coordinator needs explicit participant acceptance before a proposed intent can be executed.","The UI can show opaque execution, returned success/result, observed statuses, and an explicit cancel path.","The implementation documents execution and atomicity semantics instead of relying on the coordination interface alone."],"whenToAvoid":["Single-signer transactions.","No working coordinator implements the required lifecycle.","Users cannot understand multi-party consent."]},"prototypeFirst":[{"screen":"Coordination proposal detail","why":"Participants review what group will do.","covers":["Proposed","Partial accept","Ready"],"include":["Human intent summary","Participant list","Expiry timer","Accept button"]},{"screen":"Initiator create coordination","why":"Proposer sets participants and intent.","covers":["Create","Submit proposal"],"include":["Intent description","Participant picker","Expiry setting"]},{"screen":"Participant acceptance sign","why":"Each party confirms individually.","covers":["Pending your sign","You accepted"],"include":["Summary mirror","Accept/Decline","Your checkmark on list"]},{"screen":"Executed or expired outcome","why":"Terminal states need closure.","covers":["Executed success","Expired cancel"],"include":["Outcome banner","Explorer link","Retry or new proposal"]}],"mentalModel":[{"label":"Intent","description":"Plain-language description of group outcome."},{"label":"Participants","description":"Addresses that must accept."},{"label":"Acceptance","description":"Each signature adds checkmark — not execution yet."},{"label":"Ready","description":"All accepted — execution can proceed."},{"label":"Expiry","description":"Expiry makes the coordination ineligible and produces Expired status; it does not automatically execute cancelCoordination."}],"statesToDesign":[{"state":"Proposed — awaiting accepts","trigger":"Some participants pending.","userNeed":"See who missing.","designResponse":"Checklist with pending avatars."},{"state":"Your acceptance required","trigger":"Connected user is pending participant.","userNeed":"Review and agree.","designResponse":"Prominent Accept this group action CTA."},{"state":"Ready to execute","trigger":"All accepted.","userNeed":"Know execution imminent.","designResponse":"Ready banner only after all required acceptances and expiry checks; provide an explicit executor action and disclose that execution behavior is implementation-specific."},{"state":"Executed","trigger":"On-chain success.","userNeed":"Confirmation.","designResponse":"Completed only when executeCoordination returns success; show the returned result and any partial/failed implementation outcome."},{"state":"Expired","trigger":"Timer elapsed.","userNeed":"Not think stuck.","designResponse":"Expired status with an explicit cancelCoordination path; expiry does not itself submit a cancellation transaction."}],"designDecisions":[{"question":"How technical is intent summary?","recommendation":"Human outcome first; calldata in advanced.","rationale":"Agents still need human-readable consent."},{"question":"Visualize partial acceptance?","recommendation":"Progress bar N of M accepted.","rationale":"Limbo needs progress not static pending."},{"question":"Initiator cancel before expiry?","recommendation":"Allow cancel with notify participants.","rationale":"Plans change — need escape hatch."}],"problemsSolved":[{"problem":"Multi-party txs require manual sequencing","oldWay":"Sign one by one hope others follow","newWay":"A coordination can collect participant acceptances before an executor submits opaque executionData; execution returns success and result rather than a universal atomic guarantee","impact":"high"},{"problem":"Unclear who blocked coordination","oldWay":"Stuck pending forever","newWay":"Participant checklist with pending labels","impact":"high"},{"problem":"Agent intents opaque to humans","oldWay":"Raw calldata only","newWay":"Human intent summary layer","impact":"medium"}],"uxPatterns":[{"name":"Coordination Checklist","description":"Participant acceptance progress toward Ready.","components":["ParticipantRow","AcceptCheckmark","ExpiryTimer"],"userFlow":["Proposal is Proposed","Participants review the human intent and expiry","Each acceptance updates acceptedBy","App shows Ready only after required acceptances and valid expiry","Executor submits executionData","Shows success/result separately from coordination status"]},{"name":"Group Action Accept Flow","description":"Present a plain-language acceptance request and show explicit decline, expiry, execution, and cancel states.","components":["IntentSummary","AcceptButton","DeclineOption"],"userFlow":["Review human intent and participant scope","Show typed acceptance data and expiry","Participant accepts or declines in the app","Wait for other acceptances","Show Ready, Executed, Cancelled, or Expired as observed status"]}],"antiPatterns":[{"pattern":"Treating expiry as automatic cancellation","why":"The contract status can become Expired, but cancellation is an explicit transaction.","instead":"Show Expired and offer cancelCoordination when the caller is allowed to cancel.","severity":"critical"},{"pattern":"Calling Ready an atomic execution guarantee","why":"The coordination interface passes opaque executionData to implementation logic and returns success/result.","instead":"Show acceptance readiness, execution submission, and returned success separately.","severity":"critical"},{"pattern":"Hiding the opaque execution boundary","why":"Participants cannot infer calldata effects or atomicity from the acceptance status.","instead":"Use a human intent summary, advanced execution disclosure, and explicit implementation policy.","severity":"high"}],"vocabulary":[{"use":"Group action","avoid":"Coordination intent hash","why":"Plain multi-party language."},{"use":"Waiting for [name]","avoid":"Participant pending signature","why":"Checklist copy."},{"use":"Everyone agreed","avoid":"Threshold reached","why":"Human ready state."}],"technicalNotes":"ERC-8001 defines AgentIntent, CoordinationPayload, AcceptanceAttestation, statuses None/Proposed/Ready/Executed/Cancelled/Expired, and proposeCoordination, acceptCoordination, executeCoordination, cancelCoordination, getCoordinationStatus, and getRequiredAcceptances. executeCoordination returns (bool success, bytes result) for opaque executionData; the standard does not guarantee atomic effects. Expiry affects status and eligibility; cancelCoordination remains an explicit call.","relatedStandards":[{"id":"ERC-4337","relationship":"Smart accounts may participate as agents"},{"id":"EIP-712","relationship":"Typed data for acceptance signatures"}]},"sources":[{"label":"Official specification","url":"https://ercs.ethereum.org/ERCS/erc-8001","type":"official-spec"},{"label":"Discussion search","url":"https://ethereum-magicians.org/search?q=ERC-8001","type":"discussion"}],"urls":{"canonical":"https://www.eipsfordesigners.com/standards/ERC-8001","markdown":"https://www.eipsfordesigners.com/standards/ERC-8001/content.md","agent":"https://www.eipsfordesigners.com/standards/ERC-8001/agent.md","api":"https://www.eipsfordesigners.com/api/standards/ERC-8001","official":"https://ercs.ethereum.org/ERCS/erc-8001","discussion":"https://ethereum-magicians.org/search?q=ERC-8001"},"freshness":{"lastReviewed":"2026-09-18","lastUpdated":"2026-09-18"}}