Examples
Each runs as is with FORGE_API_KEY set, and runs on your credits.
Ask once and print the answer
curl -s https://api.forge.team/v1/conversations \
-H "Authorization: Bearer $FORGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"Summarise the plot of Hamlet in two sentences","reply":"required"}' \
| jq -r '.replies[].text'import os, requests
res = requests.post(
"https://api.forge.team/v1/conversations",
headers={"Authorization": f"Bearer {os.environ['FORGE_API_KEY']}"},
json={"text": "Summarise the plot of Hamlet in two sentences", "reply": "required"},
)
for reply in res.json()["replies"]:
print(reply["text"])Stream a reply as it is said
const res = await fetch("https://api.forge.team/v1/conversations", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FORGE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ text: "Write a short poem about steel", stream: true }),
});
const decoder = new TextDecoder();
let buffer = "";
for await (const chunk of res.body!) {
buffer += decoder.decode(chunk, { stream: true });
let end;
while ((end = buffer.indexOf("\n\n")) >= 0) {
const block = buffer.slice(0, end);
buffer = buffer.slice(end + 2);
const event = /^event: (.*)$/m.exec(block)?.[1];
const data = JSON.parse(/^data: (.*)$/m.exec(block)?.[1] ?? "null");
if (event === "message") console.log(data.text);
if (event === "done") console.log(`(${data.replies} replies)`);
}
}Start long work, then check on it
import os, time, requests
api = "https://api.forge.team/v1"
auth = {"Authorization": f"Bearer {os.environ['FORGE_API_KEY']}"}
started = requests.post(f"{api}/conversations", headers=auth, json={
"text": "Research the history of Damascus steel and write a one-page summary",
"reply": "none",
}).json()
while True:
status = requests.get(f"{api}/conversations/{started['conversationId']}", headers=auth).json()
if status["pendingGates"]:
print("The agent is waiting on you in the app:", status["pendingGates"][0]["prompt"])
break
if not status["busy"]:
print(status["lastAssistantText"])
break
time.sleep(10)Read a whole conversation
const api = "https://api.forge.team/v1";
const headers = { Authorization: `Bearer ${process.env.FORGE_API_KEY}` };
const id = process.argv[2];
const pages = [];
let before: string | null = null;
do {
const url = `${api}/conversations/${id}/messages?limit=200${before ? `&before=${before}` : ""}`;
const page = await (await fetch(url, { headers })).json();
pages.unshift(page.messages);
before = page.before;
} while (before);
for (const m of pages.flat()) console.log(`${m.role}: ${m.text}`);Follow conversations live
import WebSocket from "ws";
const ws = new WebSocket("wss://api.forge.team/v1/ws", {
headers: { Authorization: `Bearer ${process.env.FORGE_API_KEY}` },
});
ws.on("open", () => ws.send(JSON.stringify({ type: "send", id: "1", text: "Plan a three-day trip to Kyoto" })));
ws.on("message", (raw) => {
const frame = JSON.parse(raw.toString());
if (frame.type === "ack") ws.send(JSON.stringify({ type: "subscribe", conversationId: frame.conversationId }));
if (frame.type === "message") console.log(frame.text);
if (frame.type === "status") ws.close();
});A typed client
Generate one from the spec at https://api.forge.team/v1/openapi.json:
// npx openapi-typescript https://api.forge.team/v1/openapi.json -o forge.d.ts
// npm i openapi-fetch
import createClient from "openapi-fetch";
import type { paths } from "./forge";
const forge = createClient<paths>({
baseUrl: "https://api.forge.team/v1",
headers: { Authorization: `Bearer ${process.env.FORGE_API_KEY}` },
});
const { data } = await forge.GET("/conversations", { params: { query: { limit: 5 } } });
for (const c of data!.conversations) console.log(c.title);# pipx run openapi-python-client generate --url https://api.forge.team/v1/openapi.json
# then: pip install ./forge-api-client