Skip to content
you2you
  • Platform
  • Create your twin
  • Developers
  • Company
  • Contact us

Chat with your twin from your own software

The you2you API lets another app talk to your own digital twin: a Slack bot, a website widget, a script. Your app sends what people said, and your twin replies as it does in you2you.

Get a key

  1. Open you2you and go to Profile.
  2. Under Your digital twin, tap API keys, then New key.
  3. Name the key after the app that uses it, and copy it. You see it only once.

You can have up to 10 keys. Revoking one stops every app that uses it right away. A key only reaches your own twin. Keep it secret, like a password.

Send messages

Send the key as a bearer token. Pick your own id for each chat room. The room is created on the first message.

curl -X POST https://api.you2you.net/api/v1/chatrooms/support-42/messages \
  -H "Authorization: Bearer y2y_..." \
  -H "Content-Type: application/json" \
  -d '{"messages": [{"type": "user", "name": "Ana", "message": "Hi! What do you do for fun?"}]}'

The answer is 202 {"status": "pending"}. Your twin replies in the background, usually within seconds.

  • Send 1 to 20 messages at once, each up to 1,000 characters.
  • name is who said it. Different names are different people to your twin, so it can join a group conversation.
  • Several posts in a row get one reply to all of them.
  • A chat room id uses letters, digits and . _ : -, up to 200 characters. It shows up in request logs, so don't put personal data in it.

Get the reply

Either ask for it:

curl "https://api.you2you.net/api/v1/chatrooms/support-42/messages?limit=2" \
  -H "Authorization: Bearer y2y_..."
{
  "status": "replied",
  "detail": null,
  "messages": [
    {"type": "user", "name": "Ana", "message": "Hi! What do you do for fun?"},
    {"type": "assistant", "name": "Suzy", "message": "Mostly hiking, and far too much baking."}
  ]
}

Or have it sent to you: add "callback_url": "https://..." to the POST. When the turn ends, we POST {chatroom_id, status, detail, messages} to that URL. messages is empty unless the status is replied. A room uses the latest URL you sent.

