# Perplexity Client

Interact with Perplexity's search-augmented AI for real-time information retrieval and chat completions.

## Methods

| Method                                   | Description                                            |
| ---------------------------------------- | ------------------------------------------------------ |
| `apiRequest(options, schema, metadata?)` | Make any Perplexity API request with schema validation |

## Usage

### Chat Completion with Search

```typescript
import { api, z, perplexity } from "@superblocksteam/sdk-api";

// Integration ID from the integrations panel
const PROD_PERPLEXITY = "a1b2c3d4-5678-90ab-cdef-perplexi0001";

const ChatCompletionResponseSchema = z.object({
  id: z.string(),
  model: z.string(),
  created: z.number(),
  choices: z.array(
    z.object({
      index: z.number(),
      message: z.object({
        role: z.string(),
        content: z.string(),
      }),
      finish_reason: z.string(),
    }),
  ),
  usage: z.object({
    prompt_tokens: z.number(),
    completion_tokens: z.number(),
    total_tokens: z.number(),
  }),
  citations: z.array(z.string()).optional(),
});

export default api({
  integrations: {
    perplexity: perplexity(PROD_PERPLEXITY),
  },
  name: "PerplexityExample",
  input: z.object({
    question: z.string(),
  }),
  output: z.object({
    answer: z.string(),
    sources: z.array(z.string()),
  }),
  async run(ctx, { question }) {
    const result = await ctx.integrations.perplexity.apiRequest(
      {
        method: "POST",
        path: "/chat/completions",
        body: {
          model: "sonar-pro",
          messages: [
            {
              role: "system",
              content: "Be precise and cite your sources.",
            },
            { role: "user", content: question },
          ],
        },
      },
      { response: ChatCompletionResponseSchema },
    );

    return {
      answer: result.choices[0]?.message.content ?? "",
      sources: result.citations ?? [],
    };
  },
});
```

### Using Different Models

```typescript
// Standard search model - Fast, lightweight
const result = await ctx.integrations.perplexity.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "sonar", // Fast search
      messages: [{ role: "user", content: "What's the latest news about AI?" }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Pro search model - Deeper content understanding
const proResult = await ctx.integrations.perplexity.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "sonar-pro", // Advanced search
      messages: [{ role: "user", content: "Explain quantum computing" }],
    },
  },
  { response: ChatCompletionResponseSchema },
);

// Reasoning model - Multi-step Chain-of-Thought
const reasoningResult = await ctx.integrations.perplexity.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "sonar-reasoning-pro",
      messages: [{ role: "user", content: "Analyze the pros and cons of..." }],
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

### Search with Domain Filtering

```typescript
const result = await ctx.integrations.perplexity.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "sonar-pro",
      messages: [
        {
          role: "user",
          content: "Latest Python documentation on async/await",
        },
      ],
      search_domain_filter: ["python.org", "docs.python.org"], // Only search these domains
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

### Recency Filtering

```typescript
const result = await ctx.integrations.perplexity.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "sonar-pro",
      messages: [
        { role: "user", content: "Recent developments in electric vehicles" },
      ],
      search_recency_filter: "week", // Only recent results: "day", "week", "month", "year"
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

### Multi-turn Conversation

```typescript
const result = await ctx.integrations.perplexity.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "sonar",
      messages: [
        { role: "user", content: "What is the capital of France?" },
        { role: "assistant", content: "The capital of France is Paris." },
        { role: "user", content: "What's the population there?" },
      ],
    },
  },
  { response: ChatCompletionResponseSchema },
);
```

## Trace Metadata

All methods accept an optional `metadata` parameter as the last argument for diagnostics labeling. See the [root SDK README](../../../README.md#trace-metadata) for details.

## Common Pitfalls

### Streaming Is Not Supported

`apiRequest()` does not support streaming or Server-Sent Events. Do not set
`stream: true` — streaming responses fail schema validation. Every call
returns the complete response; if a UI needs real-time token streaming,
handle it at the frontend layer, not through the SDK.

### No Specialized Methods

```typescript
// WRONG - These methods do not exist
await perplexity.search({ ... });
await perplexity.chat({ ... });

// CORRECT - Use apiRequest
await ctx.integrations.perplexity.apiRequest(
  { method: "POST", path: "/chat/completions", body: { ... } },
  { response: ChatCompletionResponseSchema }
);
```

### Model Selection

Choose the right model for your use case:

```typescript
// For quick answers with web search
const model = "sonar";

// For complex queries requiring deeper understanding
const model = "sonar-pro";

// For multi-step reasoning tasks
const model = "sonar-reasoning-pro";

// For in-depth research
const model = "sonar-deep-research";
```

### Citations May Be Empty

Not all responses include citations:

```typescript
const result = await ctx.integrations.perplexity.apiRequest(...);

// Handle missing citations
const sources = result.citations ?? [];
if (sources.length === 0) {
  console.log("No citations provided for this response");
}
```

### Available Models

Perplexity offers the following Sonar models. Check the [Perplexity models page](https://docs.perplexity.ai/docs/sonar/models) for the latest options:

```typescript
const models = [
  "sonar", // Fast, lightweight search
  "sonar-pro", // Advanced search with deeper understanding
  "sonar-reasoning-pro", // Multi-step Chain-of-Thought reasoning
  "sonar-deep-research", // In-depth research for complex queries
];
```

### Search Parameters

All Sonar models support search by default. You can use search filters to refine results:

```typescript
await ctx.integrations.perplexity.apiRequest(
  {
    method: "POST",
    path: "/chat/completions",
    body: {
      model: "sonar-pro",
      messages: [...],
      search_domain_filter: ["example.com"], // Limit search to specific domains
    },
  },
  { response: schema }
);
```

## Error Handling

```typescript
import { RestApiValidationError } from "@superblocksteam/sdk-api";

try {
  const result = await ctx.integrations.perplexity.apiRequest(
    { method: "POST", path: "/chat/completions", body: { ... } },
    { response: ChatCompletionResponseSchema }
  );
} catch (error) {
  if (error instanceof RestApiValidationError) {
    console.error("Validation failed:", error.details.zodError);
  }
}
```

## API Reference

- [Perplexity API Documentation](https://docs.perplexity.ai/)
- [Sonar API](https://docs.perplexity.ai/api-reference/sonar-post)
- [Models](https://docs.perplexity.ai/docs/sonar/models)
