XIP-67: Inline Actions

XIP-67: Inline Actions

Abstract

This XIP introduces a standardized protocol for inline action buttons within XMTP conversations, enabling agents to present clear, actionable options to users through button interfaces. The protocol defines two primary content types: Actions for declaring available actions and Intent, which captures a user’s selection. This specification provides a foundation for both group-appropriate interactions (such as polls and shared decisions) and individual workflows that transition to direct messages to avoid cluttering group chats (such as multi-step configurations, payments, and personalized responses).

Motivation

Today, interacting with agents usually means either typing arcane slash‑commands or composing free‑form natural‑language prompts. Both approaches introduce ambiguity, increase cognitive load, and clutter conversation histories with verbose exchanges. Users struggle to discover available actions, understand how to invoke them, and parse agent responses buried in text.

Inline action buttons address these challenges by surfacing clear, discrete options that users can select with a single tap. This approach dramatically reduces friction in agent interactions while maintaining a clean, scannable conversation history. By providing structured, machine-readable messages for both action declaration and intent expression, the protocol enables clients to render appropriate UI elements while gracefully degrading for older implementations.

The deliberately minimal design allows the protocol to work effectively in both 1:1 and group contexts within XMTP’s current constraints, while remaining compatible with future enhancements to group messaging.

Specification

Core Concepts

The protocol standardizes how users initiate interactions with agents:

  1. Actions — An agent presents available options to users through button interfaces
  2. Intents — A user expresses their selection by tapping a button
  3. Handling — The agent processes the intent through appropriate workflows (simple text responses, multi-step DM conversations, transaction requests, etc.)

This minimal approach provides clear user intent to agents while allowing flexible response patterns through standard XMTP messaging.

Content Type: Actions

The Actions content type enables agents to present interactive button options to users. Each message contains a descriptive text field and an array of action definitions.

Schema

{
  // Unique identifier for these actions
  "id": "string",
  // Descriptive text explaining the actions
  "description": "string",
  // Array of action definitions
  "actions": [
    {
      // Unique identifier for this action
      "id": "string",
      // Display text for the button
      "label": "string",
      // Optional image URL to associate with this action
      "imageUrl": "string",
      // Optional visual style for this action: e.g. primary|secondary|danger
      "style": "string",
      // Optional ISO-8601 expiration timestamp for this action
      "expiresAt": "string"
    }
  ],
  // Optional ISO-8601 expiration timestamp for all actions
  "expiresAt": "string"
}

Requirements

  • Actions messages SHOULD only be sent by agents; end users SHOULD NOT emit them.
  • When the optional expiresAt timestamp is passed, clients SHOULD disable or hide the associated buttons.
  • Clients SHOULD validate all fields against the schema before rendering.

Content Type: Intent

Intent represents a user’s selection of an action. It contains only the essential information needed to identify which action was selected.

Schema

{
  // References id from the Actions message
  "id": "string",
  // References action.id from the Actions message
  "actionId": "string",
  // Optional context data
  "metadata": {}
}

Requirements

  • Clients SHOULD emit Intent immediately upon user selection and disable all related buttons
  • The action_id SHOULD match an action ID from the referenced Actions message
  • The metadata field is OPTIONAL and MAY contain action-specific data (e.g., custom amounts, user input)
  • Agents SHOULD handle intents idempotently - duplicate (id, actionId, sender) combinations should produce the same outcome
  • Clients SHOULD NOT emit multiple different Intent messages for the same Actions message

Group Chat Behavior

In group conversations, the protocol operates with full transparency:

  • All Actions messages are visible to all group members
  • All Intent messages are visible to all group members
  • Agents MUST assume public visibility when designing group actions
  • For individual workflows, agents MUST transition to direct messages

This transparent model works well for:

  • Polls and surveys
  • Game moves where everyone needs to see selections
  • Shared decisions
  • Simple queries with brief responses

Agents should transition to DMs for:

  • Individual workflows - Multi-step processes, configurations, or extended interactions
  • Privacy-sensitive actions - Payments, personal data, credentials
  • Personalized responses - Results that only matter to the requesting user
  • Complex interactions - Anything requiring back-and-forth that would clutter the group

The goal is maintaining clean, readable group transcripts where every message provides value to all participants.

Integration with XIP-59 WalletSendCalls

