Docs/Integrations

Integrations

TanStack AI

Last updated April 17, 2026

Integrate Cencori with TanStack Query, TanStack Start, and the first-party TanStack AI adapter.

Cencori works with the TanStack ecosystem in two common ways:

  1. use the first-party cencori/tanstack adapter with @tanstack/ai
  2. keep your Cencori API key on the server and call your own route from TanStack Query or TanStack Start

TanStack AI Adapter

Codetext
npm install cencori @tanstack/ai
Codetext
import { chat } from '@tanstack/ai';
import { cencori } from 'cencori/tanstack';
 
for await (const chunk of chat({
  adapter: cencori('gpt-4o'),
  messages: [{ role: 'user', content: 'Hello world' }],
})) {
  if (chunk.type === 'content') {
    console.log(chunk.delta);
  }
}

TanStack Query

Keep the API key on your server and call your own application route from the client:

Codetext
import { useMutation } from '@tanstack/react-query';
 
function AIComponent() {
  const mutation = useMutation({
    mutationFn: async (prompt: string) => {
      const response = await fetch('/api/ai', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({ prompt }),
      });
 
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
 
      return response.body;
    },
  });
 
  return <button onClick={() => mutation.mutate('Hello world')}>Generate</button>;
}

TanStack Start

Codetext
// app/routes/api/ai.ts
import { createAPIFileRoute } from '@tanstack/start/api';
import { Cencori } from 'cencori';
 
const cencori = new Cencori({
  apiKey: process.env.CENCORI_API_KEY,
});
 
export const Route = createAPIFileRoute('/api/ai')({
  POST: async ({ request }) => {
    const { prompt } = await request.json();
 
    const stream = cencori.ai.chatStream({
      model: 'gpt-4o',
      messages: [{ role: 'user', content: prompt }],
    });
 
    const encoder = new TextEncoder();
 
    return new Response(
      new ReadableStream({
        async start(controller) {
          for await (const chunk of stream) {
            controller.enqueue(encoder.encode(`data: ${JSON.stringify(chunk)}\n\n`));
          }
          controller.close();
        },
      }),
      {
        headers: { 'Content-Type': 'text/event-stream' },
      },
    );
  },
});

Security

Do not expose CENCORI_API_KEY through NEXT_PUBLIC_* variables. Use server routes or server functions for any request that requires a project secret key.