Construiește pe aichat.md — agenți AI conversaționali, pe orice canal.
O platformă, o singură integrare. Pune un agent inteligent pe site într-o linie de cod, conectează Facebook, Instagram, Telegram și WhatsApp, sau controlează totul programatic prin API-ul REST: agenți, tool-uri, conversații, lead-uri, CRM, automatizări, cunoștințe și analiză.
Pornire rapidă
Agentul pe site, în trei pași:
- Creează un agent în panoul aichat.md și copiază-i widgetId-ul (un UUID, din Agent → Canale → Chat Widget).
- Lipește scriptul de embed înainte de
</body>. - Sau, pentru UI propriu, apelează
POST /widget/chat.
<script src="https://aichat.md/api/v1/widget/bridge/chatbot-script.js?chatflow_id=WIDGET_ID" defer></script>Pentru acces programatic la agenți, canale, conversații sau CRM, obții întâi un token — vezi Autentificare.
URL de bază & versiuni
| URL de bază | https://aichat.md/api/v1 |
| Format | JSON pe request și response; anteturi Content-Type: application/json. |
| Widget | Rute publice sub /widget, identificate prin widgetId. CORS deschis. |
| Management | Rute autentificate cu Authorization: Bearer <token>. |
| Versiuni | Aproape tot e sub /api/v1. O singură zonă are și /api/v2: dashboard-ul (/api/v1/dashboard și /api/v2/dashboard sunt identice; folosește v2). |
Autentificare
Există două niveluri de acces:
Public — widget
Rutele /widget/* sunt publice, identificate prin widgetId. Nicio cheie în front-end. Accesul se restrânge prin lista de origini permise a agentului.
Autentificat — cont
Restul API-ului cere un JWT Bearer obținut prin login. Același token e acceptat și ca header, și ca cookie access_token.
Autentificarea programatică se face azi prin JWT de sesiune (login → token). Nu există (încă) o cheie API de workspace long-lived de pus în .env — pentru integrări server-to-server, reutilizează token-ul de login și reînnoiește-l cu refresh.
Obținerea unui token
Flux: register → verify-email → login. Endpoint-urile care emit token returnează { accessToken, refreshToken }.
curl -X POST https://aichat.md/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{ "email": "tu@firma.md", "pass": "••••••••" }'
# → 200 { "accessToken": "eyJ…", "refreshToken": "eyJ…" }
# → 202 { "twofa_required": true, "pendingToken": "…" } dacă 2FA e activ
# → 228 { "email": "…" } email neconfirmat (un cod NOU e retrimis automat)Atenție la numele câmpurilor — nu sunt uniforme: register cere pass, iar login acceptă pass sau password; verify-email folosește verificationCode (nu code); doar 2FA și reset folosesc code.
Endpoint-uri de autentificare
| Metodă & rută | Body | Rezultat |
|---|---|---|
POST /auth/register | { email, pass } | 200 { email } — apoi verificare pe email. |
POST /auth/verify-email | { email, verificationCode } | { accessToken, refreshToken } |
POST /auth/regenerate-code | { email } | Retrimite codul de verificare. |
POST /auth/login | { email, pass } | Token-uri · 202 2FA · 228 email neconfirmat (serverul retrimite automat un cod nou → treci direct la verify-email). |
POST /auth/2fa/login-verify | { pendingToken, code, remember_device? } | { accessToken, refreshToken } |
POST /auth/refresh | { refreshToken } (sau cookie) | Rotește și returnează token-uri noi. |
POST /auth/reset-password | { email } | Trimite cod de resetare. |
POST /auth/new-password | { email, code, newPassword } | { accessToken, refreshToken } (auto-login). |
POST /auth/pass-change 🔒 | { password, newPassword } | Schimbă parola; invalidează toate sesiunile. |
POST /auth/revokeRefreshTokens 🔒 | {} | Logout global — revocă toate refresh-token-urile proprii (doar ale contului tău). |
2FA (TOTP) — management (toate 🔒 Bearer)
POST /auth/2fa/setup (→ { secret, qrCode }) · /2fa/verify-enable (→ { backupCodes }) · /2fa/disable · /2fa/status · /2fa/backup-codes/regenerate · GET /2fa/trusted-devices · DELETE /2fa/trusted-devices/:id (id-ul device-ului din listă).
Apoi trimite token-ul pe orice rută autentificată: Authorization: Bearer <accessToken>. Eroare de auth: 401 { message: "🚫 Un-Authorized 🚫" }.
Convenții & paginare
Forma răspunsului
Convenția nu e uniformă pe toată platforma — verifică per zonă:
| Formă | Zone |
|---|---|
{ success: true, data: … } | widget, conversații, handoff, usage, automation-engine, keywords, dashboard, knowledge, template-library |
obiect/array „gol" (fără success) | agents, leads, amoCRM (reads), sequences, broadcasts, workflows, analytics, notes, tags, canned-responses |
Paginare
List-endpoint-urile mari acceptă page + limit (ex. /conversations, /leads) sau cursor + limit (ex. /conversations/:id/messages). Unde nu e specificat un plafon, limit are un maxim de siguranță (ex. usage/transactions ≤ 500).
Fusuri, criptare, id-uri
Datele-oră sunt în fusul Chișinău (Europe/Chisinau) unde nu se specifică altfel. Agenții și widget-ul folosesc UUID; conversațiile/thread-urile folosesc id-uri numerice.
Erori & rate limits
Coduri de răspuns
| Cod | Semnificație |
|---|---|
200 / 201 | OK. |
202 | Acceptat — proces asincron (ex. indexare fișiere) sau 2FA necesar. |
228 | Email neconfirmat (la login) — nu e eroare; du userul la ecranul de verificare. |
400 | Cerere invalidă (câmp lipsă / format greșit). |
401 / 403 | Neautentificat / interzis (token lipsă, origine neautorizată, agent dezactivat). |
402 | credits_exhausted. |
404 | Resursă / widget inexistent. |
409 | Conflict (ex. lead duplicat 24h, număr deja conectat). |
422 | Entitate neprocesabilă (moderare comentariu respinsă, WhatsApp fără numere). |
429 | Prea multe cereri. |
430 | În afara ferestrei de 24h Meta (Messenger/IG) — nu poți trimite mesaj liber. |
500/502/504 | Eroare de server / serviciu temporar indisponibil — reîncearcă cu backoff. |
Contractul de eroare diferă pe straturi. Stratul widget întoarce { success:false, error } + anteturi X-RateLimit-* + retryInSec. Stratul de management (autentificat) are un limiter global de 1000 cereri / 15 min / IP care întoarce 429 ca text simplu cu anteturi RateLimit-* (fără JSON). Tratează cele două diferit.
Rate limits — widget
| Domeniu | Limită |
|---|---|
| Chat / per widget | 600 / min |
| Chat / per IP | 120 / min |
| Config / per widget · per IP | 1200 / min · 90 / min |
| Comandă / per IP | 5 / min |
| Istoric / per IP | 60 / min |
Instalare widget
Trei metode de embed. Alege una:
1. Script bridge — recomandat (web-component)
<script src="https://aichat.md/api/v1/widget/bridge/chatbot-script.js?chatflow_id=WIDGET_ID" defer></script>2. Loader — sigur pentru Google Tag Manager (web-component)
<script async src="https://aichat.md/api/v1/widget/loader.js?widget-id=WIDGET_ID"></script>3. Embed static v2 — iframe
<script src="https://aichat.md/api/v1/widget/v2/embed.js?id=WIDGET_ID"
data-position="right" data-color="#0d9c93" data-lang="ro"></script>Metodele 1 și 2 montează componenta web <aichat-chat>; metoda 3 e un iframe (buton launcher + <iframe>) și acceptă atribute data-id/data-position/data-color/data-lang. Selectorii CSS pe aichat-chat NU funcționează cu metoda 3.
Aspectul (culoare, nume, avatar, mesaj) se setează din panou sau prin API-ul de config widget. Snippet-ul se poate genera și programatic cu POST /widget/embed-code { chatbot_id } → { success, html }.
Conversație — chat
| Câmp | Descriere | |
|---|---|---|
widgetId | obligatoriu | UUID-ul agentului (acceptă și widget_id). |
messages | obligatoriu* | [{ role, content }], role = user/assistant. |
message | alt. | Un singur mesaj, în locul lui messages. |
sessionId | recomandat | Leagă mesajele într-o conversație. Vezi nota de mai jos. |
attachments | opțional | Imagini (max 3, ≤4 MB, jpeg/png/webp/gif). |
sessionId NU e returnat de răspuns. Dacă nu-l trimiți, cererile anonime consecutive nu împart o conversație (fără memorie). Generează și persistă TU un sessionId (ex. în localStorage) și trimite-l la fiecare mesaj — e și cheia pentru istoric.
curl -X POST https://aichat.md/api/v1/widget/chat \
-H "Content-Type: application/json" \
-d '{
"widgetId": "1d00a200-8ad9-4bb3-a165-7cfa45960e1d",
"sessionId": "sess-42",
"messages": [{ "role": "user", "content": "Ce servicii aveți?" }]
}'
const sessionId = localStorage.getItem("aichat_sid")
?? (localStorage.setItem("aichat_sid", crypto.randomUUID()), localStorage.getItem("aichat_sid"));
const res = await fetch("https://aichat.md/api/v1/widget/chat", {
method: "POST", headers: { "Content-Type": "application/json" },
body: JSON.stringify({ widgetId: "WIDGET_ID", sessionId, messages: [{ role: "user", content: text }] })
});
const data = await res.json();
console.log(data.message, data.products);Răspuns (200)
{
"success": true,
"message": "Avem manichiură, pedichiură și tratamente podologice…",
"products": [{ "id","title","description","price","currency"?,"image_url"?,"product_url"?,"sku"?,"availability"? }],
"sources": [{ "index","title","snippet","url"? }],
"citations": [ … ], "media": [{ "type","url","title" }],
"actions": [{ "label","url","type" }],
"quick_replies": [{ "label","value" }],
"metadata": { "schema": "aichat.rich.v1", "quickReplies", "products", "sources", … } // duplicat camelCase
}Streaming — token cu token (SSE)
Răspunsul e Server-Sent Events: fiecare eveniment e o linie data: <JSON>, cu tipul în câmpul type. Body: { widgetId, messages | message, sessionId?, images? }.
| Eveniment | Payload |
|---|---|
token | { content } — bucată de text (repetat). |
tool_start | { message } — agentul rulează un tool. |
metadata | { products, quick_replies, sources, citations }. |
done | { duration_ms, tokens_in, tokens_out, tools_used, … }. |
error | { message } — trimis pe stream (HTTP rămâne 200). |
Pe stream, sources și citations sunt întotdeauna goale (rezervate), iar produsele au altă formă decât pe /chat: { title, description, price, image, url, sku, in_stock } — image/url (nu image_url/product_url). Nu refolosi orbește render-ul de la /chat.
const res = await fetch("https://aichat.md/api/v1/widget/v2/chat/stream", {
method: "POST", headers: { "Content-Type": "application/json" },
body: JSON.stringify({ widgetId: "WIDGET_ID", sessionId, message: text })
});
const reader = res.body.getReader(), dec = new TextDecoder();
let buf = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
buf += dec.decode(value, { stream: true });
const parts = buf.split("\n\n");
buf = parts.pop(); // păstrează fragmentul incomplet
for (const block of parts) {
if (!block.startsWith("data:")) continue;
const ev = JSON.parse(block.slice(5));
if (ev.type === "token") ui.append(ev.content);
}
}Config widget — citire publică
Configurația publică a agentului (nume, mesaj, culoare, avatar, sugestii, produse). Endpoint-ul canonic e POST; varianta GET e un alias cu cache ETag/304. Pentru setarea configului (owner, cu token) vezi Config widget al agentului.
POST cere body { widget_id }; GET ia widget_id din cale și adaugă ETag + Cache-Control: max-age=60 (trimite If-None-Match pentru 304). Răspuns: { success, config: { name, primary_color, welcome_message, placeholder, assistant_name, greeting_message, position, starter_prompts[], agent:{name,avatar,tone}, products[], cart_enabled } }.
Istoric conversație
Ultimele 40 de mesaje ale sesiunii: { success, messages: [{ role, content, time }] }. Ambii parametri sunt obligatorii.
Comandă
| Câmp | Descriere | |
|---|---|---|
widget_config_id | obligatoriu | Identificatorul widget-ului (același UUID ca widgetId). Fără el → 400. |
customer_name | obligatoriu | Numele clientului. |
cart_items | obligatoriu | Produsele (listă ne-goală). |
total_amount | obligatoriu | Total (> 0, ≤ 1 000 000). |
customer_phone | opțional | 8–15 cifre. |
customer_address · customer_notes | opțional | Livrare & observații. |
Succes: { success: true, order_id }. Rate-limit 5/min/IP; deduplicare 24h pe telefon+widget (409 duplicate_lead_24h).
{
"widget_config_id": "WIDGET_ID",
"customer_name": "Ana Pop",
"customer_phone": "37360123456",
"customer_address": "str. Ismail 33, Chișinău",
"cart_items": [
{ "id": "sku-12", "title": "Set California", "price": 180, "qty": 2 }
],
"total_amount": 360,
"customer_notes": "fără wasabi"
}Integrare headless — agentul în UI-ul tău
Ai deja un chat pe site și vrei doar „creierul"? Poți integra agentul complet în interfața ta — fără bundle-ul nostru, fără SDK, fără cookie. Toată suprafața e un API public JSON/SSE, autentificat doar prin widgetId. Practic apelezi aceleași endpoint-uri de mai sus din codul tău.
curl -sS https://aichat.md/api/v1/widget/chat \
-H 'Content-Type: application/json' \
-d '{
"widgetId": "WIDGET_ID",
"sessionId": "user-42-conv-7",
"messages": [{ "role": "user", "content": "Salut, aveți livrare la Chișinău?" }]
}'
# → { success, message, products, quick_replies, sources, actions, ... }Piesele de care ai nevoie, toate documentate mai sus:
| Scop | Endpoint |
|---|---|
| Răspuns complet | POST /widget/chat |
| Typing în timp real | POST /widget/v2/chat/stream (SSE) |
| Persona pt UI-ul tău (nume, avatar, sugestii) | GET /widget/{id}/config |
| Rehidratare conversație | GET /widget/history |
Autentificare & CORS
- Auth = doar
widgetId. Fără cheie API, fără Bearer, fără cookie, fără HMAC de identitate. - CORS pe
/widgetreflectă orice origine (credentials: false) — domeniul tău e acceptat implicit. - Lista de origini permise a agentului se verifică la nivel de aplicație și se ocolește când nu există header
Origin(apel din server). Deci dacă chemi din backend-ul tău, nu ești blocat niciodată. Dacă apelezi direct din browser, cere owner-ului agentului să adauge domeniul tău în originile permise.
Recomandare de securitate: apelează din backend-ul tău (ascunzi widgetId) și pune identitatea userului verificat în sessionId (ex. clientUserId:conversationId). Nu există (încă) o legare criptografică user↔sesiune de tip „user_hash".
Memorie / sesiune
Tu deții sessionId-ul (string stabil per user-conversație). Serverul persistă fiecare tură, dar nu re-injectează automat istoricul în prompt — pentru multi-turn, trimite tu istoricul în messages[] (max 20 mesaje, 4000 caractere/mesaj, 3 imagini).
Recomandat vs legacy
| Folosește | Evită (compat vechi Flowise) |
|---|---|
POST /widget/chat | POST /prediction/:chatflowId |
POST /widget/v2/chat/stream | GET /chatflows/:id, /chatflows-streaming/:id |
GET /widget/:id/config | /public-chatbotConfig/:id, /runtime-config/:id |
GET /widget/history | /chatmessage/:id, /apif/* |
Agenți
Creează și gestionează agenți programatic. Toate rutele cer Bearer. Un agent are: nume, instrucțiuni (system prompt), model, provider AI, ton, canale și config.
| Rută | Descriere |
|---|---|
GET /agents | Lista agenților contului. |
POST /agents | Creează agent. Body: name*, instructions, model, aiProvider, description, tone, answerLength, config. |
GET /agents/:id | Detalii + channels + metadata. |
PUT /agents/:id | Actualizează (nume, instrucțiuni, model, temperature, config, capabilities, language…). |
DELETE /agents/:id | Șterge agentul. |
POST /agents/:id/toggle-pause | Pauză / reia ({ paused }). |
POST /agents/onboarding/parse-website | Extrage conținut dintr-un site ({ url }). |
POST /agents/onboarding/generate-instructions | Generează un system prompt. |
POST /agents/onboarding/complete | Creează agentul din configul de onboarding. |
temperature e blocat la 1.0 la creare (orice valoare trimisă la POST e ignorată), dar poate fi schimbat ulterior prin PUT /agents/:id.
curl -X POST https://aichat.md/api/v1/agents \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{ "name": "Asistent salon", "instructions": "Ești asistentul online…", "model": "gpt-4o-mini", "tone": "friendly" }'Config widget al agentului
Merge atomic în channels.widget. Câmpuri: theme_color, persona_name, persona_avatar_url, welcome_message, subtitle, placeholder, starter_prompts (max 4, ≤80 char), position, enabled, pet_name, show_online_dot, theme_mode, quick_replies_enabled, auto_focus_input, allowed_origins, plus hide_branding și footer_text (doar PRO+). Alternativă unificată: PUT /agents/:id/widget-config (acceptă și chei camelCase legacy).
Modele & provideri
Un agent are un model (nume text, ex. gpt-4o-mini) și un ai_provider (implicit azure). Valorile disponibile depind de planul contului — ia lista reală cu:
Răspuns: { models, userPlanId }. Folosește un model din această listă la POST /agents / PUT /agents/:id. (Există și aliasul istoric /asisstants/models, cu doi „s".)
„agent" = „assistant". Numele parametrului diferă pe endpoint-uri: agentId (agents/altegio), assistantId (sheets/knowledge), asistantId (files — un singur „s"), assistant_id (chatbots/pause-rules). Verifică ortografia exactă a fiecărui endpoint.
Tool-uri (funcții)
Dă agentului capacități — să cheme un API, să ruleze cod sau o funcție încorporată. Legate de un agent. Toate rutele cer Bearer.
| Rută | Descriere |
|---|---|
GET /agents/:agentId/tools | Lista tool-urilor. |
POST /agents/:agentId/tools | Creează. Obligatoriu: name, description, tool_type (+ condiționat webhook_url / code_body). |
PUT /agents/:agentId/tools/:toolId | Actualizează. |
DELETE /agents/:agentId/tools/:toolId | Șterge. |
PATCH /agents/:agentId/tools/:toolId/toggle | Activează / dezactivează. |
POST /agents/:agentId/tools/attach | Atașează un tool din librăria contului ({ tool_name } sau { flowise_tool_id }). |
POST /agents/:agentId/tools/detach | Detașează ({ tool_name }). |
POST /agents/:agentId/tools/:toolId/test | Rulează cu argumente de test. |
La /test, argumentele trebuie nested sub arguments: body { "arguments": { … } }. Top-level → ignorat. Notă: name e normalizat automat ([^a-zA-Z0-9_]→_, lowercase) — „Verifică Stoc" devine verific__stoc.
Cele trei tipuri
webhook
Cheamă un URL. webhook_url, webhook_method (def POST), webhook_headers. Interpolare {{var}} din argumente.
code
JavaScript în sandbox (code_body; doar javascript). Primește args + un fetch minimal (status/ok/headers/json/text, timeout 10s); console dezactivat, module blocate (excepție url), timeout cod timeout_ms (implicit 15s).
builtin
Capacitate încorporată (builtin_type + builtin_config): Google Sheets, Altegio, SMS, notificări Telegram ș.a.
Câmpul parameters (argumentele văzute de model) e o listă:
curl -X POST https://aichat.md/api/v1/agents/AGENT_ID/tools \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"name": "verifica_stoc",
"description": "Verifică stocul unui produs după cod",
"tool_type": "webhook",
"webhook_url": "https://api.magazin.md/stoc?sku={{sku}}",
"webhook_method": "GET",
"parameters": [{ "name": "sku", "type": "string", "required": true }]
}'Conversații
Inbox-ul unificat pe toate canalele. Toate rutele cer Bearer. Răspunsuri { success, data }.
| Rută | Descriere |
|---|---|
GET /conversations | Listă (query platform, search, tab, page, limit). |
GET /conversations/:id | O conversație + mesaje recente. |
GET /conversations/:id/messages | Mesaje paginate (cursor, limit). |
POST /conversations/:id/messages | Trimite un răspuns uman ({ content }). 502 dacă livrarea pe canal eșuează. |
PUT /conversations/:id/tags | Suprascrie etichetele ({ tags }). |
POST /conversations/:id/read | Marchează citit. |
GET /conversations/:id/search | Caută în mesajele conversației (?q=). |
GET /conversations/media-proxy?url= | Proxy media FB/IG prin origine. |
GET /conversations/:id/refresh-avatar | Reîmprospătează poza de profil (Meta Graph) când URL-ul CDN semnat expiră → { success, profile_pic, name }. |
Preluare umană (handoff)
Trece o conversație de la bot la un operator uman și înapoi. Bearer, răspunsuri { success, data }.
GET /handoff/pending | Conversații care așteaptă un om. |
GET /handoff/mine | Conversațiile mele. |
POST /handoff/:id/take | Preia conversația. |
POST /handoff/:id/resolve | Rezolvă ({ notes? }). |
POST /handoff/:id/return | Dă controlul înapoi botului. |
POST /handoff/:id/stop-bot · /start-bot | Oprește / repornește răspunsurile automate. |
POST /handoff/:id/cancel-auto-pause | Anulează o pauză automată activă. |
Note · Etichete · Canned · Export · Contacte · Pause-rules
Unelte de inbox. Toate Bearer.
| Zonă | Endpoint-uri |
|---|---|
Note /notes | GET /:threadId · POST / ({ threadId, content }) · PUT /:id · DELETE /:id (ambele doar autorul notei; altfel 403). |
Etichete /tags, /threads | GET/POST /tags · DELETE /tags/:id · GET /threads/:threadId/tags · POST /threads/:threadId/tags ({ tagId }) · DELETE /threads/:threadId/tags/:tagId. |
Răspunsuri rapide /canned-responses | GET · POST ({ shortcut, title, content }) · PUT /:id · DELETE /:id. |
Export /export | GET /:threadId?format=json|csv · GET /:threadId/pdf (HTML print-ready). |
Contacte /contacts | GET /duplicates · POST /merge ({ primaryThreadId, secondaryThreadId }). |
Reguli de pauză /pause-rules | GET /defaults · GET/POST /config · GET/POST / (per assistant_id). |
Web-push /push | POST /subscribe · /unsubscribe · GET /status · GET /vapid-key (public). |
Bulk inbox /threads-bulk | POST /bulk-action ({ threadIds[], action }; action ∈ close|pause|unpause|mark_spam|export). |
Template-uri Meta
Trimite template-uri structurate pe Messenger (proxy către Facebook Graph). Bearer; toate cer recipient_id și întorc { success, message_id }.
POST /templates/receipt | Template Receipt (order_number, summary, items[]…). |
POST /templates/list | Template List (elements ≥ 2). |
POST /templates/media | Template Media (url sau attachment_id). |
POST /templates/otn/request · /otn/send | One-Time-Notification: cere permisiune, apoi trimite cu token. |
Librărie de template-uri (CRUD) — /templates/library
GET /library · GET /library/most-used · GET /library/variables · POST /library/validate · GET /library/:id (+/preview) · POST /library ({ name, templateType, content }, tipuri: text/quick_replies/buttons/generic/carousel/media) · PUT /library/:id · POST /library/:id/duplicate · DELETE /library/:id.
Facebook Messenger
Conectarea unei pagini se face prin OAuth din panou; API-ul leagă o pagină de un agent. Toate cer Bearer.
GET /facebook/oauth-init | URL-ul dialogului OAuth Facebook. |
GET /facebook/pages | Paginile + ce agent are fiecare (pages[].assigned.chatbotId). |
POST /facebook/pages/assign | Leagă o pagină de un agent ({ pageId, agentId }) + abonează webhook-ul. |
DELETE /facebook/pages/unassign | Detașează ({ chatbotId }, nu pageId!). Non-destructiv. |
POST /facebook/send-message | Mesaj ca operator ({ receiver_user_id, text, reply_to_mid? }; pune botul pe pauză). 430 în afara ferestrei Meta. |
POST /facebook/send-attachment | Atașament (multipart file + receiver_user_id). |
unassign se face după chatbotId (din GET /pages → assigned.chatbotId), NU după pageId-ul folosit la assign. Aceeași regulă la Instagram.
Toate cer Bearer.
GET /instagram/login · /pages | URL OAuth · conturile IG + asignarea. |
POST /instagram/pages/assign | Leagă un cont IG de un agent ({ instId, agentId }). |
DELETE /instagram/pages/unassign | Detașează ({ chatbotId }). |
POST /instagram/pages/revoke | Șterge conexiunea local (necesită { instId }; nu revocă grant-ul OAuth pe Meta). |
POST /instagram/unlink | Deconectare la nivel de cont. |
POST /instagram/send-message · /send-attachment | Mesaj / atașament ca operator. |
Telegram
Bot partajat (@aichat_connect_bot) — clientul nu introduce un token de bot. Conectare: cod de 6 cifre → în bot → Telegram Business Connection (Premium) → business_connection_id. Toate cer Bearer.
POST /telegram/get-code | Generează codul de conectare ({ success, code }). |
GET /telegram/business-connected | Starea ({ connected, business_connection_id }). |
POST /telegram/unlink · /send-message | Deconectare · mesaj ca operator. |
WhatsApp (Cloud API)
ready nu dovedește că destinatarul a primit mesajul.Conectare din panou
- Creează și activează agentul.
- Deschide canalul WhatsApp și începe Embedded Signup, dacă accesul pilot este disponibil.
- Autorizează propriul business, WABA și număr. Nu introduce tokenuri în panou.
- Finalizează verificarea și înregistrarea cerută de Meta; verifică abonarea webhookului și agentul asociat.
- Trimite un mesaj de pe un telefon dedicat autorizat și confirmă răspunsul pe telefon, nu numai în inbox.
Ai nevoie de drepturile necesare asupra activelor selectate. Un număr poate aparține unui singur cont aichat.md. Numerele Meta de test pot trimite numai către destinatarii autorizați în lista lor.
API autentificat
Prefix: /api/v1; sesiune validă sau Bearer. Operațiile de onboarding rămân supuse accesului pilot.
GET /whatsapp/config | Disponibilitate, aplicație, configurație și sesiunea semnată attempt, valabilă 10 minute. |
GET /whatsapp/agents | Agenții activi ai contului. |
POST /whatsapp/connect | Cere code, phone_number_id, waba_id, agentId, attempt; pin când înregistrarea îl cere. Sesiunea este consumată o singură dată înainte de schimbul codului. |
POST /whatsapp/complete | Reia pregătirea conexiunii incomplete: phone_number_id, agentId și pin dacă este cerut. |
GET /whatsapp/status | Conexiuni, agent, webhook și condiții lipsă. Verificarea istorică nu este o validare nouă a tokenului la fiecare apel. |
POST /whatsapp/agent | Schimbă agentul propriei conexiuni: phone_number_id, agentId. |
POST /whatsapp/disconnect | Dezactivează conexiunea locală: phone_number_id. Revocarea accesului Meta este un pas distinct. |
GET /whatsapp/numbers/:phoneId/templates | Șabloanele conexiunii proprii. |
GET /whatsapp/events | Evenimente care necesită atenție; retry poate fi refuzat dacă există risc de mesaj duplicat. |
POST /whatsapp/connect-manual | Retras: 410 use_embedded_signup. Nu există fallback cu token introdus manual. |
Mesaje și preluare de operator
Mesajele libere sunt limitate la fereastra de 24 de ore de la ultimul mesaj al clientului. În afara ei folosește un șablon aprobat și respectă acordul destinatarului. Preluarea de operator nu prelungește această fereastră. Revenirea la AI trebuie făcută explicit. Pauza agentului și deconectarea trebuie verificate înainte de reluarea trimiterilor.
Acceptarea mesajului de Meta, sent, delivered, read și failed sunt stări diferite; citirea depinde și de setările destinatarului. Nu considera textul generat de AI drept mesaj livrat. Calling, coexistence și campaniile nu sunt prezentate aici ca funcții disponibile.
Erori utile
503 whatsapp_rollout_pending: contul nu are acces pilot.401 signup_session_expiredsau409 signup_session_already_used: reîncepe conectarea pentru o sesiune nouă.409 whatsapp_number_already_connected_to_another_account: activul este deja legat de alt cont.phone_verification_required/registration_pin_required: finalizează pasul Meta indicat.- Meta
131030: destinatarul nu este permis pentru numărul de test. Nu retrimite automat către alt număr. whatsapp_template_required: fereastra mesajelor libere s-a închis.
Conversațiile sunt păstrate în inbox. Consultă politica de confidențialitate și procedura de ștergere. Deconectarea canalului nu șterge automat istoricul.
Webhook-uri Meta
Pentru FB/IG/WhatsApp, mesajele intră prin webhook-ul Meta — configurat automat la conectare. Nu găzduiești tu nimic.
GET /api/v1/webhook public | Verificare Meta (hub.challenge + verify-token). |
POST /api/v1/webhook public | Recepție evenimente (semnate X-Hub-Signature): mesaje, comentarii, reacții, statusuri. |
Profil Messenger / Instagram
Configurează profilul de mesagerie al unei pagini: buton „Începe", meniu persistent, mesaj de întâmpinare, ice-breakers. /messenger-settings, Bearer. :platform = facebook sau instagram.
GET /messenger-settings/:platform · PUT /:platform | Citește / salvează setările de profil. |
POST /messenger-settings/:platform/get-started | Butonul „Începe". |
POST /messenger-settings/:platform/persistent-menu | Meniu persistent. |
POST /messenger-settings/:platform/greeting | Mesaj de întâmpinare. |
POST /messenger-settings/:platform/ice-breakers | Ice-breakers (întrebări sugerate la deschidere). |
GET /messenger-settings/:platform/live-profile | Profilul curent, direct de la Meta. |
Automation engine
Reguli event-driven (declanșator → condiții → acțiuni). Bearer, răspunsuri { success, data }.
POST /automation-engine/triggers | Creează trigger. Ex: { integrationId, name, triggerType:"new_conversation", triggerScope:"dm", allowedActions:["reply_text"] }. triggerType ∈ new_conversation|story_mention; triggerScope ∈ dm|story. |
GET /automation-engine/triggers | Listă (query integrationId). |
PUT · DELETE /automation-engine/triggers/:id | Actualizează / șterge. |
POST /automation-engine/preview | Dry-run, fără efecte. |
GET /automation-engine/executions | Istoricul execuțiilor. |
Există și un modul mai vechi de task-uri programate (mesaje AI/fixe de follow-up) montat la /api/v1/tasks: GET/POST /tasks, POST /tasks/update, /tasks/delete, /tasks/switch.
Sequences & Broadcasts
Sequences (drip) — /sequences
GET / · GET /:id · POST / ({ name, steps[] }) · PUT /:id · DELETE /:id · PATCH /:id/activate · POST /:id/enroll ({ recipientId, pageId }) · GET /:id/enrollments.
Broadcasts (1-la-mulți) — /broadcasts
GET / · POST / ({ message | templateId, filterTags?, scheduledAt? }) · GET /:id · POST /:id/send (pune în coadă) · DELETE /:id. Livrarea e worker-driven; /send doar schimbă starea în sending.
Keywords & Workflows
Keywords (auto-reply pe cuvinte) — /keywords
GET / · GET /:id · POST / · PUT /:id · PATCH /:id/toggle · DELETE /:id · POST /match-preview ({ integrationId, text }).
La POST /: obligatoriu doar keyword. matchType ∈ exact|contains|starts_with|regex (implicit contains); responseType ∈ dm|comment|both (implicit dm).
dmMessage e obligatoriu când responseType e dm (implicit!) sau both; commentReply obligatoriu când e comment sau both. Un POST { keyword } minim → 400 "dmMessage is required for dm/both response types".
Workflows — /workflows
GET / · GET /:id · POST / ({ name, steps[], triggerConfig }) · PUT /:id · DELETE /:id · PATCH /:id/activate.
Mesaje programate
/schedule, Bearer. POST /create ({ chat_id, name, description, dateTime, service } + repeat?) · POST /update ({ id, … }) · POST /delete ({ id }) · GET /by-conversation?chat_id=&service=.
Lead-uri & etichete
Conversațiile devin lead-uri, pe etichete și board kanban. Bearer.
GET /leads | Listă cu filtre (canal, etichete, scor, dată, căutare, page). |
GET /leads/canban · /leads/canban/tag | Board kanban · coloană per etichetă. (ruta e scrisă literal canban.) |
POST /leads/create-tag · GET /leads/tags | Creează etichetă ({ tag, description, color? }) · listă. |
POST /leads/set-tag | Pune etichetă ({ tag_id, tag_name, chat_id, type, service }). |
POST /leads/pause | Pauză bot pe un lead ({ chat_id, service }). |
POST /leads/analyze | Analiză AI ({ page_id, recipient_id, platform }). |
GET /leads/meta · /leads/meta/stats | Lead-uri Meta îmbogățite + statistici. |
amoCRM
Sincronizare cu amoCRM. Bearer. Reads întorc obiecte „goale" ({pipelines}, {leads}); writes { success }.
GET /amocrm/status | Starea conexiunii. |
POST /amocrm/connect · /connect-oauth | /connect: { subdomain, access_token } obligatorii (client_id/client_secret opționale). /connect-oauth: { code, subdomain, client_id, client_secret } obligatorii. |
POST /amocrm/logout | Deconectare. |
GET /amocrm/pipelines | Pipeline-uri (statusurile vin în _embedded.statuses). |
GET /amocrm/statuses?pipeline_id= | Statusuri — pipeline_id obligatoriu. |
POST /amocrm/statuses | Salvează pipeline + statusuri selectate. |
GET / POST /amocrm/leads | Listă / creare lead-uri. |
GET /amocrm/leads/:id · PATCH /leads/:id | Detaliu · update (e PATCH). |
POST /amocrm/leads/:id/move · /note · /tags | Mută · notă ({ text }) · etichete ({ tags_to_add, tags_to_delete }). |
POST /amocrm/tasks | Sarcină pe lead ({ lead_id, text }). |
GET /amocrm/custom-fields · /users | Câmpuri custom · utilizatori (pt mapare + responsible_user_id). |
PATCH /amocrm/contacts/:id | Actualizează un contact (ex. { custom_fields_values }) — util pentru completarea telefonului/emailului după creare. |
Bitrix24
Sincronizare CRM — POST /bitrix-crm/connect ({ webhookUrl }) · GET /bitrix-crm/status · GET /bitrix-crm/statuses · DELETE /bitrix-crm/disconnect. Toate Bearer.
Canal de chat (Bitrix24 Open Channels) — separat de sync-ul CRM, înregistrează un imbot la /bitrix: POST /bitrix ({ data: { botName, clientId, webhookUrl } }) · POST /bitrix/remove · GET /bitrix/getDataBitrix.
Google Sheets
Agentul scrie lead-urile ca rânduri într-o foaie. La conectare se atașează un tool builtin. Bearer.
GET /google-sheets/connect-info | Emailul robot cu care partajezi foaia. |
POST /google-sheets/test-connection | Verifică accesul. |
POST /google-sheets/connect | Conectează + atașează tool ({ assistantId, spreadsheetUrl, fields, sheetTab?, dedupeKey? }). |
GET / · /for-assistant/:id | Listă · stare per agent. |
PATCH /:id · POST /:id/test-row · DELETE /:id | Editează mapping · test · deconectează. |
Altegio — programări online
Conectează calendarul Altegio al unui salon. Clientul lipește doar Company ID; se atașează 5 tool-uri (servicii, disponibilitate, creare, anulare, mutare). Bearer.
| Câmp | Descriere | |
|---|---|---|
agentId | obligatoriu | Agentul căruia i se atașează tool-urile. |
companyId | obligatoriu | ID-ul salonului din Altegio. |
userToken | opțional | Activează anularea/reprogramarea. Stocat criptat. |
bookingEnabled | opțional | Permite crearea de programări. |
Răspuns: { integrationId, companyId, salon, servicesCount, bookingEnabled, attached }. Stare: GET /altegio/for-assistant/:agentId; deconectare: DELETE pe aceeași rută.
Telegram Leads · SMS · alte integrări
| Integrare | Endpoint-uri |
|---|---|
Telegram Group Leads /telegram-leads | GET /connect-info · GET / · POST /start-link · GET /status?assistantId= · GET /for-assistant/:id · PATCH /:id · POST /:id/test · DELETE /:id. |
| SMS (Infobip) | Expus ca tool builtin (builtin_type: "sms_send"), nu ca rută REST — cheia rămâne pe server. |
Shopify /shopify | POST /logout (deconectare). |
Wix /wix | POST / (conectare) · POST /logout. |
Jivo /jivo | POST / ({ data: { providerId } } — providerId obligatoriu) · POST /remove · GET /getDataJivo. |
Bază de cunoștințe (RAG)
Alimentează agentul cu surse — text, documente, site-uri, întrebări-răspuns. Bearer, răspunsuri { success, data }.
GET /knowledge/sources · /sources/:id | Listă (filtre assistantId, status, sourceType) · una singură. |
POST /knowledge/sources | Creează. Obligatoriu: sourceType (∈ text|document|website|qa_pairs) + name. content doar pentru text; websiteUrl doar pentru website; document/qa_pairs nu cer niciunul. |
POST /knowledge/sources/upload | Din fișier încărcat (≤10 MB). |
PUT /knowledge/sources/:id · DELETE /:id | Actualizează (re-chunk) · șterge. |
POST /knowledge/sources/:id/resync · /reextract-products | Re-chunk/re-embed · re-extrage produse. |
GET /knowledge/sources/:id/products · /chunks | Citește produsele extrase (pereche cu re-extract) · chunk-urile (re-)generate ale sursei. |
GET / PUT /knowledge/config/:assistantId | Config RAG per agent. |
Fișiere & documente
Documente în indexul unui agent (pdf, doc, docx, txt, csv, json, md, markdown, rtf, log, text; ≤5 MB/fișier). Extensiile nelistate sunt încercate, nu respinse — doar lipsa extensiei → 400. Bearer.
POST /files | Încarcă (câmp multipart files + asistantId). Async automat dacă un fișier ≥300 KB sau totalul ≥700 KB (sau forțat cu asyncUpload=true): 202 + jobId; sub praguri: 200 sync. |
GET /files/upload-status/:jobId | Progresul indexării. |
GET /files?asistantId= · POST /files/delete | Listă · șterge ({ fileId, asistantId }). |
Scraping site → index căutabil
Extrage conținutul unui site și îl face căutabil (pagini, produse). /scrape, Bearer.
POST /scrape | Pornește un scrape ({ url, selector_url_override?, sitemap_urls_override_str? }). |
GET /scrape/search?query_text=&page_size=&page_number=&index= | Căutare full-text paginată (toți parametrii obligatorii). |
GET /scrape/list · /status/:index | Site-urile scrape-uite · statusul unui job (404 dacă lipsește). |
GET /scrape/:index?offset=&limit= | Rândurile/produsele dintr-un index (implicit offset 0, limit 100). |
PUT /scrape/:index · DELETE /:index | Update o intrare ({ key, data }) · șterge o intrare ({ key }). |
DELETE /scrape/delete/:index | Șterge tot indexul unui site. |
Analytics & Dashboard
Analytics — /analytics (Bearer; răspunsuri „goale")
GET /messages-per-day?days= ([{ date, incoming, outgoing }]) · GET /top-agents?days= · GET /overview ({ messagesToday, messagesThisWeek, activeThreads, total_contacts, … }).
Dashboard — /api/v2/dashboard (recomandat) sau /api/v1/dashboard
Toate GET, Bearer, cache scurt, rate-limit 60/min: /stats?period= · /trend?days= · /pages · /leads/recent?limit= · /alerts · /comments-stats?period= · /cost-detail?period=.
Consum & credite
/usage, Bearer. Query period = 1d/7d/30d/all (implicit 30d).
GET /usage/summary?period= | { credits:{ remaining, limit, used_in_period, used_today }, messages, tokens, cost_usd, wallet }. |
GET /usage/breakdown | Pe model, sursă, agent, zi. |
GET /usage/transactions | Registru tranzacții de credit (limit ≤ 500). |
GET /settings/credit-history | Istoric credite + abonament + grafic 30 zile. |
Voce (ElevenLabs)
Clonare și management de voci. /create și /update folosesc multipart/form-data. Bearer.
GET /eleven-labs · /voice?eleven_id= | Listă voci · o voce. |
POST /eleven-labs/create | Creează voce — multipart, câmp files (repetabil) + name obligatorii; opțional description, labels (JSON). |
POST /eleven-labs/update | Editează o voce (multipart): eleven_id + name obligatorii; files opțional (prezent → adaugă mostre; absent → doar metadate). |
POST /eleven-labs/delete | Șterge o singură mostră dintr-o voce ({ eleven_id, sample_id }). |
POST /eleven-labs/voice/delete | Șterge toată vocea ({ id }). |
GET /eleven-labs/available-voices | Voci disponibile contului. |
Numele câmpului multipart e exact files (repetat pentru mai multe mostre). Trimis literal ca files[], multer îl respinge cu eroare „Unexpected field".
Credite — cum se calculează
Creditul e unitatea de facturare. Numărul de credite pe un răspuns AI depinde DOAR de modelul folosit — nu de câți tokeni s-au consumat. E o taxare flat pe mesaj, per model.
credite_pe_mesaj = pret_flat_al_modelului (+ suprataxe media, doar FB/IG)Apelurile de tool și RAG/cunoștințe nu adaugă credite — un mesaj cu 5 tool-calls costă cât unul simplu.
Preț per model
| Credite / mesaj | Modele (exemple) |
|---|---|
| 1 | GPT-4o mini, 4.1, 4.1 nano, DeepSeek V3, Gemini Flash Lite |
| 2 | 4.1 mini, 5 nano, Llama 3.3 70B / Llama 4 Maverick, Grok 3 mini, Gemini Flash |
| 3 | 5.4, 5.4 mini, 5 mini, 5.5 mini, Kimi K2.5 |
| 4 | GPT-5, 4o, GPT-OSS 120B, Cohere Command A |
| 5 | GPT-5.1, Mistral Large 3, Grok 4 Non-Reasoning |
| 8 | GPT-5.2, Gemini 3 Pro / 3.1 Pro |
| 10–12 | GPT-5.3, GPT-5.5, Grok 4 fast, 5.6 Terra/Luna |
| 25 | Grok 4 |
Suprataxe media (doar FB/IG)
Peste prețul modelului: mesaj vocal primit (transcriere) +1; generare imagine +5/imagine; răspuns vocal TTS ElevenLabs +20 (alt TTS/STT +10).
Planuri & limite
| Plan | Preț | Credite incluse |
|---|---|---|
| — (fără abonament) | 0 | 0 (+ sold inițial de credite la înregistrare) |
| standard | €49 | 2.000 |
| pro | €150 | 10.000 |
| ultra | €299 | 30.000 |
| business | €499 | 50.000 |
- Sold =
limit − current(dinUserSettings.tokens). - La activarea abonamentului:
limit = max(limit, current + credite_plan). - Top-up one-time:
credite = floor(tokeni_cumpărați / 3). - La epuizare (
current ≥ limit) →402 credits_exhausted. - La înregistrare contul primește un sold inițial de credite; fără abonament activ nu există credite recurente.
Exemplu: un mesaj pe FB cu agent pe Grok 4 = 25 credite; un mesaj vocal pe IG cu gpt-5.4 (3) + transcriere (+1) + răspuns TTS ElevenLabs (+20) = 24 credite; un text simplu = între 1 și 25 credite, după model.
Citirea stării (sold / consum)
Endpoint-urile de citire sunt documentate în Consum & credite (GET /usage/summary, GET /settings/credit-history) și Facturare (GET /stripe/billing/overview, GET /stripe/billing/dashboard).
Cont & profil
/users, Bearer.
GET /users/profile | Profil complet: user, plan_id, credite rămase, stare Stripe, abonament + zile-expirare, canale IG/FB. |
POST /users/update | Actualizează full_name, bio, email (sync și la Stripe). |
POST /users/change-locale | Limba UI (locale). |
POST /users/me/delete-request · /me/delete-cancel | GDPR: cerere ștergere cont (grace 30 zile) / anulare. delete-request cere { confirm_email } (= emailul contului, altfel 400); reason opțional → { success, scheduled_at, grace_ends_at }. |
Facturare (Stripe)
/stripe, Bearer. (Webhook-ul /stripe/webhook e public/semnat — nu-l apelezi tu.)
POST /stripe/create-checkout-session | Checkout abonament ({ product } = lookup_key, ex. pro_month). |
POST /stripe/create-checkout-session-on-token | Checkout top-up credite — body { unit_amount_decimal } (sumă în USD; acordă sumă×100 credite). |
GET /stripe/create-billing-portal | Link portal facturare Stripe. |
GET /stripe/billing/overview · /stripe/billing/dashboard | Plan + credite + forecast. |
GET /stripe/billing/invoices · /billing/charges · /billing/upcoming | Facturi · plăți · factura viitoare. |
POST /stripe/billing/invoices/:id/retry | Reîncearcă plata unei facturi. |
GET /stripe/history | Istoric achiziții. |
Chatbots — mapare canal ↔ agent
Un „chatbot" leagă un canal (FB page, IG, widget…) de un agent. /chatbots, Bearer.
GET /chatbots | Listă. |
POST /chatbots/create · /update | Creează / actualizează mapare (platform ↔ assistant_id). |
POST /chatbots/disable · /delete | Toggle enabled · șterge. |
POST /chatbots/settings · /comments | Setări bulk (auto-reply, nume, agent) · reply comentarii. |
POST /chatbots/master-toggle · GET /master-status | On/off general toate canalele · stare. |
POST /chatbots/service-bulk-toggle · GET /service-status | On/off per serviciu · contoare. |
Echipe & referral
Echipe (multi-user) — /teams
Mai mulți operatori pe un cont, cu roluri (admin/agent/viewer). Bearer.
POST /teams · GET /teams | Creează echipă ({ name } — o singură echipă deținută per user; a 2-a → 400) · listă echipe (deținute + membru). |
GET /teams/:id · PUT /teams/:id | Detalii + membri · redenumește (owner). |
POST /teams/:id/invite | Invită pe email ({ email, role }). |
PUT /teams/:id/members/:memberId/role · DELETE /members/:memberId | Schimbă rol · scoate membru. |
POST /teams/accept-invite | Acceptă invitațiile pending. |
Referral — /referrals
Program de recomandare cu coduri promo și cont Stripe Express. Bearer.
GET /referrals/referrals-info | Dashboard: balanță, coduri promo, nr. referrals, câștig. |
POST /referrals/create-stripe-account · GET /dashboard | Cont Stripe Express + coupon · link dashboard/onboarding. |
POST /referrals/create-promocode | Creează cod promo pe cuponul tău ({ code }). |
POST /referrals/deactivate-promocode | Dezactivează / reactivează un cod promo — toggle reversibil ({ code }). |
POST /referrals/delete-promocode | Șterge definitiv codul (îl scoate din listă + Stripe active:false; ireversibil). |
POST /referrals/create-checkout-session | Checkout abonament cu cod referral. |
999.md (Simpals)
Integrare cu marketplace-ul 999.md. /trei9, Bearer.
POST /trei9/auth · /unlink | Leagă contul ({ username_simpals, refreshToken }) · deconectează. |
GET /trei9/threads · /thread?chat_id= | Contacte · mesajele unui thread. |
POST /trei9/send-message · /edit-config | Trimite mesaj · config per-thread (AI on/off). |
Formulare & suport
/storage. Tichete de suport și formulare (unele publice, pentru pagini de contact).
POST /storage/help-requests 🔒 | Ticket suport + atașamente (notif Telegram). |
POST /storage/callback 🔒 | Cere callback. |
POST /storage/contact-us · /get-demo · /cv · /enterprise public | Formulare publice de contact/demo/CV/enterprise. Rate-limit 1/10min doar pe /get-demo și /cv; /contact-us și /enterprise sunt fără limită. |
Calitate agent (audit)
Audit automat al conversațiilor unui agent, cu scoruri și recomandări. Bearer.
GET /agents/:id/quality · /quality/:auditId | Audituri recente · detaliu (scoruri + fragmente). |
POST /agents/:id/quality/run | Rulează manual un audit. |
POST /agents/:id/quality/:auditId/apply | Adaugă recomandările la instrucțiunile agentului. |
Events & monitoring
GET /events?userId= public | Stream SSE real-time per user (mesaje noi, notificări; heartbeat 10s). |
GET /monitoring?start=&end= 🔒 | Consum per-user: tokeni, zilnic, voce TTS/STT, imagini. |
Jurnal audit · Changelog · Conținut public
GET /audit?page=&limit=&action=&entity_type=&from=&to= 🔒 | Jurnalul de acțiuni al contului tău (paginat, filtrabil). GET /audit/actions = tipurile de acțiuni. |
GET /changelog · /latest · /seen 🔒 | Feed-ul de noutăți al produsului + starea „văzut". POST /changelog/seen marchează ca citit. |
GET /posts/news · /news/:slug · /blogs · /blogs/:slug public | Conținut public news/blog (site marketing) — parametru ?locale=. |
Postări pe pagini (Facebook & Instagram)
Publică și programează conținut pe paginile conectate. Bearer; proxy către Meta Graph.
Facebook — /page-posts
POST /page-posts | Post text/link (message SAU link; opțional published, scheduled_publish_time între 10 min și 6 luni). |
POST /page-posts/photo | Post foto (url; opțional message, scheduled_publish_time). |
PUT /page-posts/:postId · DELETE /:postId | Editează textul · șterge. |
GET /page-posts?limit=&after= | Listă postări feed (limit implicit 25, max 100). |
Instagram — /ig-publish
POST /ig-publish/post | Post imagine (image_url; opțional caption, location_id, user_tags). |
POST /ig-publish/video · /reel | Video feed / Reel (video_url; opțional caption, thumb_offset, share_to_feed). |
POST /ig-publish/carousel | Carusel 2–10 elemente (items[]; opțional caption). |
POST /ig-publish/story | Story (image_url SAU video_url). |
Programarea nativă IG e nefiabilă (Meta o ignoră frecvent) — pentru IG, publică la momentul dorit din propriul scheduler.
Comentarii FB/IG
Moderare și auto-reply AI pe comentariile de Facebook/Instagram, cu coadă de aprobare, template-uri și reguli de declanșare. /comments, Bearer.
Setări & moderare
GET /comments/settings · PUT /settings | Pagini + toggle-uri auto/private reply · actualizează toggle-urile. |
GET /comments/health · /diagnostics | Diagnostic sănătate pagină (token, stats 30 zile). |
GET /comments/recent | Ultimele 50 de comentarii pe toate paginile. |
POST /comments/:id/hide · /reply · DELETE /:id | Ascunde · răspuns manual (≤8000) · șterge. |
POST /comments/bulk-hide | Hide/unhide în masă (max 25). |
POST /comments/media/:mediaId/toggle-comments | Activează/dezactivează comentariile pe un post IG ({ enabled, page_id }). |
POST /comments/settings/:chatbotId/archive · /restore | Arhivează / restaurează o pagină din lista de setări. |
Coadă de aprobare AI
GET /comments/pending · /pending/count | Drafturi AI în așteptare + contor pentru badge. |
POST /comments/:id/approve · /:id/reject | Aprobă & publică (opțional edited_text) · respinge. |
POST /comments/chatbots/:id/comments-config | Mod (off/auto/approval) + instrucțiuni AI pe chatbot/agent. |
Template-uri & reguli de declanșare
/comments/predefined-replies (CRUD) | Template-uri de răspuns public. |
/comments/predefined-pm-messages (CRUD) | Template-uri de mesaj privat. |
/comments/trigger-rules (CRUD) | Reguli auto-reply (matchType exact/contains/regex → răspuns/PM). |
POST /comments/trigger-rules/match-preview | Testează o regulă pe un text, fără salvare. |
Comentarii live (FB Live)
GET /live-comments/:videoId/stream | Stream SSE al comentariilor live (poll Graph la 2s). |
GET /live-comments/:videoId | Comentarii live recente (non-stream, cu cursor after). |
POST /live-comments/:id/hide · DELETE /:id | Ascunde · șterge. |
Suport
Panou aichat.md
Creezi agentul, iei widgetId, configurezi canalele și originile permise.
Contact tehnic
Pentru acces, integrări dedicate sau întrebări despre API — scrie-ne prin formularul din panou sau POST /storage/contact-us.
Integrare la cheie
Scenariu complex (tool-uri proprii, canale multiple, CRM)? Echipa te ajută.
Raportare bug programatică: POST /api/v1/bug-report — multipart cu până la 10 capturi (screenshots), rate-limit 5/min; atașează userul dacă trimiți un JWT, altfel anonim.
API Marketing: acces, pregătire și execuție
Contract verificat în sursa aplicației la 21 octombrie 2026. Baza este /api/v1/marketing. Disponibilitatea unei operații depinde de rol, afacere, conexiuni și activările din instalarea curentă; o rută documentată nu garantează publicarea la furnizor.
Autentificare și spațiu de lucru
Marketing folosește JWT-ul sesiunii aichat, prin cookie access_token sau Authorization: Bearer <JWT>. Cookie-ul are prioritate când există. Cheile unui API AI, instrumentele din Developer și tokenurile Meta nu înlocuiesc acest JWT. Nu există în acest contract un adaptor de chei API Marketing pentru acces automat între servere.
Pentru rutele afacerii trimiți exact un context: X-Workspace-Id: <ID> sau X-Marketing-Scope: personal. Serverul verifică membrul, rolul și tenantul; brandId trebuie să aparțină aceluiași context. Nu trimite ambele headere. ID-urile altui spațiu nu acordă acces.
curl 'https://aichat.md/api/v1/marketing/brands' \
-H "Authorization: Bearer $AICHAT_SESSION_TOKEN" \
-H "X-Workspace-Id: $AICHAT_WORKSPACE_ID"În aplicația web folosește sesiunea normală. Pentru un CRM extern, începe cu navigarea către Marketing și autorizarea explicită a catalogului. Nu introduce parola proprietarului sau tokenuri personale în linkuri, widgeturi ori JavaScript public. Un conector automat necesită un contract separat de acces delegat, cu scope, expirare, revocare și audit; acesta nu este furnizat de simpla existență a rutelor de mai jos.
Conectarea Instagram direct
GET /instagram listează conturile profesionale autorizate în context. POST /instagram/init cu brandId și returnPath întoarce authUrl; utilizatorul autorizează în Instagram. Inițierea și revenirea trebuie făcute în același browser; cookie-ul temporar securizat leagă autorizarea de sesiunea inițiatoare. După revenire, POST /brands/:brandId/instagram cu instagramAccountId și expectedVersion atașează explicit contul. Asocierea poate fi refuzată dacă există livrări sau reclame în curs.
Acest conector cere cont Business/Creator și permisiuni pentru identificare și publicare organică. Nu acordă automat drepturi Ads, mesagerie sau răspuns AI. Conexiunea Meta pentru Facebook și reclame rămâne distinctă. Starea autorizării și acceptarea unei publicări sunt verificări separate.
De la ciornă la postare
- Înregistrează materialele și creează ciorna prin
POST /brands/:brandId/publications. - Citește
versionșirevision.hashreturnate; aprobă exact acea revizie prin/approvecu{ version, hash }. - Folosește versiunea returnată de aprobare în
/queue. Workerul și execuția trebuie să fie disponibile pentru afacere. - Verifică livrările separat pentru fiecare canal. La rezultat incert folosește reconcilierea; nu retrimite crearea orbește.
Formatul cererii este feed, story sau reel; canalele sunt facebook și instagram. Un feed poate avea 1–10 materiale; story/reel cer unul singur, iar reel cere video. Caruselul Facebook cu video combinat este refuzat. Validarea furnizorului poate restrânge suplimentar formatul. Exemplele folosesc ID-uri fictive și date care trebuie înlocuite înainte de utilizare.
{
"caption": "Text verificat pentru produsul ales.",
"format": "feed",
"channels": [
"facebook",
"instagram"
],
"mediaIds": [
"00000000-0000-4000-8000-000000000001"
],
"productIds": [],
"publishAt": "2030-01-20T10:00:00.000Z"
}Modificarea materialelor, produselor, conexiunii sau conținutului poate invalida aprobarea. Reprogramarea unei livrări anulate/expirate cere o revizie nouă și o nouă aprobare. reconcile_required nu înseamnă eșec sigur; closed_external_review păstrează rezultatul neverificat.
Reclame: plan, verificare, PAUSED
POST /brands/:brandId/ads salvează planul; preflight verifică eligibilitatea, iar prepare poate crea obiecte externe în stare PAUSED. Ambele cer version și hash actuale. Video, carusel și destinațiile Messenger/Instagram Direct cer prepareOnly: true. În acest mod bugetul este propus, rezervarea este zero și activarea este refuzată inclusiv dacă plafonul contului crește ulterior.
Pentru site: imagine, MP4 cu copertă sau carusel de 2–10 imagini. Linkurile trebuie să aibă originea site-ului afacerii. Pentru mesaje: o imagine, destination: messenger sau instagram_direct, întâmpinare de maximum 300 de caractere și 1–4 întrebări de început. Drepturile, identitatea paginii/profilului și acceptarea Meta sunt verificate separat. Crearea unei reclame către mesaje nu trimite o conversație și nu activează un agent AI.
{
"name": "Plan pentru verificare",
"caption": "Descoperă produsul și întreabă-ne detalii.",
"format": "image",
"destination": "messenger",
"mediaId": "00000000-0000-4000-8000-000000000001",
"welcomeMessage": "Bună! Cu ce te putem ajuta?",
"iceBreakers": [
{
"title": "Este disponibil produsul?",
"response": "Spune-ne produsul și mărimea dorită."
}
],
"prepareOnly": true,
"budgetMinor": 100,
"currency": "USD",
"startAt": "2030-01-20T10:00:00.000Z",
"endAt": "2030-01-21T10:00:00.000Z",
"targeting": {
"geo_locations": {
"countries": [
"MD"
]
}
},
"specialAdCategories": []
}Exemplul de mai sus nu este o comandă de executat și nu aprobă un buget. Moneda trebuie să corespundă contului publicitar. specialAdCategories este obligatoriu: lista goală este corectă numai pentru produse care nu intră într-o categorie specială. Activarea unui plan eligibil necesită administrator, execuție activă și buget aprobat separat. Verifică state.execution, nu doar existența butonului.
Catalog, comenzi și conversații
Conectorul catalogului folosește inventory/start, consimțământul managerului în CRM, callback cu cod de unică folosință și inventory/finish. Tokenul catalogului rămâne pe server. sync citește produsele, stocul și costurile disponibile; disconnect revocă legătura. Acest grant nu include comenzile.
Vânzările folosesc import explicit de export CRM, apoi asociere manuală prin /sales/:id/associate. Sunt acceptate ținte campaign, ad și conversation cu evidenceType: manual_reference. Referința conversației este un ID local meta-thread:… din lista permisă de raport, nu ID-ul destinatarului Meta. Se verifică spațiul, pagina/profilul și disponibilitatea conversației.
Limite: 500 de comenzi per export complet, 999 înregistrări per afacere și cel mult 366 zile calendaristice. Raportul acoperă snapshoturile importate, nu toate comenzile istorice. Plata, profitul net și cauzalitatea reclamei rămân necunoscute. Modificările de fapte sau pierderea accesului cer reverificare; retragerea asocierii păstrează istoricul. Nu există în Marketing un endpoint pentru a trimite mesaje, crea o comandă CRM sau un AWB.
Rutele Marketing
În tabel, rolurile se aplică după JWT și contextul explicit, cu excepțiile specificate. Majoritatea răspunsurilor JSON sunt { data: … }; erorile routerului sunt { error: "cod" }. Media sunt bytes, iar callbackul redirecționează.
| Metodă și rută | Acces | Efect și limită |
|---|---|---|
GET /api/v1/marketing/media/:id/public | URL semnat, fără JWT | Citește bytes media; expirare, semnătură și format verificate. |
GET /api/v1/marketing/inventory/describe | Stare temporară de conectare | Descrie cererea de catalog, fără a acorda acces. |
GET /api/v1/marketing/inventory/callback | Cod și stare temporară | Schimbă codul catalogului pe server; redirecționează 303. Nu se apelează manual. |
GET /api/v1/marketing/status | JWT; fără context obligatoriu | Capabilități și activări globale. Nu dovedește execuția unui brand. |
GET /api/v1/marketing/instagram | admin, manager, viewer | Conturi Instagram autorizate în contextul curent; fără tokenuri. |
POST /api/v1/marketing/instagram/init | admin, manager | Inițiază autorizarea Instagram pentru brandId și returnPath; returnează authUrl. |
POST /api/v1/marketing/brands/:brandId/instagram | admin, manager | Atașează explicit instagramAccountId cu expectedVersion; verifică grantul și operațiile în curs. |
GET /api/v1/marketing/connection | admin, manager, viewer | Citește starea conexiunii Meta pentru contextul curent. |
POST /api/v1/marketing/connection/init | admin, manager | Inițiază autorizarea Meta; returnPath limitat la pagina Marketing. |
GET /api/v1/marketing/crm/resolve | admin, manager, operator, viewer | source=defi și store exact; întoarce afaceri accesibile, nu acordă acces. |
GET /api/v1/marketing/brands/:brandId/sales | admin, manager | Raport filtrat prin store, from, to; include țintele de asociere permise. |
POST /api/v1/marketing/brands/:brandId/sales/import | admin, manager | Import explicit al exportului CRM complet; idempotent pe snapshot, cu istoric. |
POST /api/v1/marketing/brands/:brandId/sales/:id/associate | admin, manager | Asociere manuală la ad, campaign sau conversation; cere version. |
POST /api/v1/marketing/brands/:brandId/sales/:id/revoke | admin, manager | Retrage asocierea; version obligatoriu, istoricul se păstrează. |
GET /api/v1/marketing/brands | Membru autorizat | Listează afacerile contextului; maximum 1000 în stocarea curentă. |
POST /api/v1/marketing/brands | admin, manager | Creează afacere; plafonul inițial este zero. |
PATCH /api/v1/marketing/brands/:brandId | admin, manager; buget: admin | Actualizează versiunea afacerii; bugetele au validări separate. |
POST /api/v1/marketing/brands/:brandId/connect | admin, manager | Validează selection și version; modifică asocierea paginilor și contului Ads. |
GET /api/v1/marketing/brands/:brandId/state | Membru autorizat | Starea brandului, materialelor, campaniilor și operațiilor; execution este specific afacerii. |
POST /api/v1/marketing/brands/:brandId/images | admin, manager, operator | Solicită generare/editare AI; poate consuma credite. Job separat. |
GET /api/v1/marketing/brands/:brandId/images/:id | Membru autorizat | Citește starea unui job de imagine. |
POST /api/v1/marketing/brands/:brandId/inventory/start | admin, manager | Inițiază autorizarea catalogului; requestedStore opțional restrânge magazinul. |
GET /api/v1/marketing/brands/:brandId/inventory | admin, manager, operator, viewer | Starea catalogului, expirare și ultima sincronizare. |
POST /api/v1/marketing/brands/:brandId/inventory/sync | admin, manager | Citește catalogul autorizat și actualizează snapshoturile locale. |
POST /api/v1/marketing/brands/:brandId/inventory/disconnect | admin, manager | Revocă/deconectează catalogul; nu șterge comenzile CRM. |
POST /api/v1/marketing/inventory/finish | admin, manager | Finalizează cererea autorizată din contextul corect, prin id. |
POST /api/v1/marketing/brands/:brandId/automation | admin | Salvează propunerea de politică, fără activare implicită. |
PATCH /api/v1/marketing/brands/:brandId/automation/:id | admin | Revizuiește politica și invalidează aprobarea veche. |
POST /api/v1/marketing/brands/:brandId/automation/:id/approve | admin | Aprobă versiunea/hashul politicii în limitele definite. |
POST /api/v1/marketing/brands/:brandId/automation/:id/pause | admin | Oprește politica; nu publică și nu lansează reclame. |
GET /api/v1/marketing/brands/:brandId/automation/preview | admin, manager | Propuneri de acțiuni; nu execută publicații sau reclame. |
POST /api/v1/marketing/brands/:brandId/media/archive | admin, manager, operator | Multipart file: import ZIP cu rezultate individuale și erori per fișier. |
POST /api/v1/marketing/brands/:brandId/media | admin, manager, operator | Multipart file: verifică și înregistrează materialul; duplicatele sunt recunoscute. |
GET /api/v1/marketing/media/:id | Membru autorizat | Bytes media în tenant/workspace; cache privat. |
POST /api/v1/marketing/brands/:brandId/products | admin, manager, operator | Salvează produs manual și legături către materialele proprii. |
PATCH /api/v1/marketing/brands/:brandId/media/:id | admin, manager, operator; aprobare AI: admin/manager | Actualizează materialul cu version; aprobarea AI este explicită. |
PATCH /api/v1/marketing/brands/:brandId/products/:id | admin, manager, operator | Revizuiește produsul; version obligatoriu. |
POST /api/v1/marketing/brands/:brandId/publications | admin, manager, operator | Creează ciornă cu revizie/hash; nu publică. |
PATCH /api/v1/marketing/brands/:brandId/publications/:id | admin, manager, operator | Modifică ciorna și cere reaprobare; publicările realizate sunt imuabile. |
POST /api/v1/marketing/brands/:brandId/publications/:id/approve | admin, manager | Aprobă version și hash exacte după reverificarea faptelor. |
POST /api/v1/marketing/brands/:brandId/publications/:id/queue | admin, manager | Programează livrări după aprobare; cere worker și execuție disponibile pentru brand. |
POST /api/v1/marketing/brands/:brandId/deliveries/:id/cancel | admin, manager | Anulează numai livrarea eligibilă; nu șterge o postare publicată. |
POST /api/v1/marketing/brands/:brandId/deliveries/:id/reconcile | admin, manager | Verifică providerId la furnizor înainte de confirmarea unei livrări incerte. |
POST /api/v1/marketing/brands/:brandId/deliveries/:id/close-review | admin, manager | Închide verificarea manuală cu confirmReviewed și reason; rezultatul rămâne neverificat. |
POST /api/v1/marketing/brands/:brandId/campaigns | admin, manager, operator | Plan de campanie din brief/perioadă; poate apela AI și consuma credite. |
PATCH /api/v1/marketing/brands/:brandId/campaigns/:id | admin, manager, operator | Editează propunerea de campanie cu controlul versiunii. |
POST /api/v1/marketing/brands/:brandId/campaigns/:id/drafts | admin, manager, operator | Materializează planul în ciorne; nu reprezintă publicare. |
POST /api/v1/marketing/brands/:brandId/chat | admin, manager, operator | Asistent contextual; poate consuma credite și nu autorizează singur cheltuieli. |
POST /api/v1/marketing/brands/:brandId/insights | admin, manager | Citește rezultate Meta și salvează snapshot; fără lansare Ads. |
POST /api/v1/marketing/brands/:brandId/ads | admin | Salvează plan Ads. prepareOnly=true nu rezervă buget. |
GET /api/v1/marketing/brands/:brandId/regions | admin | Caută regiuni la furnizor și păstrează validarea temporară; nu este un GET fără efect local. |
POST /api/v1/marketing/brands/:brandId/ads/:id/preflight | admin | Verifică eligibilitatea și configurația; version și hash obligatorii. |
POST /api/v1/marketing/brands/:brandId/ads/:id/prepare | admin + execuție permisă pentru pregătire | Poate crea obiecte Meta PAUSED. Cere version/hash; nu lansează bugetul. |
POST /api/v1/marketing/brands/:brandId/ads/:id/reconcile | admin | Verifică obiectele Meta existente după rezultat incert; nu retrimite automat crearea. |
POST /api/v1/marketing/brands/:brandId/ads/:id/status | admin + condiții de execuție | PAUSED sau ACTIVE; activarea are verificări de buget separate și refuză prepareOnly. |
Limite și erori
Routerul aplică 120 cereri/minut după rezolvarea contextului; upload 30/minut, imagini AI 6/minut și chat 8/minut, suplimentar limitelor aplicației. Multipart: un câmp file, maximum 40 MiB; imaginile au maximum 10 MiB. Sunt recunoscute JPEG, PNG, WebP și MP4; acceptarea la upload nu garantează acceptarea fiecărui canal. ZIP: maximum 100 intrări și 100 MiB decomprimați.
401: sesiune; 403: rol/context/acces; 409: versiune, aprobare, conexiune sau execuție incompatibilă; 413: fișier prea mare; 429: limită; 503: modul sau serviciu indisponibil. La version_conflict recitește starea înainte de o decizie nouă. Listele curente nu sunt un API de paginare completă; un rezultat-limită nu dovedește că ai inventariat toate datele.
Compatibilitate și integrare automată
Rutele mai vechi /api/v1/page-posts și /api/v1/ig-publish folosesc configurația socială a contului și pot publica direct. Nu oferă contractul de afacere, aprobare, programare și reconciliere al modulului Marketing. Pentru noua integrare folosește fluxul Marketing. Ruta /facebook-ads și cheile API Marketing nu sunt confirmate în acest contract; nu deduce existența lor din exemple vechi sau din ecranul Developer.
Autorizarea independentă între servere, sincronizarea automată a vânzărilor, SSO CRM și exportul complet paginat sunt extensii distincte, încă neincluse aici. Integrarea disponibilă este navigarea contextuală, autorizarea catalogului și operațiile explicite în sesiunea utilizatorului.
Activarea publicării pentru afacere
În setări, «Verifică și activează publicarea» verifică conturile și acordă acces pentru maximum 90 de zile. Afacerea rămâne în pauză; postările necesită aprobare și programare. Oprirea accesului retrage și activarea pilot existentă. Schimbarea contului, expirarea sau revocarea persoanei care a activat accesul cer o nouă verificare. Funcția depinde de activarea instalării și de worker.
GET /api/v1/marketing/brands/:brandId/publication-access: Citește autorizarea explicită de publicare și disponibilitatea workerului.POST /api/v1/marketing/brands/:brandId/publication-access: Verifică conexiunea și activează accesul pentru maximum 90 de zile; păstrează afacerea în pauză. expectedVersion obligatoriu.POST /api/v1/marketing/brands/:brandId/publication-access/disable: Retrage accesul la publicare, inclusiv pentru activarea pilot; nu șterge postări. expectedVersion obligatoriu.