For actions requiring onchain transactions, agents respond to Intent messages with XIP-59 WalletSendCalls:

  1. User sends Intent expressing intent to execute onchain action
  2. Agent responds with a WalletSendCalls message containing transaction parameters
  3. Client presents native wallet interface for user confirmation
  4. Transaction executes through standard wallet flow
  5. Agent monitors blockchain for confirmation and sends text updates

This integration works identically in both 1:1 and group contexts, though privacy-sensitive transactions should be handled in direct messages.

Representative Flows

Simple Group Poll

A straightforward public voting scenario in a group chat:

  1. Agent → Group: “Should we meet at 3pm or 4pm?”
  2. Agent → Group: Sends Actions with buttons: “3pm :three_o_clock:”, “4pm :four_o_clock:
  3. Alice → Group: Sends Intent selecting “3pm” (references message #2)
  4. Bob → Group: Sends Intent selecting “3pm” (references message #2)
  5. Carol → Group: Sends Intent selecting “4pm” (references message #2)
  6. Agent → Group: “Current votes: 3pm (2), 4pm (1)”

Payment with Privacy Transition

A payment flow that starts in a group but handles sensitive data privately:

In Group Chat:

  1. User: “I want to pay for premium”
  2. Agent → Group: “Premium is $10/month. Ready to upgrade?”
  3. Agent → Group: Sends Actions with button: “Subscribe :credit_card:
  4. User → Group: Sends Intent selecting “Subscribe”
  5. Agent → Group: “Thanks! Check your DMs to complete payment”

In Direct Message:

  1. Agent → User: “Let’s set up your premium subscription”
  2. Agent → User: Sends WalletSendCalls for $10 USDC payment
  3. User: Confirms transaction in wallet
  4. Agent → User: “Payment confirmed! Your premium access is active”

Back in Group Chat:

  1. Agent → Group: “:white_check_mark: User is now a premium member!”

Multi-Stage Game with DM Coordination

A game where private actions in DM affect public group state:

In Group Chat:

  1. Agent → Group: “Starting a new game of Mafia! 5 players joined”
  2. Agent → Group: Sends Actions with button: “Get Your Role :performing_arts:
  3. Alice → Group: Sends Intent selecting “Get Your Role”
  4. Bob → Group: Sends Intent selecting “Get Your Role”
  5. Carol → Group: Sends Intent selecting “Get Your Role”

In Direct Messages (sent to each player):

  1. Agent → Alice: “You are the Mafia! Kill someone each night”
  2. Agent → Bob: “You are a Villager. Find the Mafia!”
  3. Agent → Carol: “You are the Detective. Investigate one player each night”

Night Phase in DMs:

  1. Agent → Alice: “Who do you want to eliminate?”
  2. Agent → Alice: Sends Actions with buttons for each player
  3. Alice → Agent: Sends Intent selecting “Bob”

Day Phase in Group:

  1. Agent → Group: “:sun: Morning! Bob was eliminated last night”
  2. Agent → Group: “Time to vote! Who is the Mafia?”
  3. Agent → Group: Sends Actions with remaining players as buttons

Configuration Flow with DM Transition

A personalization flow that transitions to DM to avoid cluttering the group:

In Group Chat:

  1. User: “I want to set up my preferences”
  2. Agent → Group: “I’ll help you configure your settings”
  3. Agent → Group: Sends Actions with button: “Configure Settings :gear:
  4. User → Group: Sends Intent selecting “Configure Settings”
  5. Agent → Group: “I’ll walk you through setup in DMs”

In Direct Message:

  1. Agent → User: “Let’s configure your preferences. First, choose your timezone:”
  2. Agent → User: Sends Actions with buttons: “PST”, “EST”, “CST”, “UTC”
  3. User → Agent: Sends Intent selecting “PST”
  4. Agent → User: “Great! Now select your notification preferences:”
  5. Agent → User: Sends Actions with buttons: “All”, “Important Only”, “None”
  6. User → Agent: Sends Intent selecting “Important Only”
  7. Agent → User: “All set! Your preferences have been saved”

Back in Group Chat:

  1. Agent → Group: “:white_check_mark: User’s preferences have been configured”

Sports Betting with Group Discussion and Private Wagers

A comprehensive flow showing how a betting agent facilitates public discussion while handling individual wagers privately:

Section 1-2.png

In Group Chat (Pre-Game Discussion):

  1. Agent → Group: “:basketball: Tonight’s Games: Lakers vs Warriors (8pm ET), Celtics vs Heat (7:30pm ET)”
  2. Agent → Group: Sends Actions with buttons: “Lakers/Warriors :bar_chart:”, “Celtics/Heat :bar_chart:”, “My Bets :ticket:
  3. Alice → Group: Sends Intent selecting “Lakers/Warriors”
  4. Agent → Group: “Lakers (-5.5) vs Warriors • O/U 220.5 • Lakers -250 ML”
  5. Bob → Group: “Lakers covering easily tonight”
  6. Agent → Group: “Want to place a bet on Lakers/Warriors?”
  7. Agent → Group: Sends Actions with buttons: “Bet on This Game :money_bag:”, “Just Watching :eyes:
  8. Alice → Group: Sends Intent selecting “Bet on This Game”
  9. Bob → Group: Sends Intent selecting “Bet on This Game”
  10. Agent → Group: “Alice, Bob - check your DMs to place your bets privately”

In Alice’s DM:

  1. Agent → Alice: “Let’s set up your Lakers/Warriors bet. Choose your bet type:”
  2. Agent → Alice: Sends Actions with buttons: “Lakers -5.5”, “Warriors +5.5”, “Over 220.5”, “Under 220.5”, “Lakers ML”
  3. Alice → Agent: Sends Intent selecting “Lakers -5.5”
  4. Agent → Alice: “How much would you like to wager?”
  5. Agent → Alice: Sends Actions with buttons: “$10”, “$25”, “$50”, “$100”, “Custom”
  6. Alice → Agent: Sends Intent selecting “$25”
  7. Agent → Alice: “Confirm: $25 on Lakers -5.5 (-110) • To win: $22.73”
  8. Agent → Alice: Sends WalletSendCalls for $25 USDC payment
  9. Alice → Agent: Completes transaction
  10. Agent → Alice: “:white_check_mark: Bet confirmed! Lakers -5.5 for $25 • Ticket #8934

In Bob’s DM (simultaneously):

  1. Agent → Bob: “Let’s set up your Lakers/Warriors bet. Choose your bet type:”
  2. Agent → Bob: Sends Actions with buttons: “Lakers -5.5”, “Warriors +5.5”, “Over 220.5”, “Under 220.5”, “Lakers ML”
  3. Bob → Agent: Sends Intent selecting “Over 220.5”
  4. Agent → Bob: “How much would you like to wager?”
  5. Agent → Bob: Sends Actions with buttons: “$10”, “$25”, “$50”, “$100”, “Custom”
  6. Bob → Agent: Sends Intent selecting “$50”
  7. Agent → Bob: “Confirm: $50 on Over 220.5 (-110) • To win: $45.45”
  8. Agent → Bob: Sends WalletSendCalls for $50 USDC payment
  9. Bob → Agent: Completes transaction
  10. Agent → Bob: “:white_check_mark: Bet confirmed! Over 220.5 for $50 • Ticket #8935

Back in Group Chat (Pre-Game):

  1. Agent → Group: “:ticket: Active bets placed for tonight’s Lakers/Warriors game!”
  2. Carol → Group: “What’s everyone betting on?”
  3. Agent → Group: “2 bets placed so far. Popular picks: Spread (1), Total (1)”
  4. Carol → Group: “I’ll take Warriors +5.5”
  5. Agent → Group: Sends Actions with button: “Place This Bet :money_bag:
  6. Carol → Group: Sends Intent selecting “Place This Bet”
  7. Agent → Group: “Carol - check your DMs to complete your Warriors +5.5 bet”

During the Game (Group Chat):

  1. Agent → Group: “:basketball: Q3 Update: Lakers 78, Warriors 71 • Total: 149”
  2. Alice → Group: “Lakers covering! :flexed_biceps:
  3. Bob → Group: “Need 72 points in Q4 for the over :grimacing:

Post-Game Settlement (Group Chat):

  1. Agent → Group: “:chequered_flag: Final: Lakers 115, Warriors 108 • Total: 223”
  2. Agent → Group: “Tonight’s results: Lakers covered -5.5 :white_check_mark: • Over 220.5 hit :white_check_mark:
  3. Agent → Group: “Congrats to tonight’s winners! :tada: Check your DMs for payouts”

In Alice’s DM:

  1. Agent → Alice: “Congrats! Your bet won: Lakers -5.5 :white_check_mark:
  2. Agent → Alice: “Payout: $47.73 USDC (bet: $25 + winnings: $22.73)”
  3. Agent → Alice: Sends WalletSendCalls to transfer winnings
  4. Agent → Alice: “Want to see tomorrow’s games?”

In Carol’s DM:

  1. Agent → Carol: “Your bet lost: Warriors +5.5 :cross_mark: (Lakers won by 7)”
  2. Agent → Carol: “Better luck next time! Want to see tomorrow’s games?”

This pattern demonstrates:

  • Public discussion and analysis in the group
  • Private handling of all financial transactions
  • Group-visible aggregate information without exposing individual bet amounts
  • Clear transitions between group and DM contexts
  • Post-game settlement maintaining privacy while celebrating publicly

User Experience Considerations

Current Limitations

The requirement to transition between group chats and DMs for individual workflows introduces UX friction:

  • Users must context-switch between conversations
  • Message flow is fragmented across multiple threads
  • Users may miss DM notifications while focused on group chat
  • Mobile clients must handle navigation between chat contexts

These transitions are necessary not only for privacy but also to prevent group chats from becoming cluttered with individual interactions that provide no value to other members. A group chat filled with one user’s multi-step configuration process or personalized results would degrade the experience for everyone.

Future Compatibility

This protocol is designed to remain fully compatible with future enhancements to XMTP that may address these limitations:

  • Directed Group Messages: If XMTP adds support for private messages within groups, Intent could target specific recipients without protocol changes
  • Client-Level Solutions: Clients could implement UI patterns that embed DM contexts within group chat interfaces
  • Inline Frames: Future clients might render agent DMs as inline frames or modals within the group chat context
  • Protocol Evolution: The minimal design ensures compatibility with future privacy features without breaking changes

The simplicity of this design means the protocol can adapt to new messaging patterns as they emerge.

Security Considerations

Replay Protection

The protocol employs nonces to prevent replay attacks:

  • Agents MUST generate unique nonces for each Actions message
  • Clients MUST reject duplicate (nonce, sender) combinations
  • Agents SHOULD maintain nonce validity windows (e.g., 24 hours)

Intent Verification

To prevent spoofing:

  • Agents MUST verify that Intent references a valid, unexpired Actions message they sent
  • Agents MUST verify the sender is an intended recipient of the original Actions
  • Clients MUST NOT allow users to craft arbitrary Intent messages

Privacy Preservation

  • Agents MUST clearly indicate when actions will be public vs. private
  • Payment amounts, personal data, and credentials MUST only be requested in DMs
  • Agents SHOULD transition to DMs for any extended interaction to avoid group clutter
  • Agents SHOULD warn users before collecting sensitive information

Backwards Compatibility

Clients that do not support the Inline Actions protocol will cannot parse Actions or Intent messages. To mitigate this, agents SHOULD:

  • Include fallback text with available commands in Actions messages
  • Recognize both button selections and text commands
  • Provide clear instructions for non-supporting clients

Example fallback text:

Choose an option:
[A] Option One
[B] Option Two

Reply with A or B to select

Implementation Considerations

Button State Management

Clients MUST:

  • Disable all buttons immediately upon selection
  • Persist selection state across app restarts
  • Show visual feedback for selected buttons
  • Handle expired actions appropriately

Agent Response Patterns

Agents SHOULD:

  • Acknowledge every Intent with a response
  • Use text messages for simple confirmations
  • Transition to DM for:
    • Multi-step workflows
    • Personalized configurations
    • Extended interactions
    • Privacy-sensitive data
  • Clearly communicate when/why DM is required
  • Keep group responses concise and relevant to all members

Visual Consistency

While clients have flexibility in rendering, they SHOULD:

  • Respect the style hint for visual hierarchy
  • Display icons when provided
  • Show expiration status clearly
  • Maintain consistent disabled states

Future Considerations

This specification provides a minimal foundation that can be extended:

  • Rich metadata schemas for common use cases
  • Conditional actions based on user state
  • Multi-step wizards with backward navigation
  • Integration with other content types
  • Standardized DM transition patterns

Extensions should maintain backward compatibility with the core intent model.

References

Copyright

Copyright and related rights waived via CC0.

3 Likes