Whapier

Dezvoltatori

Documentație API

Un API REST autentificat cu token pentru mesaje, șabloane, contacte, campanii, flow-uri și starea de livrare și costul per mesaj. Creează o cheie API la Unelte pentru dezvoltatori în contul tău, apoi autentifică fiecare apel cu Authorization: Bearer <token>.

Exemple complete în PHP, Node.js, Python, Java și Ruby sunt disponibile în documentația din aplicație după ce îți creezi un cont.

Referință citibilă de mașini: OpenAPI 3.1 (JSON) · Colecție Postman

Înainte să începi

Autentificare

Fiecare cerere poartă o cheie API în antetul Authorization, ca token Bearer. Cheile se creează la Instrumente pentru dezvoltatori > Chei API și sunt afișate o singură dată.

O cheie are scope-uri: read (orice GET), send (endpoint-urile de trimitere, campaniile și pornirile de fluxuri) și manage (crearea, modificarea și ștergerea contactelor, grupurilor, răspunsurilor automate, webhook-urilor și șabloanelor, plus acțiunile din inbox). O cheie fără scope-ul necesar primește 403 cu numele scope-ului lipsă.

O cheie poate expira: o cheie expirată primește 401 cu "This API key has expired". Un token lipsă sau necunoscut este tot 401.

O cheie sandbox validează fiecare cerere, înregistrează mesajul cu starea "sandbox" și nu trimite nimic la WhatsApp - construiește pe API-ul real fără o linie WhatsApp și fără costuri.

Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>
Limita de cereri

60 de cereri pe minut per cheie API; cererile fără cheie se numără per adresă IP.

Fiecare răspuns poartă X-RateLimit-Limit și X-RateLimit-Remaining. Peste limită răspunsul este 429 cu statusCode 429, un message și un antet Retry-After în secunde.

GET /api/usage raportează limita la rate_limit.per_minute. /api și /api/v2 împart un singur contor per cheie.

HTTP/1.1 429 Too Many Requests
Retry-After: 42
{"statusCode": 429, "message": "Too many requests. Try again in 42 seconds."}
Idempotență

Trimite un antet Idempotency-Key (1 până la 128 de caractere, unic per operațiune) pe endpoint-urile POST care creează ceva: trimiterile, campaniile, contactele, grupurile și răspunsurile automate.

Aceeași cheie cu aceeași cerere în 24 de ore returnează răspunsul stocat cu antetul Idempotent-Replayed: true, și nimic nu se execută din nou. Un client care reîncearcă după un timeout nu mai trimite de două ori.

Aceeași cheie cu o cerere diferită este 422; aceeași cheie în timp ce prima cerere încă rulează este 409. Se stochează doar răspunsurile 2xx și 4xx, așa că un 5xx poate fi reîncercat cu aceeași cheie.

Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7
Date și fusuri orare

Fiecare dată returnată de API este în UTC, în ISO-8601 cu offset, indiferent de fusul orar pe care îl folosește organizația în dashboard.

Datele pe care le trimiți (scheduled_at, since) sunt citite ca UTC, dacă nu poartă un offset.

"created_at": "2026-10-05T09:30:00+00:00"
Erori

Fiecare răspuns este JSON cu statusCode și message; un payload refuzat adaugă errors, o hartă de la numele câmpului la lista de probleme.

400 date de intrare invalide; 401 cheie lipsă, invalidă sau expirată; 403 scope, abonament, limita planului sau cont în verificare; 404 uuid necunoscut, sau unul care aparține altui spațiu de lucru; 409 conflict (o tranziție de campanie imposibilă, un Idempotency-Key încă în curs); 422 refuzat de o regulă (fereastra de 24 de ore, STOP, variabilele șablonului); 429 limita de cereri; 500 vina noastră.

Acțiunile din inbox (assign, close și reopen pe /api/conversations/{contact_uuid}) răspund 409 cât timp ticketingul este oprit în Setări > Tichete; citirea conversației și adăugarea unei note funcționează oricum.

Pe /api (v1) un refuz din partea WhatsApp însuși este un 200 cu data.success false și motivul în data.data.error (code, message, type). Pe /api/v2 același refuz este un HTTP 422 - vezi Versionare.

{"statusCode": 400, "message": "The given data was invalid.", "errors": {"phone": ["The phone number is not valid."]}}
Paginare

Endpoint-urile de listare primesc page (de la 1) și per_page (implicit 10, max 100; /api/messages are implicit 25) și sunt ordonate cu cele mai noi mai întâi.

Contactele, grupurile, răspunsurile automate, șabloanele, campaniile și jurnalele campaniilor răspund cu data, links și meta (current_page, last_page, per_page, total). /api/messages răspunde cu statusCode, data și meta (page, per_page, total, last_page).

O conversație se paginează în schimb prin cursor: GET /api/contacts/{uuid}/messages și GET /api/conversations/{contact_uuid} răspund cu cele mai noi mai întâi și cu next_before; trimite-l ca before pentru mesajele mai vechi.

Trimiterea unui șablon

O trimitere de șablon trebuie să poarte exact atâția parametri câți substituenți are șablonul aprobat; Meta refuză o nepotrivire cu eroarea 132000.

GET /api/templates/{uuid} returnează example_payload: un corp complet pentru POST /api/send/template cu numărul corect de parametri pentru antet, corp și butoanele URL - înlocuiește valorile și trimite-l.

