Sari la conținut
Documentație pentru dezvoltatori

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ă.

5canale: Web · FB · IG · Telegram · WhatsApp
REST + SSErăspuns complet sau streaming
3tipuri de tool: webhook · code · builtin
RAGbază de cunoștințe per agent
Început

Pornire rapidă

Agentul pe site, în trei pași:

  1. Creează un agent în panoul aichat.md și copiază-i widgetId-ul (un UUID, din Agent → Canale → Chat Widget).
  2. Lipește scriptul de embed înainte de </body>.
  3. Sau, pentru UI propriu, apelează POST /widget/chat.
index.html
<script src="https://aichat.md/api/v1/widget/bridge/chatbot-script.js?chatflow_id=WIDGET_ID" defer></script>
i

Pentru acces programatic la agenți, canale, conversații sau CRM, obții întâi un token — vezi Autentificare.

Început

URL de bază & versiuni

URL de bazăhttps://aichat.md/api/v1
FormatJSON pe request și response; anteturi Content-Type: application/json.
WidgetRute publice sub /widget, identificate prin widgetId. CORS deschis.
ManagementRute autentificate cu Authorization: Bearer <token>.
VersiuniAproape 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).
Început

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.

i

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 }.

POST/api/v1/auth/loginpublic
cURL
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ăBodyRezultat
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 🚫" }.

Început

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.

Început

Erori & rate limits

Coduri de răspuns

CodSemnificație
200 / 201OK.
202Acceptat — proces asincron (ex. indexare fișiere) sau 2FA necesar.
228Email neconfirmat (la login) — nu e eroare; du userul la ecranul de verificare.
400Cerere invalidă (câmp lipsă / format greșit).
401 / 403Neautentificat / interzis (token lipsă, origine neautorizată, agent dezactivat).
402credits_exhausted.
404Resursă / widget inexistent.
409Conflict (ex. lead duplicat 24h, număr deja conectat).
422Entitate neprocesabilă (moderare comentariu respinsă, WhatsApp fără numere).
429Prea multe cereri.
430În afara ferestrei de 24h Meta (Messenger/IG) — nu poți trimite mesaj liber.
500/502/504Eroare 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

DomeniuLimită
Chat / per widget600 / min
Chat / per IP120 / min
Config / per widget · per IP1200 / min · 90 / min
Comandă / per IP5 / min
Istoric / per IP60 / min

Widget pe site

Instalare widget

Trei metode de embed. Alege una:

1. Script bridge — recomandat (web-component)

html
<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)

html
<script async src="https://aichat.md/api/v1/widget/loader.js?widget-id=WIDGET_ID"></script>

3. Embed static v2 — iframe

html
<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 }.

Widget pe site

Conversație — chat

POST/api/v1/widget/chatpublic
CâmpDescriere
widgetIdobligatoriuUUID-ul agentului (acceptă și widget_id).
messagesobligatoriu*[{ role, content }], role = user/assistant.
messagealt.Un singur mesaj, în locul lui messages.
sessionIdrecomandatLeagă mesajele într-o conversație. Vezi nota de mai jos.
attachmentsopționalImagini (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.

exemplu
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?" }]
  }'

Răspuns (200)

application/json
{
  "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
}
Widget pe site

Streaming — token cu token (SSE)

POST/api/v1/widget/v2/chat/streampublic

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? }.

EvenimentPayload
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.

javascript — citire stream
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);
  }
}
Widget pe site

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/api/v1/widget/configpublic
GET/api/v1/widget/{widget_id}/configpublic

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 } }.

Widget pe site

Istoric conversație

GET/api/v1/widget/history?widget_id=…&session_id=…public

Ultimele 40 de mesaje ale sesiunii: { success, messages: [{ role, content, time }] }. Ambii parametri sunt obligatorii.

Widget pe site

Comandă

POST/api/v1/widget/orderpublic
CâmpDescriere
widget_config_idobligatoriuIdentificatorul widget-ului (același UUID ca widgetId). Fără el → 400.
customer_nameobligatoriuNumele clientului.
cart_itemsobligatoriuProdusele (listă ne-goală).
total_amountobligatoriuTotal (> 0, ≤ 1 000 000).
customer_phoneopțional8–15 cifre.
customer_address · customer_notesopționalLivrare & observații.

Succes: { success: true, order_id }. Rate-limit 5/min/IP; deduplicare 24h pe telefon+widget (409 duplicate_lead_24h).

exemplu — POST /widget/order
{
  "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"
}
Widget pe site

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.

din UI-ul tău — un singur apel
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:

