Raqeto AI API — dokumentace
REST API pro AI agenty (OpenClaw, Claude Desktop, ChatGPT Custom GPT, Cline, Cursor, …), které potřebují číst a zapisovat data v Raqeto workspace.
- Base URL:
https://raqeto.com/api/ai/ - Auth: Bearer token (
raq_live_*) - Interaktivní schema:
/api/ai/docs/(Swagger UI) - OpenAPI JSON:
/api/ai/schema.json - Self-discovery:
/api/ai/me/(vyžaduje token) - Formát: JSON request/response, HTTP/1.1
Tato stránka je veřejná — nepotřebuješ přihlášení, aby ses na ni podíval. AI agent si ji může stáhnout a použít jako referenci.
1. Co API umí
| Resource | Co můžeš dělat |
|---|---|
| Klienti | Číst, vytvářet, upravovat, mazat |
| Projekty | Číst, vytvářet, upravovat, mazat |
| Úkoly | Číst, vytvářet, upravovat, mazat, hromadně přeskládat, nastavit prioritu |
| Briefy | Číst, vytvářet, upravovat, mazat |
| Komentáře | K úkolům a projektům, čtení + vytváření |
| Time tracking | Číst, vytvářet, upravovat (smazat jen pokud není vyfakturovaný) |
| Faktury | Číst, vytvářet, upravovat, označit jako odeslané |
| Kalendář | Číst, vytvářet, upravovat, mazat události + range query |
| Rozvrh (plán) | Číst, plánovat úkoly na konkrétní den, hromadně přeskládat pořadí v rozvrhu |
| Návrhy e-mailů | Vytvořit draft (AI-generovaný), číst, upravit tělo, označit odeslaný, smazat |
| Search | Cross-model fuzzy vyhledávání |
| Self-discovery | /me/ vrátí workspace + scope klíče + seznam endpointů |
Všechny dotazy jsou workspace-scoped — klíč vydaný ve workspace A nikdy neuvidí data workspace B.
2. Autentizace
2.1 Získání klíče
- Přihlas se do Raqeto a otevři Nastavení → Integrace → AI & API přístup.
- Klikni na Nový klíč, pojmenuj ho (např.
OpenClaw laptop), popiš a zaškrtni potřebné scopes. - Stiskni Vygenerovat klíč. Token se zobrazí jednou — zkopíruj ho ihned a ulož do secret manageru tvého agenta. Pozdější recovery není možná.
- Klíč je vázaný na workspace. Každý API request vrátí jen data z toho workspace.
2.2 Použití klíče
Klíč pošli v Authorization header jako Bearer token:
curl -H "Authorization: Bearer raq_live_abc123..." \
https://raqeto.com/api/ai/me/
2.3 Scope model
Scope určuje, co klíč smí. Ukládá se jako JSON list string tokenů. HTTP metoda se mapuje na read (GET/HEAD/OPTIONS) nebo write (POST/PUT/PATCH/DELETE).
| Token | Efekt |
|---|---|
read |
Čtení všech resource |
write |
Zápis všech resource |
tasks:read |
Čtení jen úkolů |
tasks:write |
Vytvoření / úprava / smazání úkolů |
projects:read |
Čtení projektů |
projects:write |
Vytvoření / úprava / smazání projektů |
clients:read |
Čtení klientů |
clients:write |
Vytvoření / úprava / smazání klientů |
briefs:read |
Čtení briefů |
briefs:write |
Vytvoření / úprava / smazání briefů |
comments:read |
Čtení komentářů |
comments:write |
Vytváření komentářů |
time:read |
Čtení time entries |
time:write |
Vytvoření / úprava time entries (DELETE blokováno pro vyfakturované) |
invoices:read |
Čtení faktur |
invoices:write |
Vytváření / úpravy faktur, označení jako odeslané |
calendar:read |
Čtení událostí kalendáře |
calendar:write |
Vytvoření / úprava / smazání událostí |
Backwards compatibility: Klíč bez scopes (legacy, vytvořený před tímto modelem) má plný read + write přístup.
Doporučení: Vytvoř jeden klíč pro čtení (read) a druhý pro zápis, oba pro různé účely. Revokuj nepoužívané.
3. Kompletní seznam endpointů
| Metoda | Path | Popis | Scope |
|---|---|---|---|
| GET | /me/ |
Self-discovery | libovolný |
| GET | /search/?q=&types=tasks,projects |
Cross-model search | <resource>:read |
| GET | /tasks/ |
Seznam úkolů | tasks:read |
| POST | /tasks/ |
Vytvoření úkolu | tasks:write |
| GET | /tasks/{id}/ |
Detail úkolu | tasks:read |
| PATCH | /tasks/{id}/ |
Částečná úprava | tasks:write |
| DELETE | /tasks/{id}/ |
Smazání | tasks:write |
| POST | /tasks/{id}/set-priority/ |
Shortcut pro nastavení priority | tasks:write |
| POST | /tasks/reorder/ |
Hromadná změna pořadí | tasks:write |
| GET/POST/PATCH/DELETE | /projects/ |
Projekty CRUD | projects:read/write |
| GET/POST/PATCH/DELETE | /clients/ |
Klienti CRUD | clients:read/write |
| GET/POST/PATCH/DELETE | /briefs/ |
Briefy CRUD | briefs:read/write |
| GET/POST/PATCH/DELETE | /task-comments/ |
Komentáře k úkolům | comments:read/write |
| GET/POST/PATCH/DELETE | /project-comments/ |
Komentáře k projektům | comments:read/write |
| GET/POST/PATCH/DELETE | /time-entries/ |
Time tracking CRUD | time:read/write |
| GET/POST/PATCH | /invoices/ |
Faktury (DELETE není povoleno) | invoices:read/write |
| POST | /invoices/{id}/send/ |
Označit jako odeslaná | invoices:write |
| GET/POST/PATCH/DELETE | /calendar-events/ |
Kalendář CRUD | calendar:read/write |
| GET/POST/PATCH/DELETE | /schedule-entries/ |
Denní rozvrh (task × den × pozice) | schedule:read/write |
| POST | /schedule-entries/reorder/ |
Hromadná změna pořadí v rozvrhu | schedule:write |
| GET/POST/PATCH/DELETE | /emails/ |
AI-draft e-mailů | emails:read/write |
Plnou JSON schema s request/response shapes najdeš v Swagger UI.
3.1 Společné query parametry
Každý list endpoint podporuje:
- Stránkování:
?page=N, default page size 25,countv odpovědi - Filtrování: dokumentované
filterset_fieldsv Swagger (např.?status=todo&priority=high) - Search:
?search=...přessearch_fields - Řazení:
?ordering=-created_at - Kalendář range:
?start__gte=2026-04-01&end__lte=2026-04-30
3.2 Poznámky k zápisu
- Time entries vytvořené přes API jsou přiřazeny uživateli, který vydal klíč (
AIKey.created_by); fallback je workspace owner. - Kalendářové události používají stejné pravidlo pro pole
user. - Faktury:
numberse generuje automaticky — neposílej ho v body. - TimeEntry DELETE: nelze smazat záznam, který je napojený na fakturu (
invoiceFK set).
4. Příklady — cURL
4.1 Self-discovery
curl -H "Authorization: Bearer $RAQETO_TOKEN" \
https://raqeto.com/api/ai/me/
Response:
{
"workspace": {
"id": "a1b2c3...",
"name": "Freelance",
"slug": null
},
"key": {
"id": "d4e5f6...",
"name": "OpenClaw laptop",
"scopes": ["read", "write"],
"last_used_at": "2026-04-13T11:42:00Z"
},
"endpoints": {
"tasks": "/api/ai/tasks/",
"projects": "/api/ai/projects/",
"...": "..."
}
}
4.2 Seznam úkolů
curl -H "Authorization: Bearer $RAQETO_TOKEN" \
"https://raqeto.com/api/ai/tasks/?status=todo&priority=high&ordering=-created_at"
4.3 Vytvoření úkolu
curl -X POST https://raqeto.com/api/ai/tasks/ \
-H "Authorization: Bearer $RAQETO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Zavolat Jardovi ohledně briefu",
"project": "a1b2c3d4-...",
"priority": "high",
"deadline": "2026-04-20"
}'
4.4 Search
curl -H "Authorization: Bearer $RAQETO_TOKEN" \
"https://raqeto.com/api/ai/search/?q=brief&types=tasks,projects,clients"
4.5 Kalendář — události pro tento týden
curl -H "Authorization: Bearer $RAQETO_TOKEN" \
"https://raqeto.com/api/ai/calendar-events/?start__gte=2026-04-13&end__lte=2026-04-20"
4.6 Time entry — ruční záznam
curl -X POST https://raqeto.com/api/ai/time-entries/ \
-H "Authorization: Bearer $RAQETO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"project": "a1b2c3d4-...",
"description": "Review klientského briefu",
"started_at": "2026-04-13T10:00:00+02:00",
"ended_at": "2026-04-13T11:30:00+02:00",
"duration_hours": "1.5",
"is_billable": true
}'
4.7 Faktura — vytvoření + označit odeslanou
# Vytvoření (number se doplní automaticky)
curl -X POST https://raqeto.com/api/ai/invoices/ \
-H "Authorization: Bearer $RAQETO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"client": "...",
"project": "...",
"issued_date": "2026-04-13",
"due_date": "2026-04-27",
"tax_rate": "21",
"currency": "CZK"
}'
# Označit jako odeslanou
curl -X POST https://raqeto.com/api/ai/invoices/<id>/send/ \
-H "Authorization: Bearer $RAQETO_TOKEN"
4.8 Rozvrh — naplánovat úkol na den
# Přidat úkol do rozvrhu (position se dopočítá na konec dne)
curl -X POST https://raqeto.com/api/ai/schedule-entries/ \
-H "Authorization: Bearer $RAQETO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"task": "a1b2c3d4-...",
"date": "2026-04-21"
}'
# Vypsat rozvrh pro rozsah dní
curl -H "Authorization: Bearer $RAQETO_TOKEN" \
"https://raqeto.com/api/ai/schedule-entries/?date_from=2026-04-20&date_to=2026-04-26"
4.9 Rozvrh — hromadné přeskupení pořadí
# AI přeskládá úkoly v rámci dne (nebo napříč dny).
# Pošli seznam { id, position }; position je 0-based index.
curl -X POST https://raqeto.com/api/ai/schedule-entries/reorder/ \
-H "Authorization: Bearer $RAQETO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [
{"id": "uuid-a", "position": 0},
{"id": "uuid-b", "position": 1},
{"id": "uuid-c", "position": 2}
]
}'
Response: {"updated": 3} — počet úspěšně přeorderovaných záznamů.
Záznamy mimo workspace klíče jsou tiše přeskočeny (nepočítají se do updated).
4.10 Návrhy e-mailů — vytvoření draftu
Externí automatizace (mailbox watcher, webhook z formuláře) POSTne příchozí e-mail.
Server založí EmailDraft ve stavu generating, roztočí AI konverzaci a OpenClaw
vygeneruje návrh odpovědi. Uživatel ho uvidí v dashboardu v sekci Psaní e-mailů.
Nic se nikdy neodesílá — výstup je výhradně na zkopírování.
curl -X POST https://raqeto.com/api/ai/emails/ \
-H "Authorization: Bearer $RAQETO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mode": "reply",
"source_text": "Dobrý den, chtěl bych se zeptat…",
"source_from": "klient@firma.cz",
"source_subject": "Dotaz na nabídku",
"client": "a1b2c3d4-...",
"project": "e5f6g7h8-..."
}'
Odpověď obsahuje id, status="generating" a ai_conversation. Jakmile OpenClaw
odpoví, status přejde na pending a v poli body bude finální text.
4.11 Návrhy e-mailů — list + detail + update
# Filtrace a search
curl -H "Authorization: Bearer $RAQETO_TOKEN" \
"https://raqeto.com/api/ai/emails/?status=pending&project=<uuid>&search=nabídka"
# Detail jednoho draftu (zjištění přechodu generating → pending)
curl -H "Authorization: Bearer $RAQETO_TOKEN" \
"https://raqeto.com/api/ai/emails/<id>/"
# Přepsat tělo / označit odeslané
curl -X PATCH https://raqeto.com/api/ai/emails/<id>/ \
-H "Authorization: Bearer $RAQETO_TOKEN" \
-H "Content-Type: application/json" \
-d '{"body": "Upravený text e-mailu", "status": "sent"}'
# Smazat spam / omyl (pro "hotovo" radši PATCH status=sent)
curl -X DELETE https://raqeto.com/api/ai/emails/<id>/ \
-H "Authorization: Bearer $RAQETO_TOKEN"
Podporované filtry: status, mode, project, client. Search (?search=…) hledá v source_text, body, subject.
5. Příklady — Python
Univerzální klient, který funguje v libovolném Python skriptu nebo OpenClaw skillu:
import os
import httpx
BASE = "https://raqeto.com/api/ai"
TOKEN = os.environ["RAQETO_TOKEN"]
client = httpx.Client(
base_url=BASE,
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=15.0,
)
def me():
return client.get("/me/").json()
def list_tasks(status=None, project=None, assignee=None):
params = {}
if status: params["status"] = status
if project: params["project"] = project
if assignee: params["assignee"] = assignee
return client.get("/tasks/", params=params).json()
def create_task(title, project, priority="medium", deadline=None, description=""):
payload = {
"title": title,
"project": project,
"priority": priority,
"description": description,
}
if deadline:
payload["deadline"] = deadline
return client.post("/tasks/", json=payload).json()
def search(query, types="tasks,projects,clients"):
return client.get("/search/", params={"q": query, "types": types}).json()
def upcoming_events(days=7):
import datetime
start = datetime.date.today().isoformat()
end = (datetime.date.today() + datetime.timedelta(days=days)).isoformat()
return client.get(
"/calendar-events/",
params={"start__gte": start, "end__lte": end, "ordering": "start"},
).json()
def log_time(project, started_at, ended_at, duration_hours, description=""):
return client.post("/time-entries/", json={
"project": project,
"started_at": started_at,
"ended_at": ended_at,
"duration_hours": duration_hours,
"description": description,
"is_billable": True,
}).json()
if __name__ == "__main__":
print("Workspace:", me()["workspace"]["name"])
print("Úkoly dnes:", len(list_tasks(status="todo")["results"]))
5a. Raqeto chat daemon — nejjednodušší cesta k chat bubble
Doporučená cesta pro uživatele, kteří chtějí chat bubble v dashboardu fungující do 5 minut a bez nutnosti řešit OpenClaw plugin SDK.
Chat daemon je malý Node CLI (@raqeto/chat-daemon), který běží na tvém laptopu, polluje Raqeto inbox a volá tvůj LLM přímo — Anthropic, OpenAI, Ollama nebo LM Studio. Žádný OpenClaw mezi tím.
Instalace
Předpoklady:
- Node ≥ 20 (používá native fetch)
- API klíč pro zvoleného providera (Anthropic / OpenAI) nebo lokální Ollama / LM Studio
1. Vytvoř AIKey v Raqeto
Nastavení → Integrace → AI & API přístup → Nový klíč, zaškrtni chat:poll + chat:reply, Vygenerovat, zkopíruj token.
2. Nainstaluj daemon
npm install -g https://raqeto.com/api/ai/raqeto-chat-daemon.tgz
3. Spusť
raqeto-chat-daemon \
--token raq_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx \
--provider anthropic \
--api-key sk-ant-...
Nebo přes env vars:
export RAQETO_TOKEN=raq_live_...
export ANTHROPIC_API_KEY=sk-ant-...
raqeto-chat-daemon --provider anthropic
4. Otestuj bubble
Otevři https://raqeto.com/dashboard/, klikni na bubble vpravo dole, napiš "ahoj". Do ~3 s by měl dorazit reply.
Vypnutí: Ctrl+C.
Podporované providery
--provider |
Default model | Potřebuje API klíč? | Default base URL |
|---|---|---|---|
anthropic |
claude-sonnet-4-5 |
ano (ANTHROPIC_API_KEY) |
https://api.anthropic.com |
openai |
gpt-4o-mini |
ano (OPENAI_API_KEY) |
https://api.openai.com |
ollama |
llama3.2 |
ne | http://localhost:11434 |
lmstudio |
local-model |
volitelně | http://localhost:1234 |
CLI options
Všechny jsou volitelné, CLI > env var > config file.
| Flag | Env var | Popis |
|---|---|---|
--token |
RAQETO_TOKEN |
Povinné. Raqeto AIKey (raq_live_...) |
--provider |
RAQETO_PROVIDER |
anthropic / openai / ollama / lmstudio (default anthropic) |
--model |
RAQETO_MODEL |
Model ID — default per provider (viz tabulka) |
--api-key |
RAQETO_API_KEY nebo ANTHROPIC_API_KEY / OPENAI_API_KEY |
API klíč providera |
--api-base |
RAQETO_API_BASE |
Přepsat base URL (proxy, self-hosted) |
--base-url |
RAQETO_BASE_URL |
Raqeto instance (default https://raqeto.com) |
--poll-interval |
RAQETO_POLL_INTERVAL |
Inbox poll interval v ms (default 3000, min 1000) |
--system-prompt |
RAQETO_SYSTEM_PROMPT |
Přepsat default system prompt (česky, CRM kontext) |
--max-history |
RAQETO_MAX_HISTORY |
Max zpráv z konverzace posílaných do LLM (default 20) |
--verbose |
RAQETO_VERBOSE=1 |
Logovat každý poll tick |
Config file (volitelné)
Pokud nechceš psát flagy při každém startu, vytvoř ~/.raqeto/chat-daemon.json:
{
"token": "raq_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"provider": "anthropic",
"apiKey": "sk-ant-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"model": "claude-sonnet-4-5",
"pollIntervalMs": 3000,
"maxHistory": 20
}
Pak stačí spustit raqeto-chat-daemon bez argumentů. Pro jiný config path použij RAQETO_CONFIG_FILE=/path/to/config.json.
Jak to funguje
- Daemon každé ~3 s volá
GET /api/ai/chat/inbox/s Bearer tokenem - Pro každou novou user zprávu stáhne plnou historii konverzace přes
GET /api/ai/chat/history/?conversation_id=... - Pošle
{system prompt, history, latest message}do zvoleného providera - Reply POST-uje na
POST /api/ai/chat/outbox/ - Widget v dashboardu reply vybere při dalším pollingu (~2 s)
Daemon je stateless — celá historie konverzace žije v Raqeto DB. Můžeš ho kdykoliv zastavit a restartovat, nic se neztratí.
Spuštění jako systemd service (Linux)
~/.config/systemd/user/raqeto-chat-daemon.service:
[Unit]
Description=Raqeto chat daemon
After=network-online.target
[Service]
ExecStart=/usr/bin/env raqeto-chat-daemon
Environment="RAQETO_TOKEN=raq_live_..."
Environment="ANTHROPIC_API_KEY=sk-ant-..."
Restart=on-failure
[Install]
WantedBy=default.target
systemctl --user daemon-reload
systemctl --user enable --now raqeto-chat-daemon
journalctl --user -u raqeto-chat-daemon -f
Launchd na macOS
~/Library/LaunchAgents/com.raqeto.chat-daemon.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.raqeto.chat-daemon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/raqeto-chat-daemon</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>RAQETO_TOKEN</key><string>raq_live_...</string>
<key>ANTHROPIC_API_KEY</key><string>sk-ant-...</string>
</dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key><string>/tmp/raqeto-chat-daemon.log</string>
<key>StandardErrorPath</key><string>/tmp/raqeto-chat-daemon.log</string>
</dict>
</plist>
launchctl load ~/Library/LaunchAgents/com.raqeto.chat-daemon.plist
tail -f /tmp/raqeto-chat-daemon.log
Troubleshooting
| Co vidíš | Příčina | Oprava |
|---|---|---|
missing --token |
Token nepředán | --token raq_live_... nebo export RAQETO_TOKEN=... |
authentication failed (401) |
Token revokovaný / špatně opsaný | Vytvoř nový v Raqeto Settings |
authentication failed (403) |
Scope chat:poll nebo chat:reply chybí |
Settings → Upravit práva → zaškrtnout oba |
Anthropic 401 |
Špatný ANTHROPIC_API_KEY |
console.anthropic.com → nový klíč |
Ollama ECONNREFUSED |
Ollama neběží | ollama serve |
| Bubble se v dashboardu nezobrazí | Žádný AIKey se chat scopes | Vytvoř klíč |
poll failed ale pak connected |
Dočasná síť — daemon retry-uje | Nech běžet |
Odpovědi Chyba při zpracování zprávy |
LLM provider vrátil error | Podívej se do stderr daemonu |
5b. OpenClaw channel plugin — chat bubble v Raqeto
Plná integrace, která udělá z Raqeto dashboardu chat rozhraní napojené na tvůj lokální OpenClaw (a tím pádem na tvůj vlastní LLM — Claude, GPT, Ollama, cokoli). Raqeto sám o sobě žádného LLM providera nevolá.
Jak to funguje
- Uživatel napíše zprávu do chat bubble vpravo dole v Raqeto dashboardu
- Raqeto backend ji uloží jako pending user message (žádné cloud volání)
- Na tvém laptopu běží OpenClaw s nainstalovaným
@raqeto/openclaw-channelpluginem - Plugin polluje
GET /api/ai/chat/inbox/(~3 s) a vyzvedne zprávu - OpenClaw ji pošle do tvého nakonfigurovaného LLM
- Odpověď se vrátí přes
POST /api/ai/chat/outbox/ - Bubble v prohlížeči odpověď zachytí při dalším polling tiku (~2 s)
Celá AI vrstva žije u tebe. Raqeto je jen message queue.
Instalace pluginu — krok za krokem
Celá instalace zabere ~3 minuty a nepotřebuje Node, Git ani build tooling — jen běžící OpenClaw.
Předpoklady
- OpenClaw ≥ 2026.4.12 nainstalovaný na tvém stroji. Starší verze (2026.4.2 a níže) mají bug v
plugin-sdk/channel-coreexports layoutu a plugin se na nich nenačte (Cannot find module ... root-alias.cjs/channel-core). Upgrade:bash npm install -g openclaw@latest openclaw --version # mělo by ukázat 2026.4.12 nebo novější - OpenClaw má nakonfigurovaný LLM provider (Anthropic / OpenAI / Ollama / LM Studio …). Raqeto sám žádný LLM nevolá — OpenClaw musí mít čím odpovídat.
- Přihlášený účet v Raqeto (
https://raqeto.com).
Krok 1 — Vytvoř AIKey s chat scopes
- V Raqeto přejdi na Nastavení → Integrace → AI & API přístup
- Klikni na Nový klíč
- Název:
OpenClaw laptop(nebo jak chceš) - Scopes: zaškrtni
chat:pollachat:reply(ostatní nech odškrtnuté, když plugin bude dělat jen chat) - Vygenerovat klíč
- Hned zkopíruj token (
raq_live_...) — v seznamu ho uvidíš už jen jako hvězdičky, ale kopírovací tlačítko pořád funguje, kdybys ho potřeboval znovu
Krok 2 — Nainstaluj plugin jedním příkazem
openclaw plugins install https://raqeto.com/api/ai/openclaw-plugin.tgz
OpenClaw stáhne předkompilovaný tarball (@raqeto/openclaw-channel, ~10 kB) z Raqeto CDN a nainstaluje ho. Žádný git clone, žádný npm install, žádný build.
Ověř:
openclaw plugins list # uvidíš raqeto v seznamu
openclaw plugins info raqeto # detail + stav + verzi (mělo by být 0.1.3+)
Pokud
plugins installselže sinvalid manifestnebominHostVersion not satisfied, máš starou OpenClaw. Upgraduj (npm install -g openclaw@latest) a zkus znovu.
Krok 3 — Přidej config do ~/.openclaw/openclaw.json
Otevři (nebo vytvoř) soubor ~/.openclaw/openclaw.json a přidej blok channels.raqeto:
{
"channels": {
"raqeto": {
"baseUrl": "https://raqeto.com",
"token": "raq_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"pollIntervalMs": 3000,
"dmSecurity": "allowlist",
"allowFrom": []
}
}
}
Kdyby už tam channels blok existoval (např. máš Discord nebo Telegram), jen přidej raqeto dovnitř — ne jako samostatný top-level klíč vedle channels.
| Pole | Povinné | Default | Popis |
|---|---|---|---|
baseUrl |
ne | https://raqeto.com |
Self-hosteři přepíší na svoji doménu |
token |
ano | — | Bearer AIKey se scopes chat:poll + chat:reply |
pollIntervalMs |
ne | 3000 |
Jak často poll inboxu. Min 1000, max 60000 |
dmSecurity |
ne | allowlist |
allowlist / blocklist / open |
allowFrom |
ne | [] |
Raqeto user UUIDs / emaily. Prázdný + allowlist = vše blok |
Pravidla JSONu: klíče v uvozovkách, žádná čárka navíc na konci posledního klíče, žádné komentáře.
Krok 4 — Restartuj OpenClaw gateway
openclaw gateway restart
V logu (openclaw logs --follow) by mělo být:
[plugin:raqeto] loaded
[plugin:raqeto] polling https://raqeto.com/api/ai/chat/inbox/ every 3000 ms
Krok 5 — Otestuj bubble
- Otevři / refreshni
https://raqeto.com/dashboard/v prohlížeči (musíš být přihlášený) - Vpravo dole uvidíš gradient bubble (indigo → fialová)
- Tečka v header bubble zezelená = OpenClaw aktivně polluje
- Klikni na bubble → drawer se rozbalí
- Napiš
ahoj - Do ~3–5 s by měla přijít odpověď z tvého OpenClaw LLM
Upgrade pluginu
Když vyjde nová verze, stačí:
openclaw plugins remove raqeto
openclaw plugins install https://raqeto.com/api/ai/openclaw-plugin.tgz
openclaw gateway restart
URL je stabilní — vždycky serveruje aktuální verzi z static/downloads/raqeto-openclaw-channel-<nejvyšší>.tgz.
Jednotlivé endpointy
| Metoda | Path | Co dělá | Scope |
|---|---|---|---|
| GET | /api/ai/chat/inbox/ |
Vyzvedne pending user zprávy + označí jako delivered | chat:poll |
| POST | /api/ai/chat/outbox/ |
Pošle assistant odpověď zpátky | chat:reply |
Tělo POST /outbox/:
{
"conversation_id": "uuid-z-inboxu",
"text": "Máš 3 úkoly na dnes...",
"tokens_input": 120,
"tokens_output": 45
}
Troubleshooting
| Co vidíš | Co je špatně | Oprava |
|---|---|---|
Cannot find module ... root-alias.cjs/channel-core |
OpenClaw < 2026.4.12 (rozbitý SDK exports layout) | npm install -g openclaw@latest, pak reinstall pluginu a restart gateway |
unknown channel id: raqeto při startu |
Stará verze pluginu (< 0.1.3) | openclaw plugins remove raqeto && openclaw plugins install https://raqeto.com/api/ai/openclaw-plugin.tgz |
openclaw plugins install vrací 404 |
Typo v URL | Zkopíruj URL přesně z https://raqeto.com/api/ai/guide/ |
plugins install → invalid manifest |
Host je moc starý, neumí openclaw.extensions shape |
Upgrade OpenClaw (npm install -g openclaw@latest) |
minHostVersion not satisfied |
OpenClaw < 2026.4.12 | Upgrade OpenClaw |
| Bubble se v dashboardu nezobrazí | Klíč neexistuje / chybí chat:poll + chat:reply |
Settings → Upravit práva → zaškrtnout oba chat scopes |
| Bubble je, ale hlásí "OpenClaw neodpovídá" | Plugin neběží / špatný token / OpenClaw nemá LLM | Zkontroluj openclaw logs --follow a config |
| Odpovědi přicházejí pomalu (10+ s) | pollIntervalMs je moc velký |
Sniž na 2000 v openclaw.json |
| 401 v OpenClaw logu | Token revokovaný / špatně opsaný | Vytvoř nový v Raqeto Settings, vlož do configu, restart gateway |
| 403 missing chat:poll | Scope na klíči chybí | Settings → Upravit práva → zaškrtnout chat:poll + chat:reply |
| 429 rate limit | Překročený per-user hourly limit | Počkej hodinu nebo zvyš RAQETO_CHAT_RATE_LIMIT_PER_HOUR na backendu |
ECONNREFUSED v OpenClaw logu |
baseUrl je nedostupný |
Ověř baseUrl — default https://raqeto.com |
| Zprávy dorazí, ale reply nikdy | OpenClaw nemá nastavený LLM provider | V OpenClaw nastav Anthropic / OpenAI / Ollama provider |
Limity v1
- Single-user per klíč: jeden AIKey = jeden Raqeto uživatel. Pro tým si každý vytvoří vlastní klíč.
- Bez media: text-only v první verzi. Obrázky / přílohy jsou ignorované.
- Bez typing indicatoru: bubble neukazuje "agent píše".
- Bez edit/delete zpráv: po odeslání reply ji nelze změnit přes plugin.
Doporučený prompt pro tvůj OpenClaw LLM
Dej ho do OpenClaw system prompt configu, ať agent ví, že obsluhuje Raqeto chat:
Jsi asistent pro freelancery v CRM Raqeto. Uživatel ti píše z chat bubble
v Raqeto dashboardu. Komunikuj česky, stručně, použij markdown tabulky
pro výčty. Pro destruktivní akce si vyžádej explicitní potvrzení.
Pokud potřebuješ číst data z Raqeto, máš k dispozici raqeto-skill
(REST API přes /api/ai/*). Auth: stejný bearer token, co používáš pro
tento channel. Before calling any write endpoint, confirm with the user.
6. OpenClaw — custom skill setup (read/write REST přístup)
OpenClaw je lokální agent framework, který běží na tvém počítači a volá externí služby přes skills. Aby měl přístup do Raqeto, vytvoříš custom skill.
6.1 Získej AIKey
Viz sekce 2.1. Doporučené scopes: read, write (začni plným přístupem, později zúžíš).
6.2 Ulož token do OpenClaw secrets
Otevři / vytvoř ~/.openclaw/secrets (nebo ekvivalent dle tvé verze OpenClaw) a přidej:
RAQETO_TOKEN=raq_live_xxxxxxxxxxxxxxxxxxxxxxxxx
Nikdy neukládej token do kódu skillu, do Gitu, nebo do OpenClaw prompt historie.
6.3 Vytvoř skill soubor
Zkopíruj níže uvedený soubor jako ~/.openclaw/skills/raqeto.py (adresa se může lišit — viz docs.openclaw.ai):
"""Raqeto skill for OpenClaw.
Exposes Raqeto CRM as a set of agent tools. Requires RAQETO_TOKEN
in the environment (loaded from ~/.openclaw/secrets by OpenClaw).
"""
import os
import httpx
BASE = "https://raqeto.com/api/ai"
TOKEN = os.environ.get("RAQETO_TOKEN", "")
if not TOKEN:
raise RuntimeError("RAQETO_TOKEN missing — add it to ~/.openclaw/secrets")
_client = httpx.Client(
base_url=BASE,
headers={"Authorization": f"Bearer {TOKEN}"},
timeout=15.0,
)
def _get(path, **params):
r = _client.get(path, params=params)
r.raise_for_status()
return r.json()
def _post(path, **data):
r = _client.post(path, json=data)
r.raise_for_status()
return r.json()
def raqeto_whoami():
"""Return the workspace and key metadata."""
return _get("/me/")
def raqeto_list_tasks(status: str = "", project: str = "", assignee: str = "", limit: int = 20):
"""List tasks in the current workspace. Optional filters."""
params = {"page_size": limit}
if status: params["status"] = status
if project: params["project"] = project
if assignee: params["assignee"] = assignee
return _get("/tasks/", **params)
def raqeto_create_task(title: str, project: str, priority: str = "medium",
deadline: str = "", description: str = ""):
"""Create a task. ``project`` is the project UUID, ``deadline`` is ISO date."""
payload = {"title": title, "project": project, "priority": priority}
if deadline: payload["deadline"] = deadline
if description: payload["description"] = description
return _post("/tasks/", **payload)
def raqeto_set_task_priority(task_id: str, priority: str):
"""Shortcut: set priority on a task (low | medium | high | urgent)."""
return _post(f"/tasks/{task_id}/set-priority/", priority=priority)
def raqeto_list_projects(status: str = "", limit: int = 20):
params = {"page_size": limit}
if status: params["status"] = status
return _get("/projects/", **params)
def raqeto_list_clients(active: bool = True, limit: int = 20):
return _get("/clients/", is_active=active, page_size=limit)
def raqeto_search(query: str, types: str = "tasks,projects,clients"):
"""Cross-model search across tasks, projects, clients, briefs, calendar, invoices."""
return _get("/search/", q=query, types=types)
def raqeto_upcoming_events(days: int = 7):
"""Calendar events in the next N days."""
import datetime
start = datetime.date.today().isoformat()
end = (datetime.date.today() + datetime.timedelta(days=days)).isoformat()
return _get("/calendar-events/", **{"start__gte": start, "end__lte": end, "ordering": "start"})
def raqeto_log_time(project: str, started_at: str, ended_at: str,
duration_hours: str, description: str = "", billable: bool = True):
"""Log a time entry. Datetimes must be ISO 8601 with timezone."""
return _post("/time-entries/",
project=project,
started_at=started_at,
ended_at=ended_at,
duration_hours=duration_hours,
description=description,
is_billable=billable)
def raqeto_sum_hours_this_week():
"""Return billable + total hours tracked in the current ISO week (current user)."""
import datetime
today = datetime.date.today()
monday = today - datetime.timedelta(days=today.weekday())
sunday = monday + datetime.timedelta(days=6)
entries = _get("/time-entries/", **{
"started_at__gte": f"{monday}T00:00:00Z",
"started_at__lte": f"{sunday}T23:59:59Z",
"ended_at__isnull": False,
"page_size": 200,
})
total = sum(float(e.get("duration_hours", 0) or 0) for e in entries.get("results", []))
billable = sum(
float(e.get("duration_hours", 0) or 0)
for e in entries.get("results", []) if e.get("is_billable")
)
return {"week_start": str(monday), "week_end": str(sunday),
"total_hours": total, "billable_hours": billable}
# -------------------- Denní rozvrh (plán úkolů na konkrétní dny) --------------------
def raqeto_list_schedule(date_from: str = "", date_to: str = ""):
"""List schedule entries in a date range (ISO dates).
Each entry carries ``task_title``, ``project_name``, ``client_name``
and ``completed`` — no extra lookups needed.
"""
params = {}
if date_from: params["date_from"] = date_from
if date_to: params["date_to"] = date_to
return _get("/schedule-entries/", **params)
def raqeto_schedule_task(task: str, date: str, position: int = 0):
"""Plan a task for a specific day. Position 0 = append to end of day."""
payload = {"task": task, "date": date}
if position: payload["position"] = position
return _post("/schedule-entries/", **payload)
def raqeto_unschedule(entry_id: str):
"""Remove a task from the schedule (entry id = schedule entry UUID)."""
r = _client.delete(f"/schedule-entries/{entry_id}/")
r.raise_for_status()
return {"ok": True}
def raqeto_reorder_schedule(items: list):
"""Bulk reorder tasks in the schedule in one atomic call.
``items`` is a list of dicts: ``[{"id": "<uuid>", "position": 0}, ...]``.
Returns ``{"updated": N}``.
"""
return _post("/schedule-entries/reorder/", items=items)
# -------------------- Návrhy e-mailů (AI composer) --------------------
def raqeto_create_email_draft(source_text: str, mode: str = "reply",
subject: str = "", instructions: str = "",
client: str = "", project: str = "", task: str = ""):
"""Create an email draft. Server spins up an AI conversation that
generates the draft body asynchronously.
``mode`` is one of ``reply`` (odpověď na příchozí mail), ``compose``
(úplně nový mail podle bodů) or ``rewrite`` (přeformulovat text).
``source_text`` = příchozí mail (reply) / body points (compose) /
existing draft to rewrite. ``client`` / ``project`` / ``task`` jsou
volitelné UUID reference pro kontext.
Returns the new ``EmailDraft`` JSON with ``status='generating'``.
Poll ``raqeto_get_email_draft(id)`` until ``status='pending'`` to
see the final body.
"""
payload = {"mode": mode, "source_text": source_text}
if subject: payload["subject"] = subject
if instructions: payload["instructions"] = instructions
if client: payload["client"] = client
if project: payload["project"] = project
if task: payload["task"] = task
return _post("/emails/", **payload)
def raqeto_list_email_drafts(status: str = "", project: str = "",
client: str = "", search: str = "",
limit: int = 20):
"""List email drafts. Filter by ``status`` (generating|pending|sent|...),
``project`` UUID, ``client`` UUID, or free-text ``search``.
"""
params = {"page_size": limit}
if status: params["status"] = status
if project: params["project"] = project
if client: params["client"] = client
if search: params["search"] = search
return _get("/emails/", **params)
def raqeto_get_email_draft(draft_id: str):
"""Fetch one draft — use this to poll ``status`` (generating → pending)
and read the finalized ``body``.
"""
return _get(f"/emails/{draft_id}/")
def raqeto_update_email_draft(draft_id: str, body: str = "",
subject: str = "", status: str = ""):
"""Partial update — typically used to overwrite ``body`` after user
edits, or set ``status='sent'`` after the user hits send externally.
"""
payload = {}
if body: payload["body"] = body
if subject: payload["subject"] = subject
if status: payload["status"] = status
r = _client.patch(f"/emails/{draft_id}/", json=payload)
r.raise_for_status()
return r.json()
def raqeto_delete_email_draft(draft_id: str):
"""Delete a draft. Only for spam / mistakes — for "finished" drafts
prefer ``raqeto_update_email_draft(id, status='sent')`` so the record
stays in the audit trail.
"""
r = _client.delete(f"/emails/{draft_id}/")
r.raise_for_status()
return {"ok": True}
6.4 Zaregistruj skill v OpenClaw
Přesný postup závisí na verzi OpenClaw. Obecně:
- Zkopíruj soubor do adresáře, který OpenClaw skenuje na startu (
~/.openclaw/skills/) - Restartuj OpenClaw daemon / sezení
- V chatu s agentem můžeš říct: "Use the raqeto_whoami tool to check the connection"
- Nebo: "Use raqeto_list_tasks to show my todos"
Přesné kroky viz docs.openclaw.ai.
6.5 Smoke test
Před tím, než začneš skill používat v OpenClaw, otestuj token z shellu:
export RAQETO_TOKEN=raq_live_...
curl -H "Authorization: Bearer $RAQETO_TOKEN" https://raqeto.com/api/ai/me/
Pokud dostaneš JSON s názvem tvého workspace, token funguje a skill bude taky fungovat.
6.6 Doporučený prompt pro OpenClaw agenta
Jsi asistent pro správu CRM Raqeto. Máš k dispozici skills s prefixem
raqeto_* — použij je pro čtení a zápis dat ve workspace uživatele.
Co umíš:
• Klienti, projekty, úkoly — číst, zakládat, upravovat, řadit
• Time tracking — vypsat týden, zapsat záznam
• Kalendář — nadcházející události, plánování
• Denní rozvrh — raqeto_list_schedule / raqeto_schedule_task /
raqeto_reorder_schedule (bulk přeskládání)
• Návrhy e-mailů — raqeto_create_email_draft (režimy reply / compose /
rewrite), raqeto_list_email_drafts, raqeto_get_email_draft (poll
dokud status není 'pending'), raqeto_update_email_draft (uložit
úpravy nebo označit sent), raqeto_delete_email_draft
• Search — raqeto_search pro cross-model fuzzy hledání
Pro destruktivní akce (smazání, přepočet faktury) si nejprve vyžádej
textové potvrzení. Komunikuj česky, stručně, výčty v markdown tabulkách.
Pozn.: Nic se neodesílá automaticky — e-mailové návrhy uživatel
ručně kopíruje do svého klienta a označí jako sent.
7. Další AI klienti
7.1 Claude Desktop (manuálně bez MCP)
Claude Desktop zatím nepodporuje libovolné HTTP tool volání bez MCP wrapperu. Dokud nebude k dispozici Raqeto MCP server, použij:
- Custom Python helper (viz výše)
- Nebo Claude Projects s API docs vloženými jako kontext
7.2 ChatGPT Custom GPT / Actions
V GPT Builder otevři Actions → Authentication:
- Authentication Type: API Key
- API Key: vlož svůj
raq_live_...token - Auth Type: Bearer
Potom importuj schema z:
https://raqeto.com/api/ai/schema.json
GPT Builder automaticky vygeneruje všechny Actions z OpenAPI schema.
7.3 Cursor / Cline / Windsurf
Tyto IDE-agent klienti obvykle podporují volání přes HTTP. Použij Python snippet z sekce 5 jako helper v tvém workspace.
7.4 Jakýkoli HTTP klient
Cokoli, co umí poslat Authorization: Bearer raq_live_..., může API používat.
8. Rate limits
| Scope | Limit |
|---|---|
| Anonymní | N/A — všechny /api/ai/* endpointy vyžadují klíč |
| Per-key | Zatím bez hard limitu; abuse pattern může triggerovat throttling v budoucnu |
| Dashboard chat | 30 zpráv / hodinu / uživatel (separate endpoint, nepočítá se do API quoty) |
9. HTTP status kódy
| Kód | Význam |
|---|---|
| 200 | OK |
| 201 | Vytvořeno |
| 204 | OK, no content (typicky DELETE) |
| 400 | Špatný request — chybí nebo nesprávný field |
| 401 | Chybějící / neplatný / revokovaný token → vygeneruj nový v Settings |
| 403 | Token je platný, ale chybí mu scope pro tento request |
| 404 | Resource neexistuje v tomto workspace |
| 405 | HTTP metoda není dovolena na tomto URL |
| 429 | Rate limit překročen — back off a zkus později |
| 500 | Server error — nahlas s request ID z response headers |
| 502 | Upstream error (Anthropic, Fakturoid) — network / dependency |
| 503 | Služba dočasně nedostupná (chat bez ANTHROPIC_API_KEY) |
Pokud request selže s 403, zavolej /me/ a zkontroluj key.scopes — potřebuješ <resource>:<action> (např. invoices:write).
10. Troubleshooting
"Invalid AI key" / 401
- Token je špatně okopírovaný (oříznutý
raq_live_prefix?) - Klíč byl revokovaný v Settings
- Klíč vypršel (
expires_at)
→ Vygeneruj nový klíč v Nastavení → Integrace → AI & API přístup.
"AI key missing required scope" / 403
- Volaný endpoint potřebuje scope, který klíč nemá
- Například POST
/tasks/vyžadujetasks:writenebowrite
→ V Settings revokuj klíč a vytvoř nový s potřebnými scopes. Nebo edituj existující klíč (pokud to UI podporuje — zatím jen recreate).
"Cannot determine user to attribute time entry to" / 400
- Klíč nemá
created_bya workspace nemá jednoznačného ownera - V POST body explicitně uveď
"user": "<user-uuid>"
Cross-tenant leak
- Nemůže se stát — všechny querysety jsou filtrované přes
AIWorkspaceScopedMixin - Pokud se ti stane, je to security bug → nahlas
Swagger UI neukazuje "Try it out" button
- Zkontroluj, že používáš
https://(nehttp://) - Authorize přes Bearer token (ne Basic)
11. Bezpečnost
- Neposílej klíč přes URL query (
?token=...) — vždy jen header. - Neukládej klíč do Gitu, public gistu, CI variable bez encryption, nebo do OpenClaw prompt historie.
- Revokuj okamžitě pokud máš podezření na leak. Nový klíč vygeneruj v Settings.
- Audit: pole
last_used_atna klíči ukáže poslední použití. Pokud je v minulosti i když ho máš aktivní, někdo jiný ho nepoužívá. - Least privilege: Vytvoř klíč s nejmenším nutným scope. Read-only klíč pro dashboardy, write-klíč jen pro agenty, kterým důvěřuješ.
12. Versioning
Verze API je v OpenAPI schema pod info.version (aktuálně 1.0.0). Breaking změny inkrementujou major verzi a objeví se pod /api/ai/v2/. Do té doby je unversioned base /api/ai/ stabilní.
Changelog: - 1.0.0 (2026-04): První veřejná verze. Endpointy: tasks, projects, clients, briefs, comments, time-entries, invoices, calendar-events, me, search. Scope model s tokens jako JSON list.
13. Kontakt a support
- Issues / feature requesty: GitHub issue tracker (pokud je repo veřejné)
- Email: jan@raqeto.com
- Documentation updates: tato stránka je generovaná z
docs/AI_API.mdv repu
Pokud najdeš chybu v dokumentaci, nejrychlejší cesta je PR na docs/AI_API.md.