POST /api/templates trimite un șablon la Meta dintr-o formă JSON plată și răspunde cu motivul dat de Meta când este refuzat; POST /api/templates/sync preia șabloanele de la Meta după o modificare în Meta Business Manager.

GET https://whapier.com/api/templates/{{uuid}}
{"data": {"name": "order_update", "variables": {"header": 0, "body": 1, "buttons": 0}, "example_payload": {"phone": "+40721000001", "template": {"name": "order_update", "language": {"code": "en"}, "components": [{"type": "body", "parameters": [{"type": "text", "text": "Ana"}]}]}}}}
Webhook-uri

Webhook-urile de ieșire se configurează la Instrumente pentru dezvoltatori > Webhook-uri sau prin API (POST /api/webhooks): un URL https și evenimentele de primit. Secretul de semnare este generat pentru tine și afișat o singură dată. Fiecare livrare este un POST cu un corp JSON care poartă event și data.

Antetul X-Whapier-Signature este "sha256=" urmat de HMAC-SHA256 al corpului brut al cererii cu acel secret, în hex. Recalculează-l peste octeții pe care i-ai primit și compară înainte să te încrezi în payload.

Răspunde 2xx în 15 secunde. O livrare care eșuează este reîncercată de încă două ori, după 60 de secunde și după 5 minute; după al treilea eșec evenimentul este abandonat.

Evenimentele: message.received și message.sent; message.status când Meta raportează un mesaj ca delivered, read sau failed (cu eșecul și campania din care a venit); campaign.finished cu numerele finale; ticket.created și ticket.closed; contact.opted_out și contact.opted_in; contact, group și autoreply created, updated și deleted; template.status.update, template.quality.update și account.update așa cum le trimite Meta. GET /api/webhooks/events le listează cu o descriere, iar POST /api/webhooks/{uuid}/test livrează un exemplu.

X-Whapier-Signature: sha256=5d41402abc4b2a76b9719d911017c592...
{"event": "message.status", "data": {"uuid": "64968a32-fdd9-4c1d-8941-b8e538036616", "wam_id": "wamid.HBgM...", "status": "delivered", "timestamp": "2026-10-05T09:30:00+00:00", "failure": null, "contact": {"uuid": "81a2d165-41e2-43f2-847e-d69e08cba0e0", "phone": "+40721000001"}, "campaign": null}}
{"event": "campaign.finished", "data": {"uuid": "3f1c2d0e-5b7a-4c8d-9e0f-1a2b3c4d5e6f", "name": "October offers", "status": "completed", "counts": {"contacts": 120, "sent": 118, "delivered": 110, "read": 64, "failed": 2}, "finished_at": "2026-10-05T09:30:00+00:00"}}
message.received
message.sent
message.status
message.status.update
contact.created
contact.updated
contact.deleted
contact.opted_out
contact.opted_in
group.created
group.updated
group.deleted
autoreply.created
autoreply.updated
autoreply.deleted
campaign.finished
ticket.created
ticket.closed
template.status.update
template.quality.update
account.update
Versionare: v1 și v2

/api (versiunea 1) rămâne suportat așa cum este. /api/v2 servește aceleași endpoint-uri, payload-uri și câmpuri, cu o singură diferență: codul de stare HTTP poartă rezultatul.

Pe v2 un refuz din partea WhatsApp la o trimitere este un HTTP 422 al cărui corp are statusCode 422, message, error (codul, mesajul și tipul de la WhatsApp) și data (răspunsul v1), în loc de un 200 cu data.success false. Ori de câte ori statusCode din corp diferă de codul HTTP, codul HTTP urmează statusCode.

Tot restul - autentificare, scope-uri, limita de cereri, idempotență, date, paginare - este identic, iar aceeași cheie funcționează pe ambele.

POST https://whapier.com/api/v2/send
{"statusCode": 422, "message": "Template name does not exist", "error": {"code": 132001, "message": "Template name does not exist", "type": "OAuthException"}, "data": {"success": false, "message": "Template name does not exist", "data": {"error": {"code": 132001}}}}

Verificare

GET /api/verify Verifică cheia API
# Confirmă că tokenul Bearer este valid și că abonamentul organizației este activ, înainte să apelezi alte endpoint-uri.
# HTTP 200: token OK. 401: token lipsă/invalid. 403: abonament inactiv.

curl -X GET \
https://whapier.com/api/verify \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Contacte

GET /api/contacts Lista contactelor
# Parametri de query opționali: ?page=1&per_page=10 (per_page maximum 100).
# Cele mai noi mai întâi. Răspuns: data (obiecte contact), links și meta (current_page, last_page, per_page, total).
# Un contact: id, uuid, phone, first_name, last_name, email, address, metadata, groups (uuid, name), source, opted_in_at, opted_out_at, created_at, updated_at.
# Filtre de căutare, combinate cu AND: phone (orice format pe care îl poate citi țara organizației; 400 când nu este un număr), email (exact, fără distincție între majuscule și minuscule), q (2 până la 128 de caractere, căutat în nume, email și număr), group (uuid-ul unui grup de contacte; 400 când este necunoscut), opted_out (true | false), updated_since (o dată, UTC), source (api, manual, import, entry point...).