ScopEndpoint
Răspuns completPOST /widget/chat
Typing în timp realPOST /widget/v2/chat/stream (SSE)
Persona pt UI-ul tău (nume, avatar, sugestii)GET /widget/{id}/config
Rehidratare conversațieGET /widget/history

Autentificare & CORS

  • Auth = doar widgetId. Fără cheie API, fără Bearer, fără cookie, fără HMAC de identitate.
  • CORS pe /widget reflectă 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.
i

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șteEvită (compat vechi Flowise)
POST /widget/chatPOST /prediction/:chatflowId
POST /widget/v2/chat/streamGET /chatflows/:id, /chatflows-streaming/:id
GET /widget/:id/config/public-chatbotConfig/:id, /runtime-config/:id
GET /widget/history/chatmessage/:id, /apif/*

Agenți & tool-uri

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 /agentsLista agenților contului.
POST /agentsCreează agent. Body: name*, instructions, model, aiProvider, description, tone, answerLength, config.
GET /agents/:idDetalii + channels + metadata.
PUT /agents/:idActualizează (nume, instrucțiuni, model, temperature, config, capabilities, language…).
DELETE /agents/:idȘterge agentul.
POST /agents/:id/toggle-pausePauză / reia ({ paused }).
POST /agents/onboarding/parse-websiteExtrage conținut dintr-un site ({ url }).
POST /agents/onboarding/generate-instructionsGenerează un system prompt.
POST /agents/onboarding/completeCreează agentul din configul de onboarding.
i

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 — creare agent
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

PATCH/api/v1/agents/:id/channels-widget🔒 Bearer

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).

Agenți & tool-uri

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:

GET/api/v1/asistants/models🔒 Bearer

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".)

i

„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.

Agenți & tool-uri

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/toolsLista tool-urilor.
POST /agents/:agentId/toolsCreează. Obligatoriu: name, description, tool_type (+ condiționat webhook_url / code_body).
PUT /agents/:agentId/tools/:toolIdActualizează.
DELETE /agents/:agentId/tools/:toolIdȘterge.
PATCH /agents/:agentId/tools/:toolId/toggleActivează / dezactivează.
POST /agents/:agentId/tools/attachAtașează un tool din librăria contului ({ tool_name } sau { flowise_tool_id }).
POST /agents/:agentId/tools/detachDetașează ({ tool_name }).
POST /agents/:agentId/tools/:toolId/testRulează 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ă:

exemplu — creare tool webhook
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

Conversații

Inbox-ul unificat pe toate canalele. Toate rutele cer Bearer. Răspunsuri { success, data }.

RutăDescriere
GET /conversationsListă (query platform, search, tab, page, limit).
GET /conversations/:idO conversație + mesaje recente.
GET /conversations/:id/messagesMesaje paginate (cursor, limit).
POST /conversations/:id/messagesTrimite un răspuns uman ({ content }). 502 dacă livrarea pe canal eșuează.
PUT /conversations/:id/tagsSuprascrie etichetele ({ tags }).
POST /conversations/:id/readMarchează citit.
GET /conversations/:id/searchCaută în mesajele conversației (?q=).
GET /conversations/media-proxy?url=Proxy media FB/IG prin origine.
GET /conversations/:id/refresh-avatarReîmprospătează poza de profil (Meta Graph) când URL-ul CDN semnat expiră → { success, profile_pic, name }.
Conversații & Inbox

Preluare umană (handoff)

Trece o conversație de la bot la un operator uman și înapoi. Bearer, răspunsuri { success, data }.

GET /handoff/pendingConversații care așteaptă un om.
GET /handoff/mineConversațiile mele.
POST /handoff/:id/takePreia conversația.
POST /handoff/:id/resolveRezolvă ({ notes? }).
POST /handoff/:id/returnDă controlul înapoi botului.
POST /handoff/:id/stop-bot · /start-botOprește / repornește răspunsurile automate.
POST /handoff/:id/cancel-auto-pauseAnulează o pauză automată activă.
Conversații & Inbox

Note · Etichete · Canned · Export · Contacte · Pause-rules

Unelte de inbox. Toate Bearer.

ZonăEndpoint-uri
Note /notesGET /:threadId · POST / ({ threadId, content }) · PUT /:id · DELETE /:id (ambele doar autorul notei; altfel 403).
Etichete /tags, /threadsGET/POST /tags · DELETE /tags/:id · GET /threads/:threadId/tags · POST /threads/:threadId/tags ({ tagId }) · DELETE /threads/:threadId/tags/:tagId.
Răspunsuri rapide /canned-responsesGET · POST ({ shortcut, title, content }) · PUT /:id · DELETE /:id.
Export /exportGET /:threadId?format=json|csv · GET /:threadId/pdf (HTML print-ready).
Contacte /contactsGET /duplicates · POST /merge ({ primaryThreadId, secondaryThreadId }).
Reguli de pauză /pause-rulesGET /defaults · GET/POST /config · GET/POST / (per assistant_id).
Web-push /pushPOST /subscribe · /unsubscribe · GET /status · GET /vapid-key (public).
Bulk inbox /threads-bulkPOST /bulk-action ({ threadIds[], action }; action ∈ close|pause|unpause|mark_spam|export).
Conversații & Inbox

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/receiptTemplate Receipt (order_number, summary, items[]…).
POST /templates/listTemplate List (elements ≥ 2).
POST /templates/mediaTemplate Media (url sau attachment_id).
POST /templates/otn/request · /otn/sendOne-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.


Canale

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-initURL-ul dialogului OAuth Facebook.
GET /facebook/pagesPaginile + ce agent are fiecare (pages[].assigned.chatbotId).
POST /facebook/pages/assignLeagă o pagină de un agent ({ pageId, agentId }) + abonează webhook-ul.
DELETE /facebook/pages/unassignDetașează ({ chatbotId }, nu pageId!). Non-destructiv.
POST /facebook/send-messageMesaj ca operator ({ receiver_user_id, text, reply_to_mid? }; pune botul pe pauză). 430 în afara ferestrei Meta.
POST /facebook/send-attachmentAtaș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.

Canale

Instagram

Instagram DM folosește Instagram Login și un cont profesional. Nu confunda autorizarea DM cu fluxul separat de publicare prin Facebook Login. Autorizează doar activele proprii; dacă o permisiune este refuzată sau sesiunea expiră, reîncepe conectarea din panou.

Toate cer Bearer.

GET /instagram/login · /pagesURL OAuth · conturile IG + asignarea.
POST /instagram/pages/assignLeagă un cont IG de un agent ({ instId, agentId }).
DELETE /instagram/pages/unassignDetașează ({ chatbotId }).
POST /instagram/pages/revokeȘterge conexiunea local (necesită { instId }; nu revocă grant-ul OAuth pe Meta).
POST /instagram/unlinkDeconectare la nivel de cont.
POST /instagram/send-message · /send-attachmentMesaj / atașament ca operator.
Canale

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-codeGenerează codul de conectare ({ success, code }).
GET /telegram/business-connectedStarea ({ connected, business_connection_id }).
POST /telegram/unlink · /send-messageDeconectare · mesaj ca operator.
Canale

WhatsApp (Cloud API)

Acces pilot. Onboardingul general nu este deschis. Accesul pentru clienți externi depinde de permisiunile și aprobările Meta, pregătirea numărului și o probă reală de livrare. O conexiune ready nu dovedește că destinatarul a primit mesajul.

Conectare din panou

  1. Creează și activează agentul.
  2. Deschide canalul WhatsApp și începe Embedded Signup, dacă accesul pilot este disponibil.
  3. Autorizează propriul business, WABA și număr. Nu introduce tokenuri în panou.
  4. Finalizează verificarea și înregistrarea cerută de Meta; verifică abonarea webhookului și agentul asociat.
  5. 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/configDisponibilitate, aplicație, configurație și sesiunea semnată attempt, valabilă 10 minute.
GET /whatsapp/agentsAgenții activi ai contului.
POST /whatsapp/connectCere 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/completeReia pregătirea conexiunii incomplete: phone_number_id, agentId și pin dacă este cerut.
GET /whatsapp/statusConexiuni, agent, webhook și condiții lipsă. Verificarea istorică nu este o validare nouă a tokenului la fiecare apel.
POST /whatsapp/agentSchimbă agentul propriei conexiuni: phone_number_id, agentId.
POST /whatsapp/disconnectDezactivează conexiunea locală: phone_number_id. Revocarea accesului Meta este un pas distinct.
GET /whatsapp/numbers/:phoneId/templatesȘabloanele conexiunii proprii.
GET /whatsapp/eventsEvenimente care necesită atenție; retry poate fi refuzat dacă există risc de mesaj duplicat.
POST /whatsapp/connect-manualRetras: 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_expired sau 409 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.

Canale

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 publicVerificare Meta (hub.challenge + verify-token).
POST /api/v1/webhook publicRecepție evenimente (semnate X-Hub-Signature): mesaje, comentarii, reacții, statusuri.
Canale

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 /:platformCitește / salvează setările de profil.
POST /messenger-settings/:platform/get-startedButonul „Începe".
POST /messenger-settings/:platform/persistent-menuMeniu persistent.
POST /messenger-settings/:platform/greetingMesaj de întâmpinare.
POST /messenger-settings/:platform/ice-breakersIce-breakers (întrebări sugerate la deschidere).
GET /messenger-settings/:platform/live-profileProfilul curent, direct de la Meta.

Automatizări

Automation engine

Reguli event-driven (declanșator → condiții → acțiuni). Bearer, răspunsuri { success, data }.

POST /automation-engine/triggersCreează trigger. Ex: { integrationId, name, triggerType:"new_conversation", triggerScope:"dm", allowedActions:["reply_text"] }. triggerType ∈ new_conversation|story_mention; triggerScope ∈ dm|story.
GET /automation-engine/triggersListă (query integrationId).
PUT · DELETE /automation-engine/triggers/:idActualizează / șterge.
POST /automation-engine/previewDry-run, fără efecte.
GET /automation-engine/executionsIstoricul execuțiilor.
i

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.

Automatizări

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.

Automatizări

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.

Automatizări

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 & CRM

Lead-uri & etichete

Conversațiile devin lead-uri, pe etichete și board kanban. Bearer.

GET /leadsListă cu filtre (canal, etichete, scor, dată, căutare, page).
GET /leads/canban · /leads/canban/tagBoard kanban · coloană per etichetă. (ruta e scrisă literal canban.)
POST /leads/create-tag · GET /leads/tagsCreează etichetă ({ tag, description, color? }) · listă.
POST /leads/set-tagPune etichetă ({ tag_id, tag_name, chat_id, type, service }).
POST /leads/pausePauză bot pe un lead ({ chat_id, service }).
POST /leads/analyzeAnaliză AI ({ page_id, recipient_id, platform }).
GET /leads/meta · /leads/meta/statsLead-uri Meta îmbogățite + statistici.
Lead-uri & CRM

amoCRM

Sincronizare cu amoCRM. Bearer. Reads întorc obiecte „goale" ({pipelines}, {leads}); writes { success }.

GET /amocrm/statusStarea 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/logoutDeconectare.
GET /amocrm/pipelinesPipeline-uri (statusurile vin în _embedded.statuses).
GET /amocrm/statuses?pipeline_id=Statusuri — pipeline_id obligatoriu.
POST /amocrm/statusesSalvează pipeline + statusuri selectate.
GET / POST /amocrm/leadsListă / creare lead-uri.
GET /amocrm/leads/:id · PATCH /leads/:idDetaliu · update (e PATCH).
POST /amocrm/leads/:id/move · /note · /tagsMută · notă ({ text }) · etichete ({ tags_to_add, tags_to_delete }).
POST /amocrm/tasksSarcină pe lead ({ lead_id, text }).
GET /amocrm/custom-fields · /usersCâmpuri custom · utilizatori (pt mapare + responsible_user_id).
PATCH /amocrm/contacts/:idActualizează un contact (ex. { custom_fields_values }) — util pentru completarea telefonului/emailului după creare.
Lead-uri & CRM

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.


Integrări native

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-infoEmailul robot cu care partajezi foaia.
POST /google-sheets/test-connectionVerifică accesul.
POST /google-sheets/connectConectează + atașează tool ({ assistantId, spreadsheetUrl, fields, sheetTab?, dedupeKey? }).
GET / · /for-assistant/:idListă · stare per agent.
PATCH /:id · POST /:id/test-row · DELETE /:idEditează mapping · test · deconectează.
Integrări native

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.

POST/api/v1/altegio/connect🔒 Bearer
CâmpDescriere
agentIdobligatoriuAgentul căruia i se atașează tool-urile.
companyIdobligatoriuID-ul salonului din Altegio.
userTokenopționalActivează anularea/reprogramarea. Stocat criptat.
bookingEnabledopționalPermite crearea de programări.

Răspuns: { integrationId, companyId, salon, servicesCount, bookingEnabled, attached }. Stare: GET /altegio/for-assistant/:agentId; deconectare: DELETE pe aceeași rută.

Integrări native

Telegram Leads · SMS · alte integrări

IntegrareEndpoint-uri
Telegram Group Leads /telegram-leadsGET /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 /shopifyPOST /logout (deconectare).
Wix /wixPOST / (conectare) · POST /logout.
Jivo /jivoPOST / ({ data: { providerId } } — providerId obligatoriu) · POST /remove · GET /getDataJivo.

Cunoștințe

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/:idListă (filtre assistantId, status, sourceType) · una singură.
POST /knowledge/sourcesCreează. 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/uploadDin fișier încărcat (≤10 MB).
PUT /knowledge/sources/:id · DELETE /:idActualizează (re-chunk) · șterge.
POST /knowledge/sources/:id/resync · /reextract-productsRe-chunk/re-embed · re-extrage produse.
GET /knowledge/sources/:id/products · /chunksCitește produsele extrase (pereche cu re-extract) · chunk-urile (re-)generate ale sursei.
GET / PUT /knowledge/config/:assistantIdConfig RAG per agent.
Cunoștințe

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/:jobIdProgresul indexării.
GET /files?asistantId= · POST /files/deleteListă · șterge ({ fileId, asistantId }).
Cunoștințe

Scraping site → index căutabil

Extrage conținutul unui site și îl face căutabil (pagini, produse). /scrape, Bearer.

POST /scrapePorneș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/:indexSite-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 /:indexUpdate o intrare ({ key, data }) · șterge o intrare ({ key }).
DELETE /scrape/delete/:indexȘterge tot indexul unui site.

Analiză & voce

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=.

Analiză & voce

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/breakdownPe model, sursă, agent, zi.
GET /usage/transactionsRegistru tranzacții de credit (limit ≤ 500).
GET /settings/credit-historyIstoric credite + abonament + grafic 30 zile.
Analiză & voce

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/createCreează voce — multipart, câmp files (repetabil) + name obligatorii; opțional description, labels (JSON).
POST /eleven-labs/updateEditează 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-voicesVoci 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".


Cont & facturare

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.

formula
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 / mesajModele (exemple)
1GPT-4o mini, 4.1, 4.1 nano, DeepSeek V3, Gemini Flash Lite
24.1 mini, 5 nano, Llama 3.3 70B / Llama 4 Maverick, Grok 3 mini, Gemini Flash
35.4, 5.4 mini, 5 mini, 5.5 mini, Kimi K2.5
4GPT-5, 4o, GPT-OSS 120B, Cohere Command A
5GPT-5.1, Mistral Large 3, Grok 4 Non-Reasoning
8GPT-5.2, Gemini 3 Pro / 3.1 Pro
10–12GPT-5.3, GPT-5.5, Grok 4 fast, 5.6 Terra/Luna
25Grok 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

PlanPrețCredite incluse
— (fără abonament)00 (+ sold inițial de credite la înregistrare)
standard€492.000
pro€15010.000
ultra€29930.000
business€49950.000
  • Sold = limit − current (din UserSettings.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.
i

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 & facturare

Cont & profil

/users, Bearer.

GET /users/profileProfil complet: user, plan_id, credite rămase, stare Stripe, abonament + zile-expirare, canale IG/FB.
POST /users/updateActualizează full_name, bio, email (sync și la Stripe).
POST /users/change-localeLimba UI (locale).
POST /users/me/delete-request · /me/delete-cancelGDPR: 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 }.
Cont & facturare

Facturare (Stripe)

/stripe, Bearer. (Webhook-ul /stripe/webhook e public/semnat — nu-l apelezi tu.)

POST /stripe/create-checkout-sessionCheckout abonament ({ product } = lookup_key, ex. pro_month).
POST /stripe/create-checkout-session-on-tokenCheckout top-up credite — body { unit_amount_decimal } (sumă în USD; acordă sumă×100 credite).
GET /stripe/create-billing-portalLink portal facturare Stripe.
GET /stripe/billing/overview · /stripe/billing/dashboardPlan + credite + forecast.
GET /stripe/billing/invoices · /billing/charges · /billing/upcomingFacturi · plăți · factura viitoare.
POST /stripe/billing/invoices/:id/retryReîncearcă plata unei facturi.
GET /stripe/historyIstoric achiziții.
Cont & facturare

Chatbots — mapare canal ↔ agent

Un „chatbot" leagă un canal (FB page, IG, widget…) de un agent. /chatbots, Bearer.

GET /chatbotsListă.
POST /chatbots/create · /updateCreează / actualizează mapare (platform ↔ assistant_id).
POST /chatbots/disable · /deleteToggle enabled · șterge.
POST /chatbots/settings · /commentsSetări bulk (auto-reply, nume, agent) · reply comentarii.
POST /chatbots/master-toggle · GET /master-statusOn/off general toate canalele · stare.
POST /chatbots/service-bulk-toggle · GET /service-statusOn/off per serviciu · contoare.
Cont & facturare

Echipe & referral

Echipe (multi-user) — /teams

Mai mulți operatori pe un cont, cu roluri (admin/agent/viewer). Bearer.

POST /teams · GET /teamsCreează echipă ({ name } — o singură echipă deținută per user; a 2-a → 400) · listă echipe (deținute + membru).
GET /teams/:id · PUT /teams/:idDetalii + membri · redenumește (owner).
POST /teams/:id/inviteInvită pe email ({ email, role }).
PUT /teams/:id/members/:memberId/role · DELETE /members/:memberIdSchimbă rol · scoate membru.
POST /teams/accept-inviteAcceptă invitațiile pending.

Referral — /referrals

Program de recomandare cu coduri promo și cont Stripe Express. Bearer.

GET /referrals/referrals-infoDashboard: balanță, coduri promo, nr. referrals, câștig.
POST /referrals/create-stripe-account · GET /dashboardCont Stripe Express + coupon · link dashboard/onboarding.
POST /referrals/create-promocodeCreează cod promo pe cuponul tău ({ code }).
POST /referrals/deactivate-promocodeDezactivează / 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-sessionCheckout abonament cu cod referral.

Alte API

999.md (Simpals)

Integrare cu marketplace-ul 999.md. /trei9, Bearer.

POST /trei9/auth · /unlinkLeagă contul ({ username_simpals, refreshToken }) · deconectează.
GET /trei9/threads · /thread?chat_id=Contacte · mesajele unui thread.
POST /trei9/send-message · /edit-configTrimite mesaj · config per-thread (AI on/off).
Alte API

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 publicFormulare publice de contact/demo/CV/enterprise. Rate-limit 1/10min doar pe /get-demo și /cv; /contact-us și /enterprise sunt fără limită.
Alte API

Calitate agent (audit)

Audit automat al conversațiilor unui agent, cu scoruri și recomandări. Bearer.

GET /agents/:id/quality · /quality/:auditIdAudituri recente · detaliu (scoruri + fragmente).
POST /agents/:id/quality/runRulează manual un audit.
POST /agents/:id/quality/:auditId/applyAdaugă recomandările la instrucțiunile agentului.
Alte API

Events & monitoring

GET /events?userId= publicStream SSE real-time per user (mesaje noi, notificări; heartbeat 10s).
GET /monitoring?start=&end= 🔒Consum per-user: tokeni, zilnic, voce TTS/STT, imagini.
Alte API

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 publicConținut public news/blog (site marketing) — parametru ?locale=.

Comentarii & social

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-postsPost text/link (message SAU link; opțional published, scheduled_publish_time între 10 min și 6 luni).
POST /page-posts/photoPost foto (url; opțional message, scheduled_publish_time).
PUT /page-posts/:postId · DELETE /:postIdEditează textul · șterge.
GET /page-posts?limit=&after=Listă postări feed (limit implicit 25, max 100).

Instagram — /ig-publish

POST /ig-publish/postPost imagine (image_url; opțional caption, location_id, user_tags).
POST /ig-publish/video · /reelVideo feed / Reel (video_url; opțional caption, thumb_offset, share_to_feed).
POST /ig-publish/carouselCarusel 2–10 elemente (items[]; opțional caption).
POST /ig-publish/storyStory (image_url SAU video_url).
i

Programarea nativă IG e nefiabilă (Meta o ignoră frecvent) — pentru IG, publică la momentul dorit din propriul scheduler.

Comentarii & social

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 /settingsPagini + toggle-uri auto/private reply · actualizează toggle-urile.
GET /comments/health · /diagnosticsDiagnostic sănătate pagină (token, stats 30 zile).
GET /comments/recentUltimele 50 de comentarii pe toate paginile.
POST /comments/:id/hide · /reply · DELETE /:idAscunde · răspuns manual (≤8000) · șterge.
POST /comments/bulk-hideHide/unhide în masă (max 25).
POST /comments/media/:mediaId/toggle-commentsActivează/dezactivează comentariile pe un post IG ({ enabled, page_id }).
POST /comments/settings/:chatbotId/archive · /restoreArhivează / restaurează o pagină din lista de setări.

Coadă de aprobare AI

GET /comments/pending · /pending/countDrafturi AI în așteptare + contor pentru badge.
POST /comments/:id/approve · /:id/rejectAprobă & publică (opțional edited_text) · respinge.
POST /comments/chatbots/:id/comments-configMod (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-previewTestează o regulă pe un text, fără salvare.

Comentarii live (FB Live)

GET /live-comments/:videoId/streamStream SSE al comentariilor live (poll Graph la 2s).
GET /live-comments/:videoIdComentarii live recente (non-stream, cu cursor after).
POST /live-comments/:id/hide · DELETE /:idAscunde · șterge.

Referință

Suport

◈

Panou aichat.md

Creezi agentul, iei widgetId, configurezi canalele și originile permise.

Deschide panoul →
✉

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.

Marketing și integrare CRM

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.

Citire, fără generare sau publicare
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

  1. Înregistrează materialele și creează ciorna prin POST /brands/:brandId/publications.
  2. Citește version și revision.hash returnate; aprobă exact acea revizie prin /approve cu { version, hash }.
  3. Folosește versiunea returnată de aprobare în /queue. Workerul și execuția trebuie să fie disponibile pentru afacere.
  4. 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.

Body: ciornă, fără trimitere automată
{
  "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.

Body: plan Messenger, cheltuieli neautorizate
{
  "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ăAccesEfect și limită
GET /api/v1/marketing/media/:id/publicURL semnat, fără JWTCitește bytes media; expirare, semnătură și format verificate.
GET /api/v1/marketing/inventory/describeStare temporară de conectareDescrie cererea de catalog, fără a acorda acces.
GET /api/v1/marketing/inventory/callbackCod și stare temporarăSchimbă codul catalogului pe server; redirecționează 303. Nu se apelează manual.
GET /api/v1/marketing/statusJWT; fără context obligatoriuCapabilități și activări globale. Nu dovedește execuția unui brand.
GET /api/v1/marketing/instagramadmin, manager, viewerConturi Instagram autorizate în contextul curent; fără tokenuri.
POST /api/v1/marketing/instagram/initadmin, managerInițiază autorizarea Instagram pentru brandId și returnPath; returnează authUrl.
POST /api/v1/marketing/brands/:brandId/instagramadmin, managerAtașează explicit instagramAccountId cu expectedVersion; verifică grantul și operațiile în curs.
GET /api/v1/marketing/connectionadmin, manager, viewerCitește starea conexiunii Meta pentru contextul curent.
POST /api/v1/marketing/connection/initadmin, managerInițiază autorizarea Meta; returnPath limitat la pagina Marketing.
GET /api/v1/marketing/crm/resolveadmin, manager, operator, viewersource=defi și store exact; întoarce afaceri accesibile, nu acordă acces.
GET /api/v1/marketing/brands/:brandId/salesadmin, managerRaport filtrat prin store, from, to; include țintele de asociere permise.
POST /api/v1/marketing/brands/:brandId/sales/importadmin, managerImport explicit al exportului CRM complet; idempotent pe snapshot, cu istoric.
POST /api/v1/marketing/brands/:brandId/sales/:id/associateadmin, managerAsociere manuală la ad, campaign sau conversation; cere version.
POST /api/v1/marketing/brands/:brandId/sales/:id/revokeadmin, managerRetrage asocierea; version obligatoriu, istoricul se păstrează.
GET /api/v1/marketing/brandsMembru autorizatListează afacerile contextului; maximum 1000 în stocarea curentă.
POST /api/v1/marketing/brandsadmin, managerCreează afacere; plafonul inițial este zero.
PATCH /api/v1/marketing/brands/:brandIdadmin, manager; buget: adminActualizează versiunea afacerii; bugetele au validări separate.
POST /api/v1/marketing/brands/:brandId/connectadmin, managerValidează selection și version; modifică asocierea paginilor și contului Ads.
GET /api/v1/marketing/brands/:brandId/stateMembru autorizatStarea brandului, materialelor, campaniilor și operațiilor; execution este specific afacerii.
POST /api/v1/marketing/brands/:brandId/imagesadmin, manager, operatorSolicită generare/editare AI; poate consuma credite. Job separat.
GET /api/v1/marketing/brands/:brandId/images/:idMembru autorizatCitește starea unui job de imagine.
POST /api/v1/marketing/brands/:brandId/inventory/startadmin, managerInițiază autorizarea catalogului; requestedStore opțional restrânge magazinul.
GET /api/v1/marketing/brands/:brandId/inventoryadmin, manager, operator, viewerStarea catalogului, expirare și ultima sincronizare.
POST /api/v1/marketing/brands/:brandId/inventory/syncadmin, managerCitește catalogul autorizat și actualizează snapshoturile locale.
POST /api/v1/marketing/brands/:brandId/inventory/disconnectadmin, managerRevocă/deconectează catalogul; nu șterge comenzile CRM.
POST /api/v1/marketing/inventory/finishadmin, managerFinalizează cererea autorizată din contextul corect, prin id.
POST /api/v1/marketing/brands/:brandId/automationadminSalvează propunerea de politică, fără activare implicită.
PATCH /api/v1/marketing/brands/:brandId/automation/:idadminRevizuiește politica și invalidează aprobarea veche.
POST /api/v1/marketing/brands/:brandId/automation/:id/approveadminAprobă versiunea/hashul politicii în limitele definite.
POST /api/v1/marketing/brands/:brandId/automation/:id/pauseadminOprește politica; nu publică și nu lansează reclame.
GET /api/v1/marketing/brands/:brandId/automation/previewadmin, managerPropuneri de acțiuni; nu execută publicații sau reclame.
POST /api/v1/marketing/brands/:brandId/media/archiveadmin, manager, operatorMultipart file: import ZIP cu rezultate individuale și erori per fișier.
POST /api/v1/marketing/brands/:brandId/mediaadmin, manager, operatorMultipart file: verifică și înregistrează materialul; duplicatele sunt recunoscute.
GET /api/v1/marketing/media/:idMembru autorizatBytes media în tenant/workspace; cache privat.
POST /api/v1/marketing/brands/:brandId/productsadmin, manager, operatorSalvează produs manual și legături către materialele proprii.
PATCH /api/v1/marketing/brands/:brandId/media/:idadmin, manager, operator; aprobare AI: admin/managerActualizează materialul cu version; aprobarea AI este explicită.
PATCH /api/v1/marketing/brands/:brandId/products/:idadmin, manager, operatorRevizuiește produsul; version obligatoriu.
POST /api/v1/marketing/brands/:brandId/publicationsadmin, manager, operatorCreează ciornă cu revizie/hash; nu publică.
PATCH /api/v1/marketing/brands/:brandId/publications/:idadmin, manager, operatorModifică ciorna și cere reaprobare; publicările realizate sunt imuabile.
POST /api/v1/marketing/brands/:brandId/publications/:id/approveadmin, managerAprobă version și hash exacte după reverificarea faptelor.
POST /api/v1/marketing/brands/:brandId/publications/:id/queueadmin, managerProgramează livrări după aprobare; cere worker și execuție disponibile pentru brand.
POST /api/v1/marketing/brands/:brandId/deliveries/:id/canceladmin, managerAnulează numai livrarea eligibilă; nu șterge o postare publicată.
POST /api/v1/marketing/brands/:brandId/deliveries/:id/reconcileadmin, managerVerifică providerId la furnizor înainte de confirmarea unei livrări incerte.
POST /api/v1/marketing/brands/:brandId/deliveries/:id/close-reviewadmin, managerÎnchide verificarea manuală cu confirmReviewed și reason; rezultatul rămâne neverificat.
POST /api/v1/marketing/brands/:brandId/campaignsadmin, manager, operatorPlan de campanie din brief/perioadă; poate apela AI și consuma credite.
PATCH /api/v1/marketing/brands/:brandId/campaigns/:idadmin, manager, operatorEditează propunerea de campanie cu controlul versiunii.
POST /api/v1/marketing/brands/:brandId/campaigns/:id/draftsadmin, manager, operatorMaterializează planul în ciorne; nu reprezintă publicare.
POST /api/v1/marketing/brands/:brandId/chatadmin, manager, operatorAsistent contextual; poate consuma credite și nu autorizează singur cheltuieli.
POST /api/v1/marketing/brands/:brandId/insightsadmin, managerCitește rezultate Meta și salvează snapshot; fără lansare Ads.
POST /api/v1/marketing/brands/:brandId/adsadminSalvează plan Ads. prepareOnly=true nu rezervă buget.
GET /api/v1/marketing/brands/:brandId/regionsadminCaută regiuni la furnizor și păstrează validarea temporară; nu este un GET fără efect local.
POST /api/v1/marketing/brands/:brandId/ads/:id/preflightadminVerifică eligibilitatea și configurația; version și hash obligatorii.
POST /api/v1/marketing/brands/:brandId/ads/:id/prepareadmin + execuție permisă pentru pregătirePoate crea obiecte Meta PAUSED. Cere version/hash; nu lansează bugetul.
POST /api/v1/marketing/brands/:brandId/ads/:id/reconcileadminVerifică obiectele Meta existente după rezultat incert; nu retrimite automat crearea.
POST /api/v1/marketing/brands/:brandId/ads/:id/statusadmin + condiții de execuțiePAUSED 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.