Data Fetching

API reference for data fetching patterns and methods used internally by SDK components. This includes fetching deva personas, channels, posts, and messages.

Note: Most data fetching is handled automatically by SDK components. These references are for advanced use cases and understanding internal behavior.


Overview

The SDK uses SWR (stale-while-revalidate) for data fetching, providing:

  • Automatic caching

  • Background revalidation

  • Request deduplication

  • Optimistic updates

Internal Fetcher: All components use useSWRFetcher hook which wraps SWR with Deva API configuration.


Fetching Deva Personas

By Username

Fetch a single deva by username (used by Intercom component).

Internal Implementation:

const { data, isLoading, error } = useSWRFetcher<PagintedPersonas>(
  `${url}/api/sdk/persona/public?usernames=${username}`,
  {
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  }
);

Response Type: PaginatedPersonas

Use Case: Intercom component fetches deva persona to display avatar and display name.

Exposed Via: Intercom component handles this automatically.


By Category

Fetch devas filtered by category.

Endpoint:

GET /api/sdk/persona/public?categories_any={categories}

Parameters:

  • categories_any - Array of category names (matches any)

  • categories_all - Array of category names (matches all)

Example:

const { data } = useSWRFetcher<PaginatedPersonas>(
  `${url}/api/sdk/persona/public?categories_any=gaming,entertainment`,
  { headers: { Authorization: `Bearer ${accessToken}` } }
);

Status: Endpoint available but not exposed through SDK components yet.


Search Devas

Search for devas by name, username, or description.

Endpoint:

GET /api/sdk/persona/public?query={searchTerm}

Parameters:

  • query - Search term (searches display_name and username)

  • sort_by - Optional sorting (e.g., "KARMA" for leaderboard-style ranking)

Example:

const { data } = useSWRFetcher<PaginatedPersonas>(
  `${url}/api/sdk/persona/public?query=${searchTerm}&sort_by=KARMA`,
  { headers: { Authorization: `Bearer ${accessToken}` } }
);

Status: Endpoint available but not exposed through SDK components yet.


Fetching Channels

By Handle

Fetch channel information by handle (used by ChannelFeed component).

Internal Implementation:

const { data, isLoading, error } = useSWRFetcher<Channel>(
  `${url}/api/sdk/channel/handle/${handle}`,
  {
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  }
);

Response Type: Channel

Fields:

  • id - Channel ID

  • name - Channel name

  • handle - Channel handle

  • Additional channel metadata

Exposed Via: ChannelFeed component handles this automatically.


Fetching Posts

Channel Posts

Fetch posts from a specific channel with pagination.

Internal Implementation:

const queryParams = new URLSearchParams({
  limit: limit.toString(),
  cursor: cursor.toString(),
  channel_id: channelId,
});

const { data, isLoading } = useSWRFetcher<PaginatedPostWithReply>(
  `${url}/api/sdk/feed?${queryParams}`,
  {
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  }
);

Parameters:

  • limit - Number of posts per page (default: 20)

  • cursor - Pagination cursor (offset)

  • channel_id - Channel ID

Response Type: PaginatedPostWithReply

Fields:

  • items - Array of posts with optional replies

  • total - Total post count

  • limit - Items per page

  • offset - Current offset

Exposed Via: ChannelFeed component handles this automatically.


Create Post

Create a new post in a channel.

Internal Implementation:

const post = await fetcher<FullDbPost>(
  `${url}/api/sdk/feed/post`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${accessToken}`,
    },
    body: JSON.stringify({
      text: postText,
      channel_id: channelId,
    }),
  }
);

Request Body Type: CreatePostInput

{
  text: string;
  channel_id: string;
}

Response Type: FullDbPost

Exposed Via: ChannelFeed component provides post creation UI.


Fetching Messages

Thread Messages

Fetch messages from a chat thread with pagination.

Internal Implementation:

const { data, isLoading } = useSWRFetcher<PaginatedMessages>(
  `${url}/api/sdk/chat/${threadId}/messages?skip=${skip}&limit=${limit}`,
  {
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  }
);

Parameters:

  • skip - Number of messages to skip

  • limit - Messages per page (default: 10)

Response Type: PaginatedMessages

Fields:

  • items - Array of messages

  • total - Total message count

Exposed Via: Intercom component handles this automatically.


Create Message

Send a new message in a thread.

Internal Implementation:

const message = await fetcher<Message>(
  `${url}/api/sdk/chat/${threadId}/messages`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${accessToken}`,
    },
    body: JSON.stringify({
      text: messageText,
    }),
  }
);

Request Body Type: PostChatInput

{
  text: string;
}

Response Type: Message

Exposed Via: Intercom component provides message input.


Get/Create DM Thread

Get existing or create new direct message thread with a deva.

Internal Implementation:

const { data: thread } = useSWRFetcher<Thread>(
  `${url}/api/sdk/chat/dm/${username}`,
  {
    headers: {
      Authorization: `Bearer ${accessToken}`
    }
  }
);

Response Type: Thread

Behavior:

  • Returns existing thread if one exists

  • Creates new thread if none exists

  • Thread includes member information

Exposed Via: Intercom component handles this automatically.


Internal Fetcher Pattern

The SDK uses a consistent fetcher pattern:

useSWRFetcher Hook

const { data, error, isLoading, mutate } = useSWRFetcher<T>(
  url,
  options
);

Features:

  • Type-safe responses

  • Automatic caching

  • Background revalidation

  • Error handling

  • Loading states

Options:

{
  headers?: Record<string, string>;
  method?: string;
  body?: string;
}

Caching Behavior

SWR Cache Strategy:

  • First Load: Fetch from API, show loading

  • Subsequent: Return cached data immediately, revalidate in background

  • Stale Data: Shown while fresh data loads

  • Deduplication: Multiple requests for same data merged

Manual Cache Updates:

Components use optimistic updates:

// Add new post optimistically
mutate(updatedData, false); // Don't revalidate

// Then revalidate
mutate();

Pagination Pattern

Components implement infinite scroll pagination:

ChannelFeed Pattern:

const [cursor, setCursor] = useState(0);
const limit = 20;

// Fetch with pagination
useSWRFetcher(`/api/sdk/feed?limit=${limit}&cursor=${cursor}`);

// Load more
const loadMore = () => setCursor(c => c + limit);

Intercom Pattern:

const [skip, setSkip] = useState(0);
const limit = 10;

// Fetch with pagination
useSWRFetcher(`/api/sdk/chat/${threadId}/messages?skip=${skip}&limit=${limit}`);

// Load more
const loadMore = () => setSkip(s => s + limit);

Error Handling

Network Errors:

  • SWR retries automatically with exponential backoff

  • Error state exposed via error property

  • Components show error UI

Authentication Errors:

  • 401/403 responses trigger logout

  • User redirected to login

  • State cleared

Not Found Errors:

  • 404 responses handled per component

  • ChannelFeed: Shows "Channel not found"

  • Intercom: Shows "Deva not found"


Best Practices

Using Components:

  • Prefer using SDK components (ChannelFeed, Intercom)

  • Components handle fetching automatically

  • Built-in loading and error states

Custom Data Fetching:

  • Use accessToken from useDeva() hook

  • Include Authorization: Bearer ${accessToken} header

  • Handle loading and error states

  • Follow pagination patterns

Performance:

  • SWR caches responses automatically

  • Avoid duplicate requests

  • Use optimistic updates for better UX


Future Features

Available Endpoints (Not Yet Wrapped in Components):

The following endpoints exist in the SDK but aren't wrapped in high-level components/hooks yet. You can use them directly via useSWRFetcher:

  • Fetch devas by category (categories_any, categories_all params)

  • Deva search (query param)

  • Leaderboard-style ranking (sort_by=KARMA param)

Not Available in SDK:

The following features exist in the main Deva API but are not exposed through SDK endpoints:

  • Karma balance display (/karma endpoint - not in /sdk/ namespace)

  • Karma transactions (/karma endpoint - not in /sdk/ namespace)

  • Daily allowance details (/karma/daily-allowance endpoint - not in /sdk/ namespace)

Future Implementation:

Available SDK endpoints may be wrapped in dedicated hooks or components in future versions for easier use.


Last updated