Client Actions

The agent can return actions that your app should handle—navigation, opening modals, playing videos, and more.

How Actions Work

Actions are triggered by:

  1. Keyword triggers - Configured keywords that match user input (processed before AI)
  2. Intent triggers - AI-detected intents that match configured patterns (processed after AI)

See the Triggers API for creating and managing triggers programmatically.

User: "show me the pricing page"
         ↓
  Keyword Match: "pricing"
         ↓
  Action Triggered: { type: "navigate", payload: { route: "/pricing" } }
         ↓
  Response includes action for client to handle

Response Format

When actions are triggered, they appear in the response:

{
  "success": true,
  "data": {
    "message": "Sure! Let me take you to our pricing page.",
    "sessionId": "sess_abc123",
    "actions": [
      {
        "type": "navigate",
        "payload": { "route": "/pricing" },
        "label": "View Pricing",
        "immediate": true
      }
    ],
    "intent": {
      "name": "navigation_request",
      "confidence": 0.95
    }
  }
}

Action Types

| Type | Description | Payload Fields | |------|-------------|----------------| | navigate | Navigate to app route | route, params | | open_url | Open external URL | url | | open_content | Display content | contentId | | play_video | Play video | videoId, timestamp | | show_product | Show product details | productId | | add_to_cart | Add to cart | productId, quantity | | open_modal | Open modal/dialog | modalId, modalData | | trigger_event | Fire custom event | eventName, eventData | | custom | App-specific action | customType, customData |

Action Properties

| Property | Type | Description | |----------|------|-------------| | type | string | Action type (see table above) | | payload | object | Action-specific data | | label | string | Optional display label for UI | | priority | number | Higher = processed first | | immediate | boolean | true = execute now, false = suggest to user |

Handling Actions

React/Next.js

import { useRouter } from 'next/navigation';

interface ClientAction {
  type: string;
  payload: Record<string, any>;
  immediate?: boolean;
}

function useAgentActions() {
  const router = useRouter();

  const handleActions = (actions: ClientAction[]) => {
    for (const action of actions) {
      // Skip non-immediate actions (show as suggestions instead)
      if (action.immediate === false) continue;

      switch (action.type) {
        case 'navigate':
          if (action.payload.route) {
            router.push(action.payload.route);
          }
          break;

        case 'open_url':
          if (action.payload.url) {
            window.open(action.payload.url, '_blank');
          }
          break;

        case 'play_video':
          if (action.payload.videoId) {
            // Your video player logic
            openVideoPlayer(action.payload.videoId, action.payload.timestamp);
          }
          break;

        case 'show_product':
          if (action.payload.productId) {
            showProductModal(action.payload.productId);
          }
          break;

        case 'trigger_event':
          if (action.payload.eventName) {
            window.dispatchEvent(
              new CustomEvent(action.payload.eventName, {
                detail: action.payload.eventData,
              })
            );
          }
          break;

        case 'custom':
          handleCustomAction(action.payload);
          break;
      }
    }
  };

  return { handleActions };
}

Using with Chat

const { handleActions } = useAgentActions();

async function sendMessage(text: string) {
  const response = await fig1.chat(text, sessionId);

  // Display the message
  addMessage(response.message);

  // Handle any actions
  if (response.actions) {
    handleActions(response.actions);
  }
}

Handling Suggestions (Non-Immediate Actions)

Actions with immediate: false should be shown to the user as clickable suggestions:

function ActionSuggestions({ actions }: { actions: ClientAction[] }) {
  const { handleActions } = useAgentActions();

  const suggestions = actions.filter(a => a.immediate === false);

  if (suggestions.length === 0) return null;

  return (
    <div className="flex gap-2 mt-2">
      {suggestions.map((action, i) => (
        <button
          key={i}
          onClick={() => handleActions([{ ...action, immediate: true }])}
          className="px-3 py-1 bg-gray-100 rounded-full text-sm hover:bg-gray-200"
        >
          {action.label || action.type}
        </button>
      ))}
    </div>
  );
}

Flutter Example

class Fig1ActionHandler {
  final BuildContext context;

  Fig1ActionHandler(this.context);

  void handleActions(List<ClientAction> actions) {
    for (final action in actions) {
      if (!action.immediate) continue;

      switch (action.type) {
        case 'navigate':
          final route = action.payload['route'] as String?;
          if (route != null) {
            Navigator.pushNamed(context, route);
          }
          break;

        case 'open_url':
          final url = action.payload['url'] as String?;
          if (url != null) {
            launchUrl(Uri.parse(url));
          }
          break;

        case 'show_product':
          final productId = action.payload['productId'] as String?;
          if (productId != null) {
            Navigator.pushNamed(context, '/product/$productId');
          }
          break;
      }
    }
  }
}

Configuring Actions

Actions can be configured in two ways:

Via Dashboard

  1. Go to SDK SettingsTriggers tab
  2. Create a trigger (keyword or intent-based)
  3. Add actions to the trigger
  4. Configure payload and behavior

Via API

Use the Triggers API to programmatically manage triggers:

curl -X POST https://app.fig1.ai/api/sdk/triggers \
  -H "Content-Type: application/json" \
  -H "X-Fig1-API-Key: fig1_sdk_your_api_key" \
  -d '{
    "type": "keyword",
    "trigger": { "value": "pricing" },
    "response": { "message": "Navigating to pricing..." },
    "actions": [{ "type": "navigate", "payload": { "route": "/pricing" } }],
    "options": { "skipAgent": true }
  }'

Keyword vs Intent Triggers

| Aspect | Keyword Triggers | Intent Triggers | |--------|------------------|-----------------| | When | Before AI processing | After AI processing | | Speed | Instant (no AI call) | Requires AI response | | Matching | Exact/phrase match | AI confidence-based | | Use Case | Navigation, known commands | Complex user requests | | Example | "pricing", "contact us" | "I want to buy something" |

Best Practices

  1. Use keyword triggers for navigation - They're faster than intent triggers
  2. Set immediate: true for navigation - Users expect immediate response
  3. Use immediate: false for suggestions - Let users choose
  4. Handle all action types - Gracefully ignore unknown types
  5. Log actions for analytics - Track which actions users trigger