Skip to main content

Quickstart

You need three things to send a chat request:

  1. An API key with the chat:companion scope.
  2. A vector store (an Upstash Vector index) configured on your account.
  3. A request describing the persona and the conversation so far.

Base URL​

All client endpoints live under https://api.phantomrouter.ai, with the /api/v1 prefix.

1. Authenticate​

Every request carries your key as a Bearer token:

export PHANTOM_KEY="sk_your_api_key"
curl https://api.phantomrouter.ai/api/v1/me/vector-store \
-H "Authorization: Bearer $PHANTOM_KEY"

If the key is valid but no store is configured yet, you get 404 NOT_FOUND - that's expected, you'll fix it in the next step. See Authentication for how keys and scopes work.

2. Configure your vector store​

Phantom writes memories to your Upstash Vector index. Point it at the index's REST URL and token (a 1536-dimension index matching the default embedding model). Prefer a UI? Connect it from the console instead - see Connect your vector store for a screenshot walkthrough.

curl -X PUT https://api.phantomrouter.ai/api/v1/me/vector-store \
-H "Authorization: Bearer $PHANTOM_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "upstash",
"url": "https://your-index.upstash.io",
"token": "your-upstash-rest-token"
}'

Phantom test-probes the connection before saving and encrypts the token at rest. See the vector store reference for details and constraints.

3. Send a chat turn​

curl -X POST https://api.phantomrouter.ai/api/v1/companion/chat \
-H "Authorization: Bearer $PHANTOM_KEY" \
-H "Content-Type: application/json" \
-d '{
"chat_id": "user-42",
"persona": {
"name": "Luna",
"bio": "A warm, witty companion who loves astronomy and late-night talks.",
"chat_style": "playful, curious"
},
"messages": [
{ "role": "user", "content": "Hey Luna! I just hiked Mount Rainier. I'm Sam, by the way." }
]
}'

A successful response — the request messages echoed back with the reply appended as the final assistant turn:

{
"chat_id": "user-42",
"messages": [
{ "role": "user", "content": "Hey Luna! I just hiked Mount Rainier. I'm Sam, by the way." },
{
"role": "assistant",
"content": "Sam! Rainier is no joke - those switchbacks earn the view. ..."
}
],
"moderation": { "enabled": false, "inbound_prohibited": false }
}

The first turn retrieves nothing (the store is empty) and may not extract yet - memory extraction is cadence-gated (by default every 4 user turns). Keep the same chat_id across turns and Phantom builds up a memory of "Sam" and "Mount Rainier" that surfaces in later conversations.

4. See it work​

Reuse the same chat_id across turns and Phantom accumulates memory about the user. A few turns later, ask a follow-up and the earlier turns surface automatically in Luna's replies. The Playground is the fastest way to drive this interactively - send turns and inspect each request and response live, including exactly which memories were retrieved.

Next steps​