curl -X GET \
"https://whapier.com/api/contacts?page=1&per_page=10" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
GET /api/contacts/{uuid} Detaliile unui contact
# Obiectul contact de la Lista contactelor plus unread_messages, last_message_at și ticket (status, assigned_to: name, email).
# ticket este null cât timp ticketingul este oprit în Setări > Tichete, sau când conversația nu are încă un tichet. 404 când uuid-ul este necunoscut, șters sau aparține altui spațiu de lucru.

curl -X GET \
https://whapier.com/api/contacts/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/contacts Adaugă contact
# Câmpurile corpului JSON:
#   phone (obligatoriu) — număr internațional; validat și stocat în format E.164. Trebuie să fie unic în cadrul organizației (400 dacă este duplicat).
#   first_name, last_name, email (opționale) — omite-le sau trimite null ori "" pentru contactele fără nume.
#   street, city, state, zip, country (opționale) — stocate în JSON-ul address.
#   metadata (opțional) — orice valoare serializabilă în JSON.
#   group (opțional) — array de șiruri UUID ale grupurilor de contacte.
#   marketing_opt_in (opțional, boolean) — true înregistrează consimțământul de marketing pe contact (istoricul consimțământului GDPR, source: api); false înregistrează o dezabonare (opt-out). Omite-l ca să lași consimțământul neschimbat.
# Răspunsuri: 200 succes { statusCode, id, message }; 400 eroare de validare; 403 abonament inactiv sau limita de contacte atinsă.
# Acceptă un antet Idempotency-Key (vezi Înainte să începi).

curl -X POST \
https://whapier.com/api/contacts \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "first_name": "Ana",
    "last_name": "Pop",
    "email": "ana@example.com",
    "group": [
        "d746e4c5-db24-4fb2-be03-590421344d69"
    ],
    "marketing_opt_in": true
}'
POST /api/contacts/bulk Creează sau actualizează contacte în masă
# contacts (obligatoriu, 1 până la 500 de obiecte) cu câmpurile de la Adaugă contact pe fiecare rând. Un rând al cărui phone există deja în spațiul de lucru este actualizat cu câmpurile prezente (ca la Editează contact); un număr nou este creat.
# Fiecare rând stă pe picioarele lui: un rând greșit eșuează singur, iar celelalte trec. Răspuns: { statusCode, created, updated, failed: [ { index, phone, errors } ], limit_reached, message }.
# Crearea se oprește la limita de contacte a planului: limit_reached devine true și rândurile care nu au încăput sunt listate în failed. Actualizările nu se scad niciodată din limită. Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/contacts/bulk \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "contacts": [
        {
            "phone": "+40721000001",
            "first_name": "Ana",
            "last_name": "Pop",
            "email": "ana@example.com"
        },
        {
            "phone": "0721 000 002",
            "first_name": "Ion",
            "group": [
                "d746e4c5-db24-4fb2-be03-590421344d69"
            ]
        },
        {
            "phone": "not-a-phone",
            "first_name": "Nobody"
        }
    ]
}'
PUT /api/contacts/{uuid} Editează contact
# Aceleași câmpuri JSON ca la Adaugă contact. {uuid} din cale este id-ul contactului returnat la creare.
# phone este opțional la o actualizare; dacă îl schimbi, noul număr nu trebuie să aparțină altui contact (400 duplicat).
# Actualizarea cu același phone pe care îl are deja acest contact este permisă.
# Câmpurile pe care nu le trimiți își păstrează valoarea; trimite un câmp ca null sau "" ca să-l golești. Cheile metadata pe care le trimiți sunt combinate cu cele stocate, iar celelalte se păstrează.
# marketing_opt_in (opțional, boolean) — true înregistrează consimțământul de marketing (source: api), false înregistrează o dezabonare (opt-out); dacă lipsește, consimțământul rămâne neschimbat.
# 404 când uuid-ul este necunoscut, șters sau aparține altui spațiu de lucru.

curl -X PUT \
https://whapier.com/api/contacts/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "first_name": "Ana",
    "last_name": "Popescu",
    "metadata": {
        "plan": "platinum"
    }
}'
DELETE /api/contacts/{uuid} Șterge contact
# Marchează contactul ca șters (soft delete); dispare din toate listele deodată. 404 când uuid-ul este necunoscut sau deja șters.
# Răspuns: { statusCode, id, message }.

curl -X DELETE \
https://whapier.com/api/contacts/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Grupuri de contacte

GET /api/contact-groups Lista grupurilor de contacte
# Parametri de query opționali: ?page=1&per_page=10 (per_page maximum 100).
# Fiecare grup: uuid, name, contacts_count (membrii activi), created_at, updated_at.

curl -X GET \
"https://whapier.com/api/contact-groups?page=1&per_page=10" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/contact-groups Adaugă grup de contacte
# name (obligatoriu) trebuie să fie unic între grupurile organizației (400 dacă este deja folosit).
# Răspuns: { statusCode, id, message }. Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/contact-groups \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "name": "Lead 5"
}'
PUT /api/contact-groups/{uuid} Editează grup de contacte
# Același corp ca la Adaugă grup de contacte. 404 pentru un uuid necunoscut.

curl -X PUT \
https://whapier.com/api/contact-groups/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "name": "Lead 5"
}'
DELETE /api/contact-groups/{uuid} Șterge grup de contacte
# Șterge grupul și apartenențele la el; contactele în sine se păstrează. 404 pentru un uuid necunoscut.

