React SDK

The AgentKey React SDK provides React hooks and components for seamless integration with React applications. It handles authentication flows, token management, and connection status.

Installation

Install the React SDK in your React application:

npm install @agentkey/react

Quick Start

Basic Setup

import { useAgentLink } from '@agentkey/react';

function MyApp() {
  const { open, ready, error } = useAgentLink({
    linkToken: 'link_token_from_your_backend',
    onSuccess: (publicToken, metadata) => {
      console.log('Connected!', { publicToken, metadata });
      // Send publicToken to your backend for exchange
    },
    onError: (error) => {
      console.error('Connection failed:', error);
    },
  });

  return (
    <button onClick={open} disabled={!ready}>
      {ready ? 'Connect Account' : 'Loading...'}
    </button>
  );
}

Complete Integration

import { AgentLinkError, AgentLinkMetadata, useAgentLink } from '@agentkey/react';
import { useEffect, useState } from 'react';

function App() {
  const [linkToken, setLinkToken] = useState<string | null>(null);
  const [publicToken, setPublicToken] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  // Fetch link token from your backend
  useEffect(() => {
    async function fetchLinkToken() {
      try {
        const res = await fetch('/api/link-token', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ clientUserId: 'user_123' }),
        });
        const data = await res.json();
        setLinkToken(data.linkToken);
      } catch (error) {
        console.error('Failed to fetch link token:', error);
      } finally {
        setLoading(false);
      }
    }
    fetchLinkToken();
  }, []);

  const { open, ready, error } = useAgentLink({
    linkToken: linkToken || '',
    onSuccess: (publicToken: string, metadata: AgentLinkMetadata) => {
      console.log('✅ Authentication successful!', { publicToken, metadata });
      setPublicToken(publicToken);
      
      // Send publicToken to your backend for token exchange
      fetch('/api/exchange-token', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ publicToken }),
      });
    },
    onError: (error: AgentLinkError) => {
      console.error('❌ Authentication failed:', error);
    },
    env: 'sandbox', // or 'production'
  });

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      <h1>Connect Your Account</h1>
      
      <button onClick={open} disabled={!ready}>
        {ready ? 'Connect Account' : 'Loading...'}
      </button>

      {error && (
        <div style={{ color: 'red' }}>
          Error: {error.displayMessage || error.errorMessage}
        </div>
      )}

      {publicToken && (
        <div style={{ marginTop: '1rem', padding: '1rem', backgroundColor: '#d4edda' }}>
          <h3>✅ Connected Successfully!</h3>
          <p>Public Token: {publicToken.substring(0, 20)}...</p>
          <p>Token sent to backend for exchange</p>
        </div>
      )}
    </div>
  );
}

API Reference

The primary hook for handling AgentKey authentication flows.

Parameters

interface UseAgentLinkConfig {
  linkToken: string;              // Link token from your backend
  onSuccess: (publicToken: string, metadata: AgentLinkMetadata) => void;
  onError: (error: AgentLinkError) => void;
  onExit?: (error: AgentLinkError | null, metadata: AgentLinkMetadata) => void;
  env?: 'sandbox' | 'production'; // Environment (default: 'sandbox')
}

Return Value

interface UseAgentLinkReturn {
  open: () => void;     // Function to open the authentication flow
  ready: boolean;       // Whether the SDK is ready to be used
  error: AgentLinkError | null; // Current error state
}

Types

interface AgentLinkMetadata {
  provider: string;     // Provider slug (e.g., 'linkedin', 'github')
  sessionId: string;    // Unique session identifier
  timestamp: number;    // Connection timestamp
}

interface AgentLinkError {
  errorCode: string;          // Machine-readable error code
  errorMessage: string;       // Technical error message
  displayMessage?: string;    // User-friendly error message
}

Authentication Flow

The React SDK follows this simple pattern:

  1. Get Link Token: Fetch a link token from your backend
  2. User Authentication: User connects their account through AgentKey
  3. Receive Public Token: Your onSuccess callback receives a public token
  4. Send to Backend: Send the public token to your backend for token exchange

Error Handling

Handle different types of errors:

const { open, ready, error } = useAgentLink({
  linkToken: 'your-link-token',
  onError: (error: AgentLinkError) => {
    switch (error.errorCode) {
      case 'INVALID_LINK_TOKEN':
        console.error('Link token is invalid or expired');
        break;
      case 'USER_CANCELLED':
        console.log('User cancelled the authentication flow');
        break;
      case 'NETWORK_ERROR':
        console.error('Network connection failed');
        break;
      default:
        console.error('Unknown error:', error.errorMessage);
    }
  },
});

Best Practices

Always fetch link tokens from your backend:

// ✅ Good - Fetch from your secure backend
const fetchLinkToken = async () => {
  const response = await fetch('/api/link-token', {
    method: 'POST',
    credentials: 'include',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ clientUserId: user.id }),
  });
  return response.json();
};

Token Exchange

Send public tokens to your backend immediately:

// ✅ Good - Send to backend for secure exchange
const { open } = useAgentLink({
  linkToken,
  onSuccess: (publicToken) => {
    // Immediately send to backend
    fetch('/api/exchange-token', {
      method: 'POST',
      body: JSON.stringify({ publicToken }),
    });
  },
});

User Experience

Provide clear feedback to users:

const [status, setStatus] = useState('');

const { open, ready, error } = useAgentLink({
  linkToken,
  onSuccess: () => setStatus('Account connected successfully!'),
  onError: (error) => setStatus(`Error: ${error.displayMessage}`),
});

return (
  <div>
    <button onClick={open} disabled={!ready}>
      Connect Account
    </button>
    {status && <div>{status}</div>}
  </div>
);

Next Steps

  • Backend Integration - Set up your backend to create link tokens and exchange public tokens
  • Examples - See complete React integration examples
  • API Reference - Backend API documentation