Callbacks are not signed. Put a user and password in the URL (https://user:secret@example.com/hook) and check them on your side: we send them as Basic auth. We try 3 times, wait 5 seconds at most and don't follow redirects.

Examples

Each example goes through the whole flow: it sends a message and waits for the reply, sends a second one from another person, reads the conversation, lists your chat rooms and deletes the room. Set Y2Y_API_KEY in your environment first. Run them on your own computer or server: never put a key in a web page or a mobile app.

Needs curl and jq. Save it as ask.sh and run bash ask.sh.

#!/usr/bin/env bash
set -euo pipefail

API=https://api.you2you.net/api/v1/chatrooms
ROOM=example-1
AUTH="Authorization: Bearer $Y2Y_API_KEY"

# Send one message and wait until your twin's turn ends.
send() {
  jq -n --arg name "$1" --arg message "$2" '{messages: [{type: "user", name: $name, message: $message}]}' |
    curl -fsS -X POST "$API/$ROOM/messages" -H "$AUTH" -H "Content-Type: application/json" -d @- > /dev/null
  while true; do
    sleep 2
    body=$(curl -fsS "$API/$ROOM/messages?limit=1" -H "$AUTH")
    [ "$(jq -r .status <<< "$body")" != pending ] && break
  done
  jq -r 'if .status == "replied" then "Twin: \(.messages[-1].message)" else "No reply (\(.status)): \(.detail)" end' <<< "$body"
}

# 1. The first message creates the room.
send Ana "Hi! What do you do for fun?"

# 2. Keep talking in the same room. Another name is another person.
send Ben "And what is your favourite book?"

# 3. Read the conversation, oldest first.
curl -fsS "$API/$ROOM/messages?limit=50" -H "$AUTH" | jq -r '.messages[] | "\(.name): \(.message)"'

# 4. List your chat rooms, most recently active first.
curl -fsS "$API?limit=20" -H "$AUTH" | jq -r '.items[] | "\(.chatroom_id) \(.status) \(.message_count)"'

# 5. Delete the room.
curl -fsS -X DELETE "$API/$ROOM" -H "$AUTH"

Needs pip install requests. Save it as ask.py and run python ask.py.

import os
import time

import requests

API = "https://api.you2you.net/api/v1/chatrooms"
ROOM = "example-1"
session = requests.Session()
session.headers["Authorization"] = f"Bearer {os.environ['Y2Y_API_KEY']}"


def send(name, message):
    """Send one message and wait until your twin's turn ends."""
    session.post(
        f"{API}/{ROOM}/messages",
        json={"messages": [{"type": "user", "name": name, "message": message}]},
    ).raise_for_status()
    while True:
        time.sleep(2)
        response = session.get(f"{API}/{ROOM}/messages", params={"limit": 1})
        response.raise_for_status()
        body = response.json()
        if body["status"] != "pending":
            break
    if body["status"] == "replied":
        print("Twin:", body["messages"][-1]["message"])
    else:
        print(f"No reply ({body['status']}):", body["detail"])


# 1. The first message creates the room.
send("Ana", "Hi! What do you do for fun?")

# 2. Keep talking in the same room. Another name is another person.
send("Ben", "And what is your favourite book?")

# 3. Read the conversation, oldest first.
history = session.get(f"{API}/{ROOM}/messages", params={"limit": 50})
history.raise_for_status()
for message in history.json()["messages"]:
    print(f"{message['name']}: {message['message']}")

# 4. List your chat rooms, most recently active first.
rooms = session.get(API, params={"limit": 20})
rooms.raise_for_status()
for room in rooms.json()["items"]:
    print(room["chatroom_id"], room["status"], room["message_count"])

# 5. Delete the room.
session.delete(f"{API}/{ROOM}").raise_for_status()

Needs Node 18 or newer. Save it as ask.mjs and run node ask.mjs.

const API = "https://api.you2you.net/api/v1/chatrooms";
const ROOM = "example-1";
const headers = {
  Authorization: `Bearer ${process.env.Y2Y_API_KEY}`,
  "Content-Type": "application/json",
};

async function call(method, url, body) {
  const response = await fetch(url, { method, headers, body: body && JSON.stringify(body) });
  if (!response.ok) throw new Error(`${method} ${url} failed with ${response.status}`);
  return response.status === 204 ? null : response.json();
}

// Send one message and wait until your twin's turn ends.
async function send(name, message) {
  await call("POST", `${API}/${ROOM}/messages`, { messages: [{ type: "user", name, message }] });
  let body;
  do {
    await new Promise((resolve) => setTimeout(resolve, 2000));
    body = await call("GET", `${API}/${ROOM}/messages?limit=1`);
  } while (body.status === "pending");
  if (body.status === "replied") console.log("Twin:", body.messages.at(-1).message);
  else console.log(`No reply (${body.status}):`, body.detail);
}

// 1. The first message creates the room.
await send("Ana", "Hi! What do you do for fun?");

// 2. Keep talking in the same room. Another name is another person.
await send("Ben", "And what is your favourite book?");

// 3. Read the conversation, oldest first.
const history = await call("GET", `${API}/${ROOM}/messages?limit=50`);
for (const message of history.messages) console.log(`${message.name}: ${message.message}`);

// 4. List your chat rooms, most recently active first.
const rooms = await call("GET", `${API}?limit=20`);
for (const room of rooms.items) console.log(room.chatroom_id, room.status, room.message_count);

// 5. Delete the room.
await call("DELETE", `${API}/${ROOM}`);

Statuses

StatusMeans
pendingYour twin is still working on it.
repliedYour twin answered.
no_replyYour twin chose not to answer, or its answer was held back.
over_budgetYour monthly AI budget is spent.
pausedYour account or your twin is paused in the app.
failedSomething went wrong on our side. Try again later.

When you can do something about it, detail says why in plain words.

All routes

RouteDoes
POST /api/v1/chatrooms/{id}/messagesAdds messages, creating the room if needed.
GET /api/v1/chatrooms/{id}/messages?limit=1The status and the newest 1 to 50 messages, oldest first.
GET /api/v1/chatrooms?limit=20&offset=0Your rooms as {items, total}, most recently active first.
DELETE /api/v1/chatrooms/{id}Deletes a room. Posting to the same id later starts an empty one.

The full reference is at api.you2you.net/api/v1/docs, and the OpenAPI schema at api.you2you.net/api/v1/openapi.json.

Errors and limits

  • 401: the key is wrong or revoked.
  • 404: no chat room has that id.
  • 409: your twin is not ready yet, or is deactivated.
  • 422: the request is not valid. The body says which field.
  • 429: too many requests. Each key may post 60 times a minute.

Replies use the same monthly AI budget as your twin in the app, across all your keys.

Your data

These chat rooms don't appear in the app. They are part of your data export. Revoking a key keeps its rooms; deleting your account deletes them and your keys. Details are in our Privacy Policy. Questions: info@you2you.net.

you2you

Copyright © 2026. All rights reserved

  • Privacy Policy
  • General Terms & Conditions
  • Legal Note
  • Cookie Policy
Contact us
info@you2you.net
Get it on Google Play Download on the App Store

We use cookies to improve your experience and understand how you use our site. See our Cookie Policy.