curl -X DELETE \
https://whapier.com/api/contact-groups/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Răspunsuri automate

GET /api/canned-replies Lista răspunsurilor automate
# Parametri de query opționali: ?page=1&per_page=10 (per_page maximum 100).
# Fiecare răspuns: uuid, name, trigger, match_criteria, response_type, response (textul, sau null pentru media), file (name, url) sau null, created_at, updated_at.

curl -X GET \
"https://whapier.com/api/canned-replies?page=1&per_page=10" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/canned-replies Adaugă răspuns automat
# Corp: name și trigger (max 255), match_criteria (exact match | contains), response_type (text | image | audio), response.
# Pentru text, response este răspunsul (max 4096). Pentru image sau audio trimite multipart/form-data cu fișierul ca response (png/jpg până la 5 MB; mp3/aac/ogg/amr/opus/m4a până la 16 MB); fără fișier cererea este 400.
# Răspuns: { statusCode, id, message }. 403 când limita de răspunsuri automate a planului este atinsă. Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/canned-replies \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "name": "About Us",
    "trigger": "what do you do?",
    "match_criteria": "contains",
    "response_type": "text",
    "response": "We sell shoes"
}'
PUT /api/canned-replies/{uuid} Editează răspuns automat
# Aceleași câmpuri ca la Adaugă răspuns automat. O actualizare fără fișier păstrează fișierul media pe care îl are deja. 404 pentru un uuid necunoscut.

curl -X PUT \
https://whapier.com/api/canned-replies/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "name": "About Us",
    "trigger": "what do you do?",
    "match_criteria": "contains",
    "response_type": "text",
    "response": "We sell shoes and clothes"
}'
DELETE /api/canned-replies/{uuid} Șterge răspuns automat
# 404 pentru un uuid necunoscut. Răspuns: { statusCode, id, message }.

curl -X DELETE \
https://whapier.com/api/canned-replies/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Linii WhatsApp

GET /api/whatsapp-connections Lista conexiunilor
# Returnează uuid-ul fiecărei linii (folosește-l ca whatsapp_connection în /api/send). Fără id-uri interne din baza de date.
# Fiecare rând: uuid, type, name, phone, display_phone_number și, pentru o linie WhatsApp Business, verified_name și number_status. 403 când nu este conectată nicio linie.

curl -X GET \
https://whapier.com/api/whatsapp-connections \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Mesaje

POST /api/send Trimite mesaj
# Opțional: whatsapp_connection (UUID din GET /api/whatsapp-connections). Dacă îl omiți, se folosește linia implicită a organizației.
# phone (obligatoriu) — orice format; normalizat la E.164 cu țara organizației. Un număr nou devine contact (first_name, last_name, email opționale).
# message (obligatoriu, max 4096); header și footer (opționale, max 60); buttons (opțional, până la 3 de { id, title }).
# Mesajele libere au nevoie de o fereastră de 24 de ore deschisă: 422 când ultimul mesaj al clientului este mai vechi de o zi. 403: abonament, limita planului, plafonul zilnic de trial sau un cont în verificare.
# Răspuns: 200 { statusCode, data: { success, data: { chat: { uuid, wam_id, status, type, created_at, contact } } } }. Un refuz din partea WhatsApp este 200 cu data.success false și data.data.error pe /api; un HTTP 422 pe /api/v2.
# Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/send \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "message": "Hello Ana, how are you?",
    "whatsapp_connection": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "header": "Example Shoes",
    "footer": "Reply STOP to opt out",
    "buttons": [
        {
            "id": "yes",
            "title": "Fine"
        },
        {
            "id": "no",
            "title": "Not well"
        }
    ]
}'
POST /api/send/media Trimite fișier media
# Opțional: whatsapp_connection (UUID din GET /api/whatsapp-connections). Dacă îl omiți, se folosește linia implicită a organizației.
# media_type (image | video | audio | document | sticker); media_url (https, un host public; verificat cu o singură cerere HEAD față de plafoanele WhatsApp de dimensiune și tip - 400 cu motivul în caz contrar); caption (opțional, nu pentru audio); file_name (obligatoriu pentru document).
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/media \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "media_type": "image",
    "media_url": "https://cdn.example.com/offers/october.jpg",
    "caption": "Our October offers"
}'
POST /api/send/template Trimite mesaj-șablon
# Opțional: "whatsapp_connection": "<uuid>" pentru o anumită linie WABA (UUID din GET /api/whatsapp-connections).
# template.name și template.language ("en" sau { "code": "en" }) sunt obligatorii; components urmează structura proprie WhatsApp (header, body, parametrii butoanelor).
# Funcționează în afara ferestrei de 24 de ore. Unui contact care s-a dezabonat (STOP) nu i se trimite un șablon MARKETING: 422. Șabloanele utilitare și de autentificare pleacă în continuare.
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/template \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "template": {
        "name": "order_update",
        "language": {
            "code": "en"
        },
        "components": [
            {
                "type": "header",
                "parameters": [
                    {
                        "type": "text",
                        "text": "48213"
                    }
                ]
            },
            {
                "type": "body",
                "parameters": [
                    {
                        "type": "text",
                        "text": "Ana"
                    },
                    {
                        "type": "text",
                        "text": "48213"
                    },
                    {
                        "type": "date_time",
                        "date_time": {
                            "fallback_value": "October 7, 2026"
                        }
                    }
                ]
            },
            {
                "type": "button",
                "sub_type": "url",
                "index": "0",
                "parameters": [
                    {
                        "type": "text",
                        "text": "48213"
                    }
                ]
            }
        ]
    }
}'
POST /api/send/location Trimite locație
# latitude (-90 până la 90) și longitude (-180 până la 180) obligatorii; name și address opționale.
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/location \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "latitude": 46.77120000000000032969182939268648624420166015625,
    "longitude": 23.623599999999999710098563809879124164581298828125,
    "name": "Example Shoes",
    "address": "Str. Memorandumului 12, Cluj-Napoca"
}'
POST /api/send/contacts Trimite carduri de contact
# contacts (1 până la 10 carduri) în structura contacts[] a WhatsApp: name.formatted_name obligatoriu; phones[], emails[], addresses[], org opționale.
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/contacts \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "contacts": [
        {
            "name": {
                "formatted_name": "Example Shoes Support",
                "first_name": "Support"
            },
            "phones": [
                {
                    "phone": "+40700000000",
                    "type": "WORK"
                }
            ],
            "emails": [
                {
                    "email": "support@example.com",
                    "type": "WORK"
                }
            ]
        }
    ]
}'
POST /api/send/reaction Trimite reacție
# message_id (wam_id-ul mesajului la care reacționezi) și emoji (obligatoriu; "" elimină reacția).
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/reaction \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "message_id": "wamid.HBgMNDA3MjEwMDAwMDEVAgARGBI5QkY2RkE3RDlCMjc2RjI2QkEA",
    "emoji": "👍"
}'
POST /api/send/location-request Cere locația
# message (obligatoriu, max 1024): textul afișat deasupra butonului "Send location".
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/location-request \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "message": "Where should we deliver?"
}'
POST /api/send/request-contact-info Cere datele de contact
# message (obligatoriu, max 1024): îi cere unui utilizator WhatsApp care are doar nume de utilizator să-și partajeze numărul de telefon.
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/request-contact-info \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "message": "Could you share your number so we can call you back?"
}'
POST /api/send/carousel Trimite carusel
# message (obligatoriu, max 1024) și cards (2 până la 10): header { type: image | video, link } obligatoriu; body (max 160), url_button { text, url } și quick_replies (până la 3 de { id, title }) opționale.
# Aceleași verificări și același răspuns ca la Trimite mesaj.

curl -X POST \
https://whapier.com/api/send/carousel \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "phone": "+40721000001",
    "message": "Our new arrivals",
    "cards": [
        {
            "header": {
                "type": "image",
                "link": "https://cdn.example.com/shoes/1.jpg"
            },
            "body": "Runner, 89 EUR",
            "url_button": {
                "text": "See it",
                "url": "https://example.com/shoes/1"
            }
        },
        {
            "header": {
                "type": "image",
                "link": "https://cdn.example.com/shoes/2.jpg"
            },
            "body": "Trail, 119 EUR",
            "quick_replies": [
                {
                    "id": "trail",
                    "title": "Tell me more"
                }
            ]
        }
    ]
}'

Fluxuri

POST /api/flows/{uuid}/start Pornește un flux
# contact (obligatoriu): uuid-ul contactului sau numărul phone (normalizat cu țara organizației).
# 200 { statusCode, success: true, message }; 404 flux sau contact necunoscut; 422 fluxul nu este publicat; 409 contactul este deja într-o sesiune de flux.
# Tot ce trimite fluxul este supus ferestrei de 24 de ore, dacă nu folosește noduri de tip șablon.

curl -X POST \
https://whapier.com/api/flows/{{uuid}}/start \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "contact": "+40721000001"
}'

Campanii

GET /api/campaigns Lista campaniilor
# Opțional: ?page=1&per_page=10&search=
# Fiecare campanie: uuid, name, status, scheduled_at, created_at, template (uuid, name, language, category, status), whatsapp_connection (uuid, name, type), audience (type: all | group | segment, uuid, name), counts (contacts, sent, delivered, read, failed).

curl -X GET \
"https://whapier.com/api/campaigns?page=1&per_page=10" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/campaigns Creează campanie (șablon WABA cu variabile)
# Folosește-l când whatsapp_connection este o linie WhatsApp Cloud (WABA) din GET /api/whatsapp-connections.
#
# CONDIȚII PREALABILE
# - template: UUID-ul unui rând din GET /api/templates (la nivelul organizației), NU numele public al șablonului ca șir de caractere.
# - Potrivește numărul de variabile cu șablonul aprobat: deschide metadatele șablonului în interfață sau la Meta — BODY folosește {{1}}, {{2}}, … în ordine.
# - Trebuie să furnizezi câte un parametru de corp pentru fiecare substituent din BODY, în aceeași ordine. Un număr care nu se potrivește cu șablonul aprobat este refuzat din start (422), nu de WhatsApp ulterior.
#
# NOTE DESPRE CÂMPURI
# - contacts: "all" sau uuid-ul unui grup de contacte; ori segment: uuid-ul unui segment salvat (unul din cele două, nu ambele). send_immediately: true, sau scheduled_at (o dată, citită ca UTC).
# - header: obiect opțional; dacă îl omiți înseamnă { "format": "TEXT", "parameters": [] }.
# - body: folosește body.parameters[] pentru variabile. Formatul API (recomandat): { "type": "text", "value": "literal for {{1}}" } pentru fiecare poziție.
#   Alternativă (ca în dashboard): { "selection": "static", "value": "..." } sau { "selection": "dynamic", "value": "first name" } (mapează câmpuri ale contactului).
# - footer / buttons: opționale; folosește [] sau {} dacă nu le folosești. Șabloanele cu variabile în URL sau în răspunsuri rapide au nevoie de buttons[] structurat ca în formularul web de campanie.
# - Antet media (IMAGE|VIDEO|DOCUMENT): header.parameters[] cu type (IMAGE|VIDEO|DOCUMENT), "selection": "link", "value": "https://..." (URL public; API-ul nu poate încărca fișiere).
#
# RĂSPUNS: 200 { "statusCode": 200, "uuid": "...", "message": "..." }. Interoghează GET /api/campaigns/{uuid} pentru raport și GET /api/campaigns/{uuid}/logs pentru starea fiecărui destinatar, sau abonează-te la webhook-ul campaign.finished.
# 403 când limita de campanii a planului este atinsă. Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/campaigns \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "name": "Billing reminder blast",
    "whatsapp_connection": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "contacts": "all",
    "send_immediately": true,
    "template": "281a3383-985c-4084-bcb0-9ec523c952de",
    "header": {
        "format": "TEXT",
        "parameters": []
    },
    "body": {
        "parameters": [
            {
                "type": "text",
                "value": "Ana"
            },
            {
                "type": "text",
                "value": "48213"
            },
            {
                "type": "text",
                "value": "7 October 2026"
            }
        ]
    },
    "footer": {},
    "buttons": []
}'
GET /api/campaigns/{uuid} Detaliile unei campanii, cu raportul ei
# Obiectul campanie de la Lista campaniilor plus report: counts (contacts, sent, delivered, read, failed, pending), failure_reasons (code, title, count - cele mai frecvente zece), started_at, finished_at (null până se încheie campania), paused_reason, paused_detail și paused_at (null dacă starea nu este paused).
# paused_reason este user (pusă pe pauză din panou sau din API), admin, failing, failure_rate sau quality (pusă pe pauză de platformă; paused_detail spune de ce). 404 pentru o campanie necunoscută.

curl -X GET \
https://whapier.com/api/campaigns/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/campaigns/{uuid}/pause Pune o campanie pe pauză
# Fără corp. Doar o campanie scheduled sau ongoing poate fi pusă pe pauză: 409 altfel, cu starea în care se află campania. Jurnalele rămân cum sunt, iar reluarea le preia.
# Răspuns: { statusCode, status, message } - status este noua stare a campaniei. 404 pentru o campanie necunoscută.

curl -X POST \
https://whapier.com/api/campaigns/{{uuid}}/pause \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{}'
POST /api/campaigns/{uuid}/resume Reia o campanie
# Fără corp. Doar o campanie paused poate fi reluată: 409 altfel. O campanie pusă pe pauză înainte de ora ei revine la scheduled; una pusă pe pauză în timpul trimiterii revine la ongoing.
# Răspuns: { statusCode, status, message }. 404 pentru o campanie necunoscută.

curl -X POST \
https://whapier.com/api/campaigns/{{uuid}}/resume \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{}'
POST /api/campaigns/{uuid}/cancel Anulează o campanie
# Fără corp. O campanie scheduled, ongoing sau paused poate fi anulată: 409 altfel. Ce nu s-a trimis rămâne netrimis; raportul arată în continuare cine a fost atins.
# Răspuns: { statusCode, status, message }. 404 pentru o campanie necunoscută.

curl -X POST \
https://whapier.com/api/campaigns/{{uuid}}/cancel \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{}'
GET /api/campaigns/{uuid}/logs Jurnalele campaniei
# Opțional: ?page=1&per_page=10&search= (caută după numele sau telefonul contactului).
# Fiecare rând: contact (uuid, phone, first_name, last_name), status, message (uuid, wam_id, status) sau null, error (code, title, reason) sau null, retry_count, created_at, updated_at. 404 pentru o campanie necunoscută.

curl -X GET \
"https://whapier.com/api/campaigns/{{uuid}}/logs?page=1&per_page=10" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Șabloane

GET /api/templates Lista șabloanelor
# Parametri de query opționali: ?page=1&per_page=10 (per_page maximum 100).
# Fiecare șablon: uuid, name, language, category, status, components (așa cum le-a aprobat WhatsApp), variables (header, body, buttons: câți substituenți are fiecare parte), rejection (motivul respingerii, sau null), quality_score, updated_at.

curl -X GET \
"https://whapier.com/api/templates?page=1&per_page=10" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
GET /api/templates/{uuid} Detaliile unui șablon, cu un exemplu gata de trimis
# Obiectul șablon de la Lista șabloanelor plus example_payload: un corp complet pentru POST /api/send/template cu un parametru pentru fiecare substituent (exemplele cu care a fost trimis șablonul, altfel o valoare care numește poziția), un link pentru un antet media și un sufix pentru fiecare buton URL cu variabilă.
# Query opțional: whatsapp_connection (uuid-ul unei linii) când același șablon există pe mai multe linii. 404 pentru un uuid necunoscut.

curl -X GET \
https://whapier.com/api/templates/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/templates Creează șablon
# name (litere mici, cifre și underscore), category (MARKETING | UTILITY) și language (un cod de limbă Meta, de exemplu en sau pt_BR) sunt obligatorii; whatsapp_connection (uuid-ul unei linii WhatsApp Business) este opțional - altfel linia implicită.
# header (opțional): { format: TEXT, text (max 60, un singur {{1}} permis), examples } sau { format: IMAGE | VIDEO | DOCUMENT, media_url: un link https public către un fișier exemplu }.
# body.text (obligatoriu, max 1024, substituenți {{1}}, {{2}}, ...) cu body.examples, câte unul pentru fiecare substituent; footer (opțional, max 60); buttons (opțional, până la 10): { type: QUICK_REPLY | URL | PHONE_NUMBER | COPY_CODE, text, url, phone_number, example }.
# Răspuns: 200 { statusCode, uuid, status, message } - status este PENDING până îl verifică Meta (webhook-ul template.status.update te anunță). 400 cu motivul dat de Meta când Meta îl refuză; șabloanele AUTHENTICATION nu pot fi trimise încă prin API. O cheie sandbox nu poate trimite (403). Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/templates \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "name": "order_update",
    "category": "UTILITY",
    "language": "en",
    "header": {
        "format": "TEXT",
        "text": "Order {{1}}",
        "examples": [
            "48213"
        ]
    },
    "body": {
        "text": "Hi {{1}}, your order {{2}} ships on {{3}}.",
        "examples": [
            "Ana",
            "48213",
            "October 7"
        ]
    },
    "footer": "Example Shoes",
    "buttons": [
        {
            "type": "URL",
            "text": "Track",
            "url": "https://example.com/track/{{1}}",
            "example": "48213"
        },
        {
            "type": "QUICK_REPLY",
            "text": "Stop updates"
        }
    ]
}'
POST /api/templates/sync Sincronizează șabloanele de la Meta
# Fără corp. Preia de la Meta șabloanele fiecărei linii WhatsApp Business, așa cum face reîmprospătarea din panou, astfel încât un șablon modificat în Meta Business Manager apare și aici.
# Răspuns: { statusCode, synced, message } - synced este numărul de șabloane adăugate sau modificate. O cheie sandbox nu poate sincroniza (403); 400 când Meta a refuzat cererea.

curl -X POST \
https://whapier.com/api/templates/sync \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{}'

Webhook-uri

GET /api/webhooks Lista webhook-urilor
# Fiecare rând: uuid, url, events, secret_preview (ultimele șase caractere ale secretului de semnare), created_at, updated_at. Secretul complet este afișat o singură dată, în răspunsul la Adaugă webhook.
# 403 când modulul Webhooks nu este inclus în plan.

curl -X GET \
https://whapier.com/api/webhooks \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
GET /api/webhooks/events Lista evenimentelor
# Fiecare eveniment pe care îl poate primi un webhook: data (name, description). Pagina Webhook-uri din panou citește același catalog.
# O livrare este { event, data }; forma lui data pentru fiecare eveniment se găsește la Înainte să începi > Webhooks, iar POST /api/webhooks/{uuid}/test livrează un exemplu pentru oricare dintre ele.

curl -X GET \
https://whapier.com/api/webhooks/events \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/webhooks Adaugă webhook
# url (obligatoriu, https, unic per organizație) și events (obligatoriu, unul sau mai multe nume din GET /api/webhooks/events).
# Răspuns: { statusCode, uuid, secret, message } - singura dată când secretul complet este returnat; păstrează-l pentru a verifica X-Whapier-Signature. Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/webhooks \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "url": "https://example.com/hooks/whapier",
    "events": [
        "message.received",
        "message.status",
        "campaign.finished"
    ]
}'
PUT /api/webhooks/{uuid} Editează webhook
# Același corp ca la Adaugă webhook. Lista events o înlocuiește pe cea stocată; secretul rămâne neschimbat. 404 pentru un uuid necunoscut.

curl -X PUT \
https://whapier.com/api/webhooks/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "url": "https://example.com/hooks/whapier",
    "events": [
        "message.received",
        "message.status"
    ]
}'
DELETE /api/webhooks/{uuid} Șterge webhook
# Elimină endpoint-ul și abonările lui; nimic nu mai este livrat către el. Răspuns: { statusCode, uuid, message }. 404 pentru un uuid necunoscut.

curl -X DELETE \
https://whapier.com/api/webhooks/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/webhooks/{uuid}/test Trimite un eveniment de test
# event (obligatoriu): un nume din GET /api/webhooks/events. Payload-ul exemplu este trimis prin POST către url ca { event, data, test: true }, semnat cu secretul în X-Whapier-Signature.
# Răspuns: { statusCode, event, delivered, http_status, message } - delivered este false împreună cu starea cu care a răspuns endpoint-ul tău, sau http_status null când nu a putut fi contactat. 404 pentru un uuid necunoscut.

curl -X POST \
https://whapier.com/api/webhooks/{{uuid}}/test \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "event": "message.status"
}'

Starea mesajelor

GET /api/messages Lista mesajelor
# Query opțional: status (sent | delivered | read | failed | accepted | played), direction (inbound | outbound), since și until (date, UTC), contact (uuid-ul unui contact), campaign (uuid-ul unei campanii: mesajele produse de ea), wam_id (un mesaj după id-ul WhatsApp), api_key (uuid-ul unei chei, sau current: mesajele trimise cu cheia care face cererea), page, per_page (implicit 25, max 100).
# Răspuns: { statusCode, data: [ message ], meta: { page, per_page, total, last_page } }. 404 când contact, campaign sau api_key este necunoscut.
# Un mesaj: uuid, wam_id, direction, status, type, content, created_at, delivered_at, read_at, failed_at, failure (code, title, reason, retryable) sau null, pricing (category, model, billable, amount, currency, country), api_key (uuid, name) sau null când nu a fost trimis prin API, contact (uuid, phone, first_name, last_name).
# content după type - text: body, header, footer, buttons (type, text); template: name, language, body; image, video, audio, document, sticker: caption, media (type, url, filename); interactive și button: text, payload (ce a apăsat clientul); location: latitude, longitude, name, address; contacts: contacts (name, phones); reaction: emoji, wam_id.

curl -X GET \
"https://whapier.com/api/messages?status=failed&per_page=25" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
GET /api/contacts/{uuid}/messages Conversația cu un contact
# Aceleași obiecte mesaj ca la Lista mesajelor, pentru un singur contact, cele mai noi mai întâi. Query opțional: per_page (implicit 25, max 100), before (uuid-ul celui mai vechi mesaj pe care îl ai deja).
# Răspuns: { statusCode, data: [ message ], meta: { per_page, has_more, next_before } } - trimite next_before ca before pentru mesajele mai vechi. 404 pentru un contact sau un cursor necunoscut.

curl -X GET \
"https://whapier.com/api/contacts/{{uuid}}/messages?per_page=25" \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
GET /api/messages/{uuid} Detaliile unui mesaj
# Același obiect mesaj plus history: o listă de { status, timestamp, recorded_at }, fiecare schimbare de stare raportată de WhatsApp. 404 pentru un uuid necunoscut.

curl -X GET \
https://whapier.com/api/messages/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Utilizare

GET /api/usage Plan și utilizare
# Răspuns data: plan (name, status, valid_until), limits (contacts, messages, campaigns: used, limit; limit null = nelimitat), trial_daily_messages (doar conturile de trial), messages_sent (today, last_7_days, last_30_days), estimated_cost (last_30_days: amount, currency), rate_limit (per_minute).

curl -X GET \
https://whapier.com/api/usage \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'

Inbox

GET /api/conversations/{contact_uuid} Detaliile unei conversații
# Răspuns data: contact (uuid, phone, first_name, last_name), ticketing (dacă Setări > Tichete este pornit), ticket (status, assigned_to: name, email; opened_at, waiting_since, resolved_at) sau null, messages (uuid, wam_id, direction, type, text, status, created_at - cele mai noi 50, mai întâi), next_before.
# Query opțional: before (uuid-ul celui mai vechi mesaj pe care îl ai) pentru mesajele mai vechi; 400 când cursorul nu este un mesaj al acestui contact. 404 pentru un contact necunoscut.

curl -X GET \
https://whapier.com/api/conversations/{{uuid}} \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Accept: application/json'
POST /api/conversations/{contact_uuid}/assign Atribuie o conversație
# user_email (obligatoriu, poate fi null): emailul unui membru activ al organizației; null retrage atribuirea tichetului. O conversație fără tichet primește unul.
# Răspuns: { statusCode, data: ticket, message } cu tichetul așa cum îl arată Detaliile unei conversații. 409 cât timp ticketingul este oprit; 422 când niciun membru activ al organizației nu are acel email; 404 pentru un contact necunoscut.

curl -X POST \
https://whapier.com/api/conversations/{{uuid}}/assign \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "user_email": "maria@example.com"
}'
POST /api/conversations/{contact_uuid}/close Închide o conversație
# Fără corp. Rezolvă tichetul (status closed, resolved_at setat), ca butonul din inbox. Răspuns: { statusCode, data: ticket, message }.
# 409 cât timp ticketingul este oprit; 404 pentru un contact necunoscut.

curl -X POST \
https://whapier.com/api/conversations/{{uuid}}/close \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{}'
POST /api/conversations/{contact_uuid}/reopen Redeschide o conversație
# Fără corp. Redeschide un tichet închis (status open, resolved_at golit); un tichet deschis este returnat așa cum este. Răspuns: { statusCode, data: ticket, message }.
# 409 cât timp ticketingul este oprit; 404 pentru un contact necunoscut.

curl -X POST \
https://whapier.com/api/conversations/{{uuid}}/reopen \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{}'
POST /api/conversations/{contact_uuid}/notes Adaugă o notă internă
# note (obligatoriu, max 5000): vizibilă agenților în fir, niciodată trimisă contactului. Funcționează indiferent dacă ticketingul este pornit sau oprit.
# Răspuns: { statusCode, uuid, created_at, message }. 404 pentru un contact necunoscut. Acceptă un antet Idempotency-Key.

curl -X POST \
https://whapier.com/api/conversations/{{uuid}}/notes \
-H 'Authorization: Bearer <YOUR_AUTHORIZATION_TOKEN>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
    "note": "Customer called; wants the order delivered on Friday."
}'

Obține o cheie API în două minute

Probă gratuită, fără card — panoul de dezvoltator este inclus în fiecare plan.

Începe proba gratuită