Transactional

Migrate from Anthropic SDK

Add observability to your existing Anthropic Claude integration with minimal code changes.

Overview

Already using the Anthropic SDK? Add full observability with just 3 lines of code. No need to change your existing API calls.

Quick Migration

Before (Direct Anthropic)

import Anthropic from '@anthropic-ai/sdk';
 
const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
});
 
const response = await anthropic.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
});

After (With Observability)

import Anthropic from '@anthropic-ai/sdk';
+ import { initObservability, wrapAnthropic } from '@transactional/observability';
 
+ initObservability({ dsn: process.env.TRANSACTIONAL_OBSERVABILITY_DSN! });
 
- const anthropic = new Anthropic({
+ const anthropic = wrapAnthropic(new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
- });
+ }));
 
// All existing code works unchanged!
const response = await anthropic.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
});

Step-by-Step Migration

1. Install the SDK

npm install @transactional/observability

2. Get Your DSN

  1. Go to Observability Dashboard
  2. Create or select a project
  3. Copy the DSN from project settings

3. Initialize Observability

Add initialization at your application entry point:

// app.ts or index.ts
import { initObservability } from '@transactional/observability';
 
initObservability({
  dsn: process.env.TRANSACTIONAL_OBSERVABILITY_DSN!,
  // Optional: only enable in production
  enabled: process.env.NODE_ENV === 'production',
});

4. Wrap Your Anthropic Client

Update where you create your Anthropic client:

// lib/anthropic.ts
import Anthropic from '@anthropic-ai/sdk';
import { wrapAnthropic } from '@transactional/observability';
 
export const anthropic = wrapAnthropic(new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
}));

5. Use As Normal

All your existing code continues to work:

import { anthropic } from '@/lib/anthropic';
 
// Messages API
const message = await anthropic.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
});
 
// With system prompt
const withSystem = await anthropic.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 1024,
  system: 'You are a helpful assistant.',
  messages: [{ role: 'user', content: 'Hello!' }],
});
 
// Streaming
const stream = await anthropic.messages.stream({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Tell me a story' }],
});
 
// Tool use
const tools = await anthropic.messages.create({
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 1024,
  tools: [...],
  messages: [...],
});

Adding Context (Optional)

Enhance your traces with additional context:

User Tracking

import { getObservability } from '@transactional/observability';
 
// After user authentication
const obs = getObservability();
obs.setUser({
  id: user.id,
  email: user.email,
});

Per-Request Context

const response = await anthropic.messages.create(
  {
    model: 'claude-3-5-sonnet-20241022',
    max_tokens: 1024,
    messages: [...],
  },
  {
    observability: {
      name: 'code-assistant',
      userId: user.id,
      sessionId: conversationId,
      tags: ['code', 'assistant'],
    },
  }
);

Grouping Conversations

// Use the same sessionId for all messages in a conversation
const sessionId = `chat-${conversationId}`;
 
// First message
await anthropic.messages.create(
  { model: 'claude-3-5-sonnet-20241022', max_tokens: 1024, messages: [...] },
  { observability: { sessionId } }
);
 
// Follow-up message (same session)
await anthropic.messages.create(
  { model: 'claude-3-5-sonnet-20241022', max_tokens: 1024, messages: [...] },
  { observability: { sessionId } }
);

Framework Examples

Next.js App Router

// lib/anthropic.ts
import Anthropic from '@anthropic-ai/sdk';
import { wrapAnthropic } from '@transactional/observability';
 
export const anthropic = wrapAnthropic(new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
}));
// app/api/chat/route.ts
import { anthropic } from '@/lib/anthropic';
 
export async function POST(request: Request) {
  const { messages, userId } = await request.json();
 
  const response = await anthropic.messages.create(
    {
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 1024,
      messages,
    },
    {
      observability: {
        name: 'api-chat',
        userId,
      },
    }
  );
 
  return Response.json({ message: response.content[0].text });
}

Express

// lib/anthropic.ts
import Anthropic from '@anthropic-ai/sdk';
import { wrapAnthropic } from '@transactional/observability';
 
export const anthropic = wrapAnthropic(new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
}));
// routes/chat.ts
import { anthropic } from '../lib/anthropic';
 
app.post('/chat', async (req, res) => {
  const { messages } = req.body;
 
  const response = await anthropic.messages.create(
    {
      model: 'claude-3-5-sonnet-20241022',
      max_tokens: 1024,
      messages,
    },
    {
      observability: {
        userId: req.user?.id,
        sessionId: req.session?.id,
      },
    }
  );
 
  res.json({ message: response.content[0].text });
});

Error Tracking

Enable error tracking for Anthropic failures:

import { getObservability } from '@transactional/observability';
 
const obs = getObservability();
 
try {
  const response = await anthropic.messages.create({...});
} catch (error) {
  obs.captureException(error as Error, {
    tags: { provider: 'anthropic' },
    extra: { model: 'claude-3-5-sonnet-20241022' },
  });
  throw error;
}

What You Get

After migration, you automatically get:

FeatureDescription
Full TracingEvery API call is traced
Token TrackingInput and output tokens
Cost CalculationAutomatic cost per request
Latency MetricsResponse time tracking
Error TrackingAPI errors captured
Session GroupingGroup related calls
DashboardVisual analytics and debugging

Verifying Migration

  1. Make an API call with the wrapped client
  2. Go to Observability Dashboard
  3. Select your project and click Traces
  4. You should see your API call with full details

Rollback

If you need to rollback, simply remove the wrapper:

- import { wrapAnthropic } from '@transactional/observability';
 
- const anthropic = wrapAnthropic(new Anthropic({
+ const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY,
- }));
+ });

Next Steps