Two API calls.
That's the whole integration.

Track conversations after they happen. Query preferences before your agent responds. pref0 extracts what matters and compounds it over time.

1

Send conversations after they end

await fetch("https://api.pref0.com/v1/track", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${PREF0_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    userId: "user_abc",
    messages: conversation.messages,
  }),
});
2

Query preferences before responding

const { prompt } = await fetch(
  `https://api.pref0.com/v1/profiles/${userId}?minConfidence=0.5`,
  { headers: { Authorization: `Bearer ${PREF0_KEY}` } },
).then(r => r.json());

// Append to your system prompt — that's it
const systemPrompt = basePrompt + "\n\n" + prompt;

Your agent remembers everything

Preferences compound across conversations. Confidence increases with repetition. Users never repeat themselves.

Extracts

Corrections, explicit instructions, implied preferences from natural conversation.

Compounds

Same preference across multiple sessions increases confidence from 0.4 to 1.0.

Serves

Returns a ready-to-use prompt string. Append to system prompt. Done.

What pref0 extracts from a conversation
user:      "Set up a React project"
assistant: "Here's a project with npm and JavaScript..."
user:      "Use pnpm, not npm. And TypeScript."

→ package_manager: pnpm       confidence: 0.70  (explicit correction)
  language:        typescript  confidence: 0.70  (explicit correction)

Next time this user asks, your agent defaults to pnpm + TypeScript.

API Reference

Base URL https://api.pref0.comAuth Bearer pref0_sk_...
POST/v1/track

Send a conversation to learn from. Preferences are extracted and merged into the user's profile.

userId string — your identifier for the user
messages array of {role, content} — the conversation to learn from
conversationId string, optional — explicit conversation identifier for dedup. If omitted, pref0 auto-detects repeated conversations by fingerprinting the first message and only processes new messages.
Request
curl -X POST https://api.pref0.com/v1/track \
  -H "Authorization: Bearer pref0_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
  "userId": "user_abc",
  "messages": [
    { "role": "user", "content": "Set up a new React project for me" },
    { "role": "assistant", "content": "Sure! I\'ll create a React project with npm..." },
    { "role": "user", "content": "Actually use pnpm, not npm. And TypeScript please." },
    { "role": "assistant", "content": "Got it — switching to pnpm and TypeScript." }
  ]
}'

Messages use the same {role, content} format as the OpenAI/Anthropic chat APIs. Pass the full conversation — pref0 auto-deduplicates and only extracts from new messages when the same conversation is sent again.

Response
{
  "messagesAnalyzed": 4,
  "preferences": { "created": 3, "reinforced": 0, "decreased": 0, "removed": 0 },
  "patterns":    { "created": 1, "reinforced": 0 }
}
GET/v1/profiles/:userId

Get learned preferences. Returns structured data + a ready-to-use prompt string.

minConfidence number, optional — filter by confidence (0–1)
Response
{
  "userId": "user_abc",
  "preferences": [
    {
      "key": "language",
      "value": "typescript",
      "confidence": 0.85,
      "evidence": "User said: Use TypeScript, not JavaScript",
      "firstSeen": "2026-01-15T10:00:00.000Z",
      "lastSeen": "2026-02-05T14:30:00.000Z"
    },
    {
      "key": "package_manager",
      "value": "pnpm",
      "confidence": 0.85,
      "evidence": "User said: use pnpm instead of npm",
      "firstSeen": "2026-01-15T10:00:00.000Z",
      "lastSeen": "2026-02-03T09:15:00.000Z"
    }
  ],
  "patterns": [
    { "pattern": "prefers explicit tooling choices", "confidence": 0.45 }
  ],
  "prompt": "The following preferences have been learned from this user's previous conversations. Follow them unless explicitly told otherwise:\n- language: typescript\n- package_manager: pnpm\n\nBehavioral patterns observed:\n- prefers explicit tooling choices"
}

The prompt field is a ready-to-use string — append it directly to your system prompt. Each preference includes evidence (the quote that triggered extraction), firstSeen, and lastSeen timestamps.

DELETE/v1/profiles/:userId

Reset a user's profile. Returns 204.

GET/v1/usage

Org request count + last request timestamp.

Errors return {"error": "..."}. Status codes: 400 validation · 401 auth · 500 server.

100 requests/mo free. No credit card.

Get your API key