MENU navbar-image

Introduction

Türkçe REST API referansı — kanal entegrasyonları, voice/sip, randevu sistemi, fonksiyon gateway.

DoWaba REST API ile kendi sistemini DoWaba'nın çok kanallı altyapısına entegre edebilirsin: WhatsApp, Instagram DM, Telegram, e-posta, web widget, SMS ve AI Voice (telefon).

Buradan başla

  1. Token üret: Panel → Ayarlar → API Anahtarı (Bearer token). Sunucu-sunucu entegrasyonlar için dsk_ prefix'li External API Key kullanılır.
  2. İlk isteğini at:
curl https://dowaba.com/api/auth/user \
  -H "Authorization: Bearer TOKEN" \
  -H "Accept: application/json"
  1. Yanıtları işle: Tüm yanıtlar JSON'dır. Kimliksiz istek 401 ({"message": "Unauthenticated."}), doğrulama hatası 422 ({"message": "...", "errors": {...}}), yetki dışı kaynak 403 döner.

Hız limitleri: Kötüye kullanıma açık uçlarda istek limitleri uygulanır (örn. token üretimi 10 istek/dk, webhook testi 10 istek/dk). Limit aşımında 429 Too Many Requests ve Retry-After header'ı döner — istemcin bu header'a saygı göstermeli.

Erişim modeli: Tüm kaynaklar hesap kapsamına (tenant) bağlıdır — yalnızca sahibi olduğun veya yetkilendirildiğin (bayi/ekip erişimi) site, kanal ve konuşmalara erişebilirsin.

Makine-okur formatlar: Postman collection · OpenAPI 3 spec

Sağdaki kod örnekleri otomatik üretilir: curl, JavaScript (axios), PHP (Guzzle). Üst sekmeden değiştirebilirsin. Her endpoint için "Try It Out" butonuyla canlı bir istek atıp gerçek response'u görebilirsin (Bearer token girmeyi unutma).

🚀 Hızlı başlangıç + örnek projeler için: /api-docs-ornekler — Laravel Bridge, saf-PHP snippet, widget embed, webhook receiver, AI prompt template'leri ve composer/npm paket listesi.

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Token, Panel → Ayarlar → API Anahtarı menüsünden üretilir. Sunucu-sunucu (server-to-server) entegrasyonlarda dsk_ prefix'li External API Key kullanılabilir; bu durumda X-API-Key header'ı gönderilir.

Yönetici / Genel Bakış

Bayinin müşterilerini listele. Kart grid için zenginleştirilmiş.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/customers?search=ali&is_active=1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers"
);

const params = {
    "search": "ali",
    "is_active": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
        'query' => [
            'search' => 'ali',
            'is_active' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "data": [
        {
            "id": 12,
            "name": "Test Müşteri",
            "email": "u***@example.com",
            "phone": "+90 555 *** ** **",
            "is_active": true,
            "sites_count": 2,
            "active_licenses_count": 2,
            "created_at": "2026-05-01T10:00:00.000000Z"
        }
    ],
    "count": 1
}
 

Example response (403, Reseller sözleşmesi imzalanmamış):


{
    "success": false,
    "error": "Bayi sözleşmesini imzalamadan müşterilerinizi göremezsiniz."
}
 

Request      

GET api/reseller/customers

Headers

Authorization        

Example: Bearer {TOKEN}

Query Parameters

search   string  optional    

İsim/email/telefon ara. Example: ali

is_active   boolean  optional    

Aktif filtre. Example: true

Admin Manuel Abonelik

Havale/EFT ile ödeme yapan kullanıcılara abonelik aktivasyonu yapar:

  1. paytr_payments tablosuna manual_transfer kaydı
  2. SubscriptionService::activateSubscription
  3. Paraşüt — contact + sales invoice + e-archive
  4. Müşteriye + admin'e (CC) onay maili

Idempotent değil — tekrar çağrılırsa yeni subscription + yeni invoice oluşur. Çağrı eden admin kullanıcı kredilerini panelden manuel ekler/değiştirir.

Manuel aktivasyona uygun planları dön (frontend dropdown'u için).

Son-müşteri planları: Starter / Pro / Premium / Ultimate.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscription-plans"
const url = new URL(
    "https://dowaba.com/api/subscription-plans"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscription-plans';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscription-plans

Kullanıcı Yönetimi

Yeni kullanıcı kaydı (e-posta + telefon + parola). Spam koruma + e-posta doğrulama maili.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/register" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Test Kullanıcı\",
    \"phone\": \"+905551234567\",
    \"email\": \"user@example.com\",
    \"password\": \"GucluParola123\",
    \"consents\": {
        \"terms\": true,
        \"privacy\": true,
        \"yurtdisi\": true,
        \"cagri_kayit\": true,
        \"marketing\": true,
        \"analytics\": false,
        \"cookie_marketing\": false
    },
    \"timezone\": \"Africa\\/Brazzaville\",
    \"password_confirmation\": \"GucluParola123\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/register"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Test Kullanıcı",
    "phone": "+905551234567",
    "email": "user@example.com",
    "password": "GucluParola123",
    "consents": {
        "terms": true,
        "privacy": true,
        "yurtdisi": true,
        "cagri_kayit": true,
        "marketing": true,
        "analytics": false,
        "cookie_marketing": false
    },
    "timezone": "Africa\/Brazzaville",
    "password_confirmation": "GucluParola123"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/register';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Test Kullanıcı',
            'phone' => '+905551234567',
            'email' => 'user@example.com',
            'password' => 'GucluParola123',
            'consents' => [
                'terms' => true,
                'privacy' => true,
                'yurtdisi' => true,
                'cagri_kayit' => true,
                'marketing' => true,
                'analytics' => false,
                'cookie_marketing' => false,
            ],
            'timezone' => 'Africa/Brazzaville',
            'password_confirmation' => 'GucluParola123',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "success": true,
    "user": {
        "id": 42,
        "name": "Test Kullanıcı",
        "email": "u***@example.com",
        "role": "user",
        "credits": 1000,
        "email_verified_at": null
    },
    "token": "[REDACTED]",
    "message": "Hesabınız oluşturuldu. E-postanızı doğrulamak için maili kontrol edin."
}
 

Example response (422, KVKK onayları eksik):


{
    "success": false,
    "error": "Zorunlu onaylar eksik: hizmet sözleşmesi, gizlilik, yurt dışı aktarım ve çağrı kayıt onaylarını işaretlemeniz gerekir.",
    "missing_consents": [
        "yurtdisi",
        "cagri_kayit"
    ]
}
 

Example response (422, Spam guard reddetti):


{
    "success": false,
    "error": "Geçersiz e-posta domain'i."
}
 

Example response (422, Doğrulama hatası):


{
    "message": "The given data was invalid.",
    "errors": {
        "email": [
            "The email has already been taken."
        ]
    }
}
 

Request      

POST api/auth/register

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Ad soyad. Example: Test Kullanıcı

phone   string     

Telefon (E.164 önerilir). Example: +905551234567

email   string     

E-posta (unique). Example: user@example.com

password   string     

Min 8 karakter, confirmation alanı zorunlu. Example: GucluParola123

consents   object  optional    

KVKK onayları. Zorunlu: terms, privacy, yurtdisi, cagri_kayit. Opsiyonel: marketing, analytics, cookie_marketing.

terms   boolean     

Hizmet sözleşmesi onayı. Example: true

privacy   boolean     

Gizlilik politikası onayı. Example: true

yurtdisi   boolean     

Yurt dışı veri aktarım onayı. Example: true

cagri_kayit   boolean     

Çağrı kayıt onayı. Example: true

marketing   boolean  optional    

Example: true

analytics   boolean  optional    

Example: false

cookie_marketing   boolean  optional    

Example: false

timezone   string  optional    

Saat dilimi — kayıt formu tarayıcıdan otomatik algılar (Intl.DateTimeFormat().resolvedOptions().timeZone). Geçersiz/yoksa null → frontend Europe/Istanbul varsayar. Tüm geçerli IANA tanımı kabul. Must not be greater than 64 characters. Example: Africa/Brazzaville

password_confirmation   string     

password ile aynı. Example: GucluParola123

E-posta + parola ile giriş. Aktif 2FA metodu varsa full token VERİLMEZ; yerine kısa-ömürlü interim_token + requires_2fa döner. Challenge başarılı olduğunda /api/auth/2fa/challenge endpoint'i Sanctum token üretir.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/login" \
    --header "Content-Type: application/json" \
    --data "{
    \"email\": \"user@example.com\",
    \"password\": \"GucluParola123\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/login"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "user@example.com",
    "password": "GucluParola123"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/login';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'email' => 'user@example.com',
            'password' => 'GucluParola123',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Başarılı (2FA kapalı)):


{
    "success": true,
    "user": {
        "id": 42,
        "name": "Test Kullanıcı",
        "email": "u***@example.com",
        "phone": "+90 555 *** ** **",
        "role": "user",
        "is_active": true,
        "credits": 1000,
        "allowed_modules": null,
        "assigned_site_id": null,
        "is_agent_only": false,
        "reseller_id": null,
        "locale": "tr"
    },
    "token": "[REDACTED]",
    "modules": [
        "appointment",
        "saas"
    ]
}
 

Example response (200, 2FA gerekli):


{
    "success": true,
    "requires_2fa": true,
    "interim_token": "[REDACTED]",
    "available_methods": [
        "totp",
        "email"
    ]
}
 

Example response (401):


{
    "success": false,
    "error": "E-posta veya parola hatalı."
}
 

Example response (403):


{
    "success": false,
    "error": "Hesabınız pasif duruma alınmış. Yönetici ile iletişime geçin."
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "email": [
            "The email field is required."
        ]
    }
}
 

Example response (429):


{
    "success": false,
    "error": "Çok fazla hatalı deneme. Lütfen 42 saniye sonra tekrar deneyin.",
    "retry_after": 42
}
 

Request      

POST api/auth/login

Headers

Content-Type        

Example: application/json

Body Parameters

email   string     

Kullanıcı e-postası. Example: user@example.com

password   string     

Parola. Example: GucluParola123

Doğrulama mailini tekrar gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/resend-verification" \
    --header "Content-Type: application/json" \
    --data "{
    \"email\": \"qkunze@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/resend-verification"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "qkunze@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/resend-verification';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'email' => 'qkunze@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/resend-verification

Headers

Content-Type        

Example: application/json

Body Parameters

email   string     

Must be a valid email address. Example: qkunze@example.com

Şifre sıfırlama linki gönder. E-posta varsa MailAccount cascade ile (parent → reseller → site → system fallback) mail çıkışına gider.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/forgot-password" \
    --header "Content-Type: application/json" \
    --data "{
    \"email\": \"user@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/forgot-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "user@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/forgot-password';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'email' => 'user@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "message": "Şifre sıfırlama bağlantısı e-posta adresinize gönderildi."
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "email": [
            "The email field is required."
        ]
    }
}
 

Example response (429):


{
    "message": "Too Many Attempts."
}
 

Request      

POST api/auth/forgot-password

Headers

Content-Type        

Example: application/json

Body Parameters

email   string     

Kullanıcı e-postası. Example: user@example.com

Token ile şifre sıfırlama (forgot-password sonrası).

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/reset-password" \
    --header "Content-Type: application/json" \
    --data "{
    \"token\": null,
    \"email\": \"carolyne.luettgen@example.org\",
    \"password\": \"ij-e\\/dl4m\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/reset-password"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "token": null,
    "email": "carolyne.luettgen@example.org",
    "password": "ij-e\/dl4m"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/reset-password';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'token' => null,
            'email' => 'carolyne.luettgen@example.org',
            'password' => 'ij-e/dl4m',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/reset-password

Headers

Content-Type        

Example: application/json

Body Parameters

token   string     

Şifre sıfırlama e-postasındaki bağlantıdan gelen token.

email   string     

Must be a valid email address. Example: carolyne.luettgen@example.org

password   string     

Must be at least 8 characters. Example: ij-e/dl4m

Google ile giriş/kayıt (id_token doğrulaması). Kullanıcı yoksa otomatik oluşturulur (email_verified_at=now, credits=1000, provider='google').

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/google" \
    --header "Content-Type: application/json" \
    --data "{
    \"id_token\": \"eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3M...\",
    \"consents\": {
        \"terms\": false,
        \"privacy\": false,
        \"yurtdisi\": true,
        \"cagri_kayit\": false,
        \"marketing\": false,
        \"analytics\": true,
        \"cookie_marketing\": true
    }
}"
const url = new URL(
    "https://dowaba.com/api/auth/google"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3M...",
    "consents": {
        "terms": false,
        "privacy": false,
        "yurtdisi": true,
        "cagri_kayit": false,
        "marketing": false,
        "analytics": true,
        "cookie_marketing": true
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/google';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'id_token' => 'eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3M...',
            'consents' => [
                'terms' => false,
                'privacy' => false,
                'yurtdisi' => true,
                'cagri_kayit' => false,
                'marketing' => false,
                'analytics' => true,
                'cookie_marketing' => true,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "user": {
        "id": 42,
        "name": "Test Kullanıcı",
        "email": "u***@example.com",
        "avatar_url": "https://lh3.googleusercontent.com/a/example",
        "role": "user",
        "provider": "google",
        "email_verified_at": "2026-05-19T14:23:11.000000Z"
    },
    "token": "[REDACTED]",
    "modules": [
        "appointment",
        "saas"
    ]
}
 

Example response (401, Google doğrulama fail):


{
    "success": false,
    "error": "Google doğrulama başarısız."
}
 

Example response (401, Audience mismatch):


{
    "success": false,
    "error": "Google token bu uygulamaya ait değil."
}
 

Example response (403, E-posta doğrulanmamış):


{
    "success": false,
    "error": "Google e-posta adresi doğrulanmamış."
}
 

Example response (422):


{
    "success": false,
    "error": "Google hesabından e-posta alınamadı."
}
 

Example response (500, Backend Google config yok):


{
    "success": false,
    "error": "Google girişi yapılandırılmamış."
}
 

Request      

POST api/auth/google

Headers

Content-Type        

Example: application/json

Body Parameters

id_token   string     

Google Sign-In'den dönen JWT id_token. Example: eyJhbGciOiJSUzI1NiIsImtpZCI6IjE3M...

consents   object  optional    

KVKK Faz 4: OAuth ile YENİ kayıt için 4 zorunlu + 3 opsiyonel consent. Mevcut user girişinde göz ardı edilir (login flow).

terms   boolean  optional    

Example: false

privacy   boolean  optional    

Example: false

yurtdisi   boolean  optional    

Example: true

cagri_kayit   boolean  optional    

Example: false

marketing   boolean  optional    

Example: false

analytics   boolean  optional    

Example: true

cookie_marketing   boolean  optional    

Example: true

Apple ile giriş/kayıt (id_token doğrulaması).

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/apple" \
    --header "Content-Type: application/json" \
    --data "{
    \"id_token\": null,
    \"name\": \"mqeopfuudtdsufvyvddqa\",
    \"consents\": {
        \"terms\": false,
        \"privacy\": false,
        \"yurtdisi\": false,
        \"cagri_kayit\": false,
        \"marketing\": true,
        \"analytics\": false,
        \"cookie_marketing\": true
    }
}"
const url = new URL(
    "https://dowaba.com/api/auth/apple"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id_token": null,
    "name": "mqeopfuudtdsufvyvddqa",
    "consents": {
        "terms": false,
        "privacy": false,
        "yurtdisi": false,
        "cagri_kayit": false,
        "marketing": true,
        "analytics": false,
        "cookie_marketing": true
    }
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/apple';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'id_token' => null,
            'name' => 'mqeopfuudtdsufvyvddqa',
            'consents' => [
                'terms' => false,
                'privacy' => false,
                'yurtdisi' => false,
                'cagri_kayit' => false,
                'marketing' => true,
                'analytics' => false,
                'cookie_marketing' => true,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/apple

Headers

Content-Type        

Example: application/json

Body Parameters

id_token   string     

Apple Sign In'den dönen JWT id_token.

name   string  optional    

Must not be greater than 255 characters. Example: mqeopfuudtdsufvyvddqa

consents   object  optional    

KVKK Faz 4 (2026-05-24): OAuth ile YENİ kayıt için consent.

terms   boolean  optional    

Example: false

privacy   boolean  optional    

Example: false

yurtdisi   boolean  optional    

Example: false

cagri_kayit   boolean  optional    

Example: false

marketing   boolean  optional    

Example: true

analytics   boolean  optional    

Example: false

cookie_marketing   boolean  optional    

Example: true

Passkey ile parolasız giriş için seçenekler. `email` opsiyonel — boş ise discoverable credential listesi (cihazda kayıtlı tüm dowaba.com passkey'leri) gösterilir.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/passkey/login/options" \
    --header "Content-Type: application/json" \
    --data "{
    \"email\": \"qkunze@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/passkey/login/options"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "qkunze@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/passkey/login/options';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'email' => 'qkunze@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/passkey/login/options

Headers

Content-Type        

Example: application/json

Body Parameters

email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: qkunze@example.com

`navigator.credentials.get()`'ten dönen assertion'u doğrula → Sanctum token döndür.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/passkey/login/verify" \
    --header "Content-Type: application/json" \
    --data "{
    \"credential\": {
        \"id\": \"vmqeopfuudtdsufvyvddq\",
        \"rawId\": null,
        \"type\": \"public-key\",
        \"response\": []
    },
    \"challenge_ref\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/passkey/login/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "credential": {
        "id": "vmqeopfuudtdsufvyvddq",
        "rawId": null,
        "type": "public-key",
        "response": []
    },
    "challenge_ref": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/passkey/login/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'credential' => [
                'id' => 'vmqeopfuudtdsufvyvddq',
                'rawId' => null,
                'type' => 'public-key',
                'response' => [],
            ],
            'challenge_ref' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/passkey/login/verify

Headers

Content-Type        

Example: application/json

Body Parameters

credential   object     
id   string     

Must not be greater than 1024 characters. Example: vmqeopfuudtdsufvyvddq

rawId   string     

WebAuthn credential ham kimliği (base64url).

type   string     

Example: public-key

Must be one of:
  • public-key
response   object     
challenge_ref   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

Mevcut access token'ı iptal eder ve session'ı temizler.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/logout" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/auth/logout"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/logout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "message": "Çıkış yapıldı."
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Request      

POST api/auth/logout

Headers

Authorization        

Example: Bearer {TOKEN}

Hesap silme için e-posta doğrulama kodu gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/account/delete-request"
const url = new URL(
    "https://dowaba.com/api/auth/account/delete-request"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/account/delete-request';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/account/delete-request

E-posta kodunu doğrula, hesabı ve tüm ilişkili verileri kalıcı sil.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/account/confirm-delete" \
    --header "Content-Type: application/json" \
    --data "{
    \"code\": \"vmqeop\",
    \"confirmation\": \"fuudtdsufvyvddqamniih\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/account/confirm-delete"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "vmqeop",
    "confirmation": "fuudtdsufvyvddqamniih"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/account/confirm-delete';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'code' => 'vmqeop',
            'confirmation' => 'fuudtdsufvyvddqamniih',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/account/confirm-delete

Headers

Content-Type        

Example: application/json

Body Parameters

code   string  optional    

Must be 6 characters. Example: vmqeop

confirmation   string  optional    

Must not be greater than 32 characters. Example: fuudtdsufvyvddqamniih

Mevcut kullanıcının kayıtlı passkey'leri.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/profile/passkeys"
const url = new URL(
    "https://dowaba.com/api/profile/passkeys"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/passkeys';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/profile/passkeys

Yeni passkey kaydı için seçenekleri (challenge + RP + user) üret. Frontend bu cevabı `navigator.credentials.create({ publicKey: ... })`'a verir.

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/passkeys/register/options"
const url = new URL(
    "https://dowaba.com/api/profile/passkeys/register/options"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/passkeys/register/options';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/passkeys/register/options

`navigator.credentials.create()`'den dönen credential'ı doğrula ve kaydet.

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/passkeys/register/verify" \
    --header "Content-Type: application/json" \
    --data "{
    \"credential\": {
        \"id\": \"vmqeopfuudtdsufvyvddq\",
        \"rawId\": null,
        \"type\": \"public-key\",
        \"response\": []
    },
    \"device_name\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/profile/passkeys/register/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "credential": {
        "id": "vmqeopfuudtdsufvyvddq",
        "rawId": null,
        "type": "public-key",
        "response": []
    },
    "device_name": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/passkeys/register/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'credential' => [
                'id' => 'vmqeopfuudtdsufvyvddq',
                'rawId' => null,
                'type' => 'public-key',
                'response' => [],
            ],
            'device_name' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/passkeys/register/verify

Headers

Content-Type        

Example: application/json

Body Parameters

credential   object     
id   string     

Must not be greater than 1024 characters. Example: vmqeopfuudtdsufvyvddq

rawId   string     

WebAuthn credential ham kimliği (base64url).

type   string     

Example: public-key

Must be one of:
  • public-key
response   object     
device_name   string  optional    

Must not be greater than 80 characters. Example: vmqeopfuudtdsufvyvddq

Bir passkey'i sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/profile/passkeys/1562"
const url = new URL(
    "https://dowaba.com/api/profile/passkeys/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/passkeys/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/profile/passkeys/{id}

URL Parameters

id   string     

The ID of the passkey. Example: 1562

Ayarlar & Profil

Medya dosyası yükleme + listeleme + silme.

Endpoint: POST /api/media/upload — dosya yükle (multipart/form-data) GET /api/media — kullanıcının dosyaları (snippet picker'da seçim için) DELETE /api/media/{id} — dosya sil (cascade: snippet.media_file_id null'a düşer)

Storage: 'public' disk → storage/app/public/media//. Public URL: APP_URL/storage/media//.

WhatsApp / Meta limitler (request validation):

GET api/media

Example request:
curl --request GET \
    --get "https://dowaba.com/api/media"
const url = new URL(
    "https://dowaba.com/api/media"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/media';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/media

POST api/media/upload

Example request:
curl --request POST \
    "https://dowaba.com/api/media/upload" \
    --header "Content-Type: multipart/form-data" \
    --form "file=@/tmp/phpQiDKd4" 
const url = new URL(
    "https://dowaba.com/api/media/upload"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('file', document.querySelector('input[name="file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/media/upload';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'file',
                'contents' => fopen('/tmp/phpQiDKd4', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/media/upload

Headers

Content-Type        

Example: multipart/form-data

Body Parameters

file   file     

Must be a file. Example: /tmp/phpQiDKd4

DELETE api/media/{id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/media/1562"
const url = new URL(
    "https://dowaba.com/api/media/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/media/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/media/{id}

URL Parameters

id   string     

The ID of the medium. Example: 1562

Mevcut kullanıcı profili + site sayısı + krediler.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/user"
const url = new URL(
    "https://dowaba.com/api/user"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/user';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/user

Kullanıcı profil bilgilerini güncelle (ad, e-posta, parola).

Example request:
curl --request PUT \
    "https://dowaba.com/api/user" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"email\": \"kunde.eloisa@example.com\",
    \"password\": \"[2UZ5ij-e\\/dl4\"
}"
const url = new URL(
    "https://dowaba.com/api/user"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "email": "kunde.eloisa@example.com",
    "password": "[2UZ5ij-e\/dl4"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/user';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'email' => 'kunde.eloisa@example.com',
            'password' => '[2UZ5ij-e/dl4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/user

Headers

Content-Type        

Example: application/json

Body Parameters

name   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

email   string  optional    

Must be a valid email address. Example: kunde.eloisa@example.com

current_password   string  optional    

Parola değiştirilirken zorunlu; kullanıcının mevcut parolası.

password   string  optional    

Must be at least 8 characters. Example: [2UZ5ij-e/dl4

Kullanıcının UI dil tercihini günceller. Sanctum auth zorunlu. NULL kabul edilir = "tercih sıfırlama" — SetLocale middleware bundan sonra Accept-Language header'ı üzerinden karar verir (tarayıcı diline geri döner). AI yanıt dili (sites.languages) bu endpoint ile DEĞİŞMEZ — ayrı konsept.

Example request:
curl --request PUT \
    "https://dowaba.com/api/user/locale" \
    --header "Content-Type: application/json" \
    --data "{
    \"locale\": \"so_ET\"
}"
const url = new URL(
    "https://dowaba.com/api/user/locale"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "locale": "so_ET"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/user/locale';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'locale' => 'so_ET',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/user/locale

Headers

Content-Type        

Example: application/json

Body Parameters

locale   string  optional    

Example: so_ET

Mevcut kullanıcı bilgileri + site sayısı + krediler + kullanım özeti.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/auth/user" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/auth/user"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/user';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "user": {
        "id": 42,
        "name": "Test Kullanıcı",
        "email": "u***@example.com",
        "phone": "+90 555 *** ** **",
        "role": "user",
        "is_active": true,
        "credits": 1000,
        "allowed_modules": null,
        "assigned_site_id": null,
        "is_agent_only": false,
        "reseller_id": null,
        "parent_user_id": null,
        "locale": "tr",
        "app_name": null,
        "app_logo_url": null,
        "app_primary_color": null,
        "sites": [
            {
                "id": 1,
                "name": "Demo Site",
                "domain": "example.com",
                "is_active": true
            }
        ]
    },
    "stats": {
        "sites_count": 1,
        "credits": 1000,
        "monthly_usage": 0
    },
    "usage": {
        "messages_sent": 0,
        "ai_calls": 0,
        "voice_minutes": 0
    },
    "modules": [
        "appointment",
        "saas"
    ]
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Request      

GET api/auth/user

Headers

Authorization        

Example: Bearer {TOKEN}

Kullanıcı profilini güncelle (ad, e-posta, parola).

requires authentication

Example request:
curl --request PUT \
    "https://dowaba.com/api/auth/profile" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Test Kullanıcı\",
    \"email\": \"user@example.com\",
    \"phone\": \"+905551234567\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/profile"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Test Kullanıcı",
    "email": "user@example.com",
    "phone": "+905551234567"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/profile';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Test Kullanıcı',
            'email' => 'user@example.com',
            'phone' => '+905551234567',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "user": {
        "id": 42,
        "name": "Test Kullanıcı",
        "email": "u***@example.com",
        "phone": "+90 555 *** ** **"
    },
    "message": "Profil güncellendi."
}
 

Example response (422, Mevcut parola hatalı):


{
    "success": false,
    "error": "Mevcut parolanız hatalı."
}
 

Example response (422, Doğrulama hatası):


{
    "message": "The given data was invalid.",
    "errors": {
        "new_password": "[REDACTED]"
    }
}
 

Request      

PUT api/auth/profile

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

name   string  optional    

Yeni ad soyad. Example: Test Kullanıcı

email   string  optional    

Yeni e-posta (unique). Example: user@example.com

current_password   string  optional    

Parola değişikliği için mevcut parola gerekli.

new_password   string  optional    

Yeni parola (min 8 karakter, confirmation alanı zorunlu).

phone   string  optional    

Yeni telefon. Example: +905551234567

new_password_confirmation   string  optional    

Yeni parola tekrar.

2FA

Kullanıcının kurulu 2FA metodları + recovery code sayısı.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/profile/2fa/methods"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/methods"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/methods';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/profile/2fa/methods

2FA - Login

Login challenge öncesi SMS/Email yöntemi seçildiğinde kod tetikler. TOTP için gereksiz (kod uygulamadan üretilir).

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/2fa/send-code" \
    --header "Content-Type: application/json" \
    --data "{
    \"interim_token\": null,
    \"method\": \"sms\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/2fa/send-code"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "interim_token": null,
    "method": "sms"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/2fa/send-code';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'interim_token' => null,
            'method' => 'sms',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/2fa/send-code

Headers

Content-Type        

Example: application/json

Body Parameters

interim_token   string     

Login yanıtında dönen geçici 2FA oturum token'ı.

method   string     

Example: sms

Must be one of:
  • sms
  • email

interim_token + method + code → full sanctum token. Yanlış kod 5 deneme/saat per token (RateLimiter).

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/2fa/challenge" \
    --header "Content-Type: application/json" \
    --data "{
    \"interim_token\": null,
    \"method\": \"email\",
    \"code\": \"mqeopfu\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/2fa/challenge"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "interim_token": null,
    "method": "email",
    "code": "mqeopfu"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/2fa/challenge';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'interim_token' => null,
            'method' => 'email',
            'code' => 'mqeopfu',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/2fa/challenge

Headers

Content-Type        

Example: application/json

Body Parameters

interim_token   string     

Login yanıtında dönen geçici 2FA oturum token'ı.

method   string     

Example: email

Must be one of:
  • totp
  • sms
  • email
code   string     

Must not be greater than 8 characters. Example: mqeopfu

Recovery code ile bypass. Tek kullanımlık.

Example request:
curl --request POST \
    "https://dowaba.com/api/auth/2fa/recovery" \
    --header "Content-Type: application/json" \
    --data "{
    \"interim_token\": null,
    \"recovery_code\": \"mqeopfuu\"
}"
const url = new URL(
    "https://dowaba.com/api/auth/2fa/recovery"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "interim_token": null,
    "recovery_code": "mqeopfuu"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/auth/2fa/recovery';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'interim_token' => null,
            'recovery_code' => 'mqeopfuu',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/auth/2fa/recovery

Headers

Content-Type        

Example: application/json

Body Parameters

interim_token   string     

Login yanıtında dönen geçici 2FA oturum token'ı.

recovery_code   string     

Must be 8 characters. Example: mqeopfuu

i18n

Frontend için meta endpoint — desteklenen locale listesi + native etiketler. Dropdown UI bunu çağırır; dil ekleme/çıkarma değişikliği bundle rebuild gerektirmez, sadece config/i18n.php güncellenir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/i18n/meta"
const url = new URL(
    "https://dowaba.com/api/i18n/meta"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/i18n/meta';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: max-age=300, public
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 115
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "supported": [
        "tr",
        "en",
        "ru",
        "de",
        "ar",
        "fr",
        "it"
    ],
    "fallback": "tr",
    "labels": {
        "tr": "Türkçe",
        "en": "English",
        "ru": "Русский",
        "de": "Deutsch",
        "ar": "العربية",
        "fr": "Français",
        "it": "Italiano"
    },
    "default": "en"
}
 

Request      

GET api/i18n/meta

Belirtilen locale'in tüm UI çeviri sözlüğünü nested JSON olarak döner. Public — auth gerekmez (widget cold-start, login öncesi admin gibi unauthenticated senaryolarda da bu endpoint çağrılır). Response shape: { "locale": "tr", "version": "ab12cd34ef56", "translations": { "common": {...}, "admin": {...}, "widget": {...}, ... } } Hata davranışı: - locale supported listede değil → 404 - dosya yok ama supported → 500 (server config eksikliği)

Example request:
curl --request GET \
    --get "https://dowaba.com/api/i18n/fu-ud.json"
const url = new URL(
    "https://dowaba.com/api/i18n/fu-ud.json"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/i18n/fu-ud.json';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 114
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "success": false,
    "error": "Locale not supported",
    "supported": [
        "tr",
        "en",
        "ru",
        "de",
        "ar",
        "fr",
        "it"
    ]
}
 

Request      

GET api/i18n/{locale}.json

URL Parameters

locale   string     

Example: fu-ud

Siteler

Kullanıcının sitelerini listele. Bayi token'ı ile çağırılırsa bayinin müşterilerinin tüm siteleri de döner (reseller_id cascade).

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "Demo Site",
            "domain": "example.com",
            "user_id": 42,
            "api_key": "[REDACTED]",
            "is_active": true,
            "system_prompt": "[REDACTED]",
            "widget_color": "#4f46e5",
            "subscription_id": 7,
            "created_at": "2026-05-01T10:00:00.000000Z",
            "updated_at": "2026-05-19T14:23:11.000000Z"
        }
    ]
}
 

Example response (401):


{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites

Headers

Authorization        

Example: Bearer {TOKEN}

Yeni site oluştur (hibrit slot/pay_per_site akışı — SUBSCRIPTION_ARCHITECTURE.md): Business slot varsa ücretsiz; slot dolu + bayi ise 402 onay → pay_per_site (3.999₺/yıl); slot yok + bayi değil → 403 requires_upgrade.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/sites" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Demo Site\",
    \"domain\": \"example.com\",
    \"widget_color\": \"#4f46e5\",
    \"widget_position\": \"bottom-right\",
    \"welcome_message\": \"dtdsufvyvddqamniihfqc\",
    \"bot_name\": \"oynlazghdtqtqxbajwbpi\",
    \"ai_enabled\": false,
    \"similarity_threshold\": 1,
    \"confirm_paid_site\": true,
    \"system_prompt\": \"Sen bir destek asistanısın\",
    \"confirm_pay_per_site\": false
}"
const url = new URL(
    "https://dowaba.com/api/sites"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Demo Site",
    "domain": "example.com",
    "widget_color": "#4f46e5",
    "widget_position": "bottom-right",
    "welcome_message": "dtdsufvyvddqamniihfqc",
    "bot_name": "oynlazghdtqtqxbajwbpi",
    "ai_enabled": false,
    "similarity_threshold": 1,
    "confirm_paid_site": true,
    "system_prompt": "Sen bir destek asistanısın",
    "confirm_pay_per_site": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Demo Site',
            'domain' => 'example.com',
            'widget_color' => '#4f46e5',
            'widget_position' => 'bottom-right',
            'welcome_message' => 'dtdsufvyvddqamniihfqc',
            'bot_name' => 'oynlazghdtqtqxbajwbpi',
            'ai_enabled' => false,
            'similarity_threshold' => 1,
            'confirm_paid_site' => true,
            'system_prompt' => 'Sen bir destek asistanısın',
            'confirm_pay_per_site' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "success": true,
    "site": {
        "id": 7,
        "name": "Demo Site",
        "domain": "example.com",
        "api_key": "[REDACTED]",
        "user_id": 42,
        "subscription_id": 5,
        "is_active": true,
        "created_at": "2026-05-19T14:23:11.000000Z"
    },
    "billing": {
        "mode": "subscription_slot",
        "remaining_slots": 4
    }
}
 

Example response (402, Slot dolu + bayi onayı bekleniyor):


{
    "success": false,
    "error": "Site slot'unuz dolu. Onaylarsanız bu site için ayrı yıllık lisans (3.999₺) açılır.",
    "requires_confirmation": true,
    "billing_mode": "pay_per_site",
    "annual_price_try": 3999
}
 

Example response (403, Slot yok + bayi değil — paket yükseltme):


{
    "success": false,
    "error": "Site limitiniz dolu. Business pakete geçin veya site sayısını arttırın.",
    "requires_upgrade": true
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "domain": [
            "The domain has already been taken."
        ]
    }
}
 

Request      

POST api/sites

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

name   string     

Site adı. Example: Demo Site

domain   string     

Domain (eşsiz). Example: example.com

widget_color   string  optional    

Widget rengi (hex). Example: #4f46e5

widget_position   string  optional    

Example: bottom-right

Must be one of:
  • bottom-right
  • bottom-left
welcome_message   string  optional    

Must not be greater than 500 characters. Example: dtdsufvyvddqamniihfqc

bot_name   string  optional    

Must not be greater than 50 characters. Example: oynlazghdtqtqxbajwbpi

ai_enabled   boolean  optional    

Example: false

similarity_threshold   number  optional    

Must be at least 0.5. Must not be greater than 1. Example: 1

confirm_paid_site   boolean  optional    

Example: true

languages   string[]  optional    
default_widget_locale   string  optional    

Widget UI dili — sites.languages (AI dil seti) ile FARKLI bir alan. NULL → embed data-locale veya browser yönlendirsin (Widget.vue hiyerarşisi).

system_prompt   string  optional    

AI persona promtu (max 50000). Example: Sen bir destek asistanısın

confirm_pay_per_site   boolean  optional    

Slot dolduğunda bayi onayı için. Example: false

Site detaylarını getir.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 1,
        "name": "Demo Site",
        "domain": "example.com",
        "user_id": 42,
        "api_key": "[REDACTED]",
        "is_active": true,
        "system_prompt": "[REDACTED]",
        "widget_color": "#4f46e5",
        "widget_position": "bottom-right",
        "gemini_api_key": "[REDACTED]",
        "subscription_id": 7,
        "settings": {
            "max_messages_per_session": 50
        },
        "faqs_count": 12,
        "created_at": "2026-05-01T10:00:00.000000Z",
        "updated_at": "2026-05-19T14:23:11.000000Z"
    }
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Example response (404):


{
    "message": "No query results for model [App\\Models\\Site]."
}
 

Request      

GET api/sites/{id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 1

Site bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/sites/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"widget_color\": \"#4CD4ab\",
    \"widget_position\": \"bottom-left\",
    \"welcome_message\": \"dtdsufvyvddqamniihfqc\",
    \"bot_name\": \"oynlazghdtqtqxbajwbpi\",
    \"bot_avatar\": \"lpmufinllwloauydlsmsj\",
    \"is_active\": true,
    \"ai_enabled\": false,
    \"appointment_enabled\": true,
    \"whatsapp_voice_enabled\": true,
    \"daily_outbound_limit\": 20,
    \"daily_outbound_message_limit\": 17,
    \"outbound_call_hours_start\": \"20:55\",
    \"outbound_call_hours_end\": \"20:55\",
    \"similarity_threshold\": 1,
    \"monthly_ai_limit\": 21,
    \"settings\": {
        \"system_prompt\": \"ojcybzvrbyickznkygloi\",
        \"response_delay_enabled\": true,
        \"response_delay_min\": 6,
        \"response_delay_max\": 13,
        \"max_call_duration_sec\": 11,
        \"kvkk_compliance_mode\": true,
        \"kvkk_consent_mode\": true,
        \"voice_transfer_enabled\": false,
        \"voice_translate_enabled\": true,
        \"widget_theme\": {
            \"primary\": \"#4CD4ab\",
            \"secondary\": \"#4CD4ab\",
            \"header_text\": \"#4CD4ab\",
            \"chat_bg\": \"#4CD4ab\",
            \"bot_bubble_bg\": \"#4CD4ab\",
            \"bot_bubble_text\": \"#4CD4ab\",
            \"user_bubble_bg\": \"#4CD4ab\",
            \"user_bubble_text\": \"#4CD4ab\",
            \"launcher_bg\": \"#4CD4ab\",
            \"launcher_icon_color\": \"#4CD4ab\"
        }
    },
    \"whatsapp_profile_id\": 17,
    \"instagram_profile_id\": 17,
    \"external_api_base_url\": \"https:\\/\\/example.com\\/api\",
    \"external_api_key\": \"sufvyvddqamniihfqcoyn\",
    \"gemini_api_key\": \"lazghdtqtqxbajwbpilpm\",
    \"use_reseller_gemini_key\": true
}"
const url = new URL(
    "https://dowaba.com/api/sites/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "widget_color": "#4CD4ab",
    "widget_position": "bottom-left",
    "welcome_message": "dtdsufvyvddqamniihfqc",
    "bot_name": "oynlazghdtqtqxbajwbpi",
    "bot_avatar": "lpmufinllwloauydlsmsj",
    "is_active": true,
    "ai_enabled": false,
    "appointment_enabled": true,
    "whatsapp_voice_enabled": true,
    "daily_outbound_limit": 20,
    "daily_outbound_message_limit": 17,
    "outbound_call_hours_start": "20:55",
    "outbound_call_hours_end": "20:55",
    "similarity_threshold": 1,
    "monthly_ai_limit": 21,
    "settings": {
        "system_prompt": "ojcybzvrbyickznkygloi",
        "response_delay_enabled": true,
        "response_delay_min": 6,
        "response_delay_max": 13,
        "max_call_duration_sec": 11,
        "kvkk_compliance_mode": true,
        "kvkk_consent_mode": true,
        "voice_transfer_enabled": false,
        "voice_translate_enabled": true,
        "widget_theme": {
            "primary": "#4CD4ab",
            "secondary": "#4CD4ab",
            "header_text": "#4CD4ab",
            "chat_bg": "#4CD4ab",
            "bot_bubble_bg": "#4CD4ab",
            "bot_bubble_text": "#4CD4ab",
            "user_bubble_bg": "#4CD4ab",
            "user_bubble_text": "#4CD4ab",
            "launcher_bg": "#4CD4ab",
            "launcher_icon_color": "#4CD4ab"
        }
    },
    "whatsapp_profile_id": 17,
    "instagram_profile_id": 17,
    "external_api_base_url": "https:\/\/example.com\/api",
    "external_api_key": "sufvyvddqamniihfqcoyn",
    "gemini_api_key": "lazghdtqtqxbajwbpilpm",
    "use_reseller_gemini_key": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'widget_color' => '#4CD4ab',
            'widget_position' => 'bottom-left',
            'welcome_message' => 'dtdsufvyvddqamniihfqc',
            'bot_name' => 'oynlazghdtqtqxbajwbpi',
            'bot_avatar' => 'lpmufinllwloauydlsmsj',
            'is_active' => true,
            'ai_enabled' => false,
            'appointment_enabled' => true,
            'whatsapp_voice_enabled' => true,
            'daily_outbound_limit' => 20,
            'daily_outbound_message_limit' => 17,
            'outbound_call_hours_start' => '20:55',
            'outbound_call_hours_end' => '20:55',
            'similarity_threshold' => 1,
            'monthly_ai_limit' => 21,
            'settings' => [
                'system_prompt' => 'ojcybzvrbyickznkygloi',
                'response_delay_enabled' => true,
                'response_delay_min' => 6,
                'response_delay_max' => 13,
                'max_call_duration_sec' => 11,
                'kvkk_compliance_mode' => true,
                'kvkk_consent_mode' => true,
                'voice_transfer_enabled' => false,
                'voice_translate_enabled' => true,
                'widget_theme' => [
                    'primary' => '#4CD4ab',
                    'secondary' => '#4CD4ab',
                    'header_text' => '#4CD4ab',
                    'chat_bg' => '#4CD4ab',
                    'bot_bubble_bg' => '#4CD4ab',
                    'bot_bubble_text' => '#4CD4ab',
                    'user_bubble_bg' => '#4CD4ab',
                    'user_bubble_text' => '#4CD4ab',
                    'launcher_bg' => '#4CD4ab',
                    'launcher_icon_color' => '#4CD4ab',
                ],
            ],
            'whatsapp_profile_id' => 17,
            'instagram_profile_id' => 17,
            'external_api_base_url' => 'https://example.com/api',
            'external_api_key' => 'sufvyvddqamniihfqcoyn',
            'gemini_api_key' => 'lazghdtqtqxbajwbpilpm',
            'use_reseller_gemini_key' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/sites/{id}

PATCH api/sites/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the site. Example: 1

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

widget_color   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

widget_position   string  optional    

Example: bottom-left

Must be one of:
  • bottom-right
  • bottom-left
welcome_message   string  optional    

Must not be greater than 500 characters. Example: dtdsufvyvddqamniihfqc

bot_name   string  optional    

Must not be greater than 50 characters. Example: oynlazghdtqtqxbajwbpi

bot_avatar   string  optional    

Must be a valid URL. Must not be greater than 500 characters. Example: lpmufinllwloauydlsmsj

is_active   boolean  optional    

Example: true

ai_enabled   boolean  optional    

Example: false

appointment_enabled   boolean  optional    

Example: true

whatsapp_voice_enabled   boolean  optional    

Example: true

daily_outbound_limit   integer  optional    

Must be at least 0. Must not be greater than 10000. Example: 20

daily_outbound_message_limit   integer  optional    

Must be at least 0. Must not be greater than 10000. Example: 17

outbound_call_hours_start   string  optional    

KVKK outbound çağrı saat penceresi (HH:MM). Worker bu aralık dışında originate etmez (RunOutboundIntents::isWithinCallWindow). null → default 09:00-20:30. Must be a valid date in the format H:i. Example: 20:55

outbound_call_hours_end   string  optional    

Must be a valid date in the format H:i. Example: 20:55

message_retention_days   string  optional    

KVKK mesaj içeriği saklama süresi (gün). Site sahibi (veri sorumlusu) belirler; kvkk:purge-messages bu süreden eski içeriği NULL'lar. KVKK süresiz saklamayı yasaklar → min 30, max 3650 (TBK 10 yıl tavanı). null → mevcut değer korunur (aşağıda unset; kolon NOT NULL default 90).

similarity_threshold   number  optional    

Must be at least 0.5. Must not be greater than 1. Example: 1

monthly_ai_limit   integer  optional    

Site-level AI mesaj kotası — null/0 = kullanıcı havuzu paylaşımı,

0 = bu siteye ayrılan dilim (kullanıcı havuzundan ayrıştırılır). Must be at least 0. Must not be greater than 1000000. Example: 21

languages   string[]  optional    
default_widget_locale   string  optional    

Widget UI dili — sites.languages (AI dil seti) ile FARKLI bir alan. NULL → embed data-locale veya browser yönlendirsin (Widget.vue hiyerarşisi).

settings   object  optional    
system_prompt   string  optional    

Must not be greater than 50000 characters. Example: ojcybzvrbyickznkygloi

response_delay_enabled   boolean  optional    

Example: true

response_delay_min   number  optional    

2026-05-24: integer -> numeric. DB'de 0.3 / 0.7 gibi float değerler var (saniye kesri, örn 300ms = 0.3sn). Integer şart koşmak frontend'in merge gönderdiği settings'i 422'ye düşürüyordu → "sistem promptu kaydedilemedi" sessiz fail. Float kabul + 0-300 sn aralığı korundu. Must be at least 0. Must not be greater than 300. Example: 6

response_delay_max   number  optional    

Must be at least 0. Must not be greater than 300. Example: 13

max_call_duration_sec   integer  optional    

Must be at least 60. Must not be greater than 1800. Example: 11

voice_name   string  optional    

2026-06-05: Gemini Live AI ses seçimi. Allowlist = config/voice.php (tek otorite). sip-bridge bunu speechConfig.voiceConfig.prebuiltVoiceConfig.voiceName olarak gönderir.

thinking_level   string  optional    

2026-06-05: AI düşünme seviyesi (thinkingConfig.thinkingLevel). Allowlist config/voice.php.

kvkk_compliance_mode   boolean  optional    

KVKK 2025 ÜYZ Rehberi + Md.10 Aydınlatma: son tüketici (Ali) WA/IG/TG/Msg'dan ilk yazdığında bot otomatik KVKK aydınlatma yollar + 'verilerimi sil' intent tanır. Default true (KVKK uyumu önerisi); site sahibi kapatabilir. Example: true

kvkk_consent_mode   boolean  optional    

Açık rıza modu (opt-in, default kapalı): açıksa kanal aydınlatması rıza beyanı içerir. Akışı değiştirmez (bot yine cevap verir). Example: true

voice_transfer_enabled   boolean  optional    

Santral (canlı çağrı aktarımı) opt-in — default kapalı. Açıkken ve aktif aktarım hedefi varken telefonu_aktar Gemini'ye deklare edilir. Example: false

voice_translate_enabled   boolean  optional    

Santral canlı ÇEVİRİ (translate-bridge) opt-in — default kapalı. Açıkken + aktarım hedefinin dili müşteri dilinden farklıysa çağrı translate-bridge'den geçer (gemini-3.5-live-translate-preview). Example: true

widget_theme   object  optional    

Widget görünüm teması (2026-06-10) — Entegrasyonlar → Widget Görünümü. Renk seti + launcher ikonu; tek otorite WidgetThemeAiService (DEFAULTS/ICONS). Komple obje gönderilir (settings merge top-level: widget_theme replace edilir).

primary   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

secondary   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

header_text   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

chat_bg   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

bot_bubble_bg   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

bot_bubble_text   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

user_bubble_bg   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

user_bubble_text   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

launcher_bg   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

launcher_icon_color   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

launcher_icon   string  optional    
whatsapp_profile_id   integer  optional    

The id of an existing record in the whatsapp_profiles table. Example: 17

instagram_profile_id   integer  optional    

The id of an existing record in the instagram_profiles table. Example: 17

external_api_base_url   string  optional    

Fonksiyon Gateway HTTP modu için harici API kök URL'i. Example: https://example.com/api

external_api_key   string  optional    

Must not be greater than 500 characters. Example: sufvyvddqamniihfqcoyn

gemini_api_key   string  optional    

Site-bazlı Gemini API key (2026-07-25). DB'de ŞİFRELİ saklanır: Site modeli mutator'ı enc:v1: prefix + Crypt::encryptString ile yazar, accessor okurken decrypt eder (Setting modeli ile aynı pattern; sip-bridge lib/laravel-decrypt.js Node tarafında aynı formatı çözer). Validation gelen DÜZ key'e (max 255); şifreli blob TEXT kolona sığar. Boş string gelirse aşağıda null'a normalize edilir. Must not be greater than 255 characters. Example: lazghdtqtqxbajwbpilpm

use_reseller_gemini_key   boolean  optional    

2026-05-25: Bayi key cascade toggle. Bayi/superadmin müşteri sitesi için bayinin Gemini key'inin paylaşılıp paylaşılmadığını kontrol eder. Müşteri kendi sitesinde body'de gönderse bile aşağıda DROP edilir (UI'da göstermesin diye + defansif backend katmanı). Example: true

Siteyi sil (KVKK Md.7 — anonymize cascade + soft delete + 30 gün geri alma). Akış (SiteAnonymizationService::anonymize): - Tüm conversation içerikleri "[Silindi]" yapılır (WA/widget/IG/TG/Msgr/voice) - PII alanları (phone, email, IP, sender_id) SHA-256 hash'lenir - FAQ + document hard delete (fikri mülkiyet, restore audit'ten geri yüklenmez) - Subscription status='cancelled' (fatura izi korunur) - Site row: name='[Silinmiş Site #ID]', settings/api_key NULL, deleted_at=now() - AuditLog: 'site.deleted_anonymized' + snapshot 30 gün penceresinde POST /api/sites/{id}/restore ile geri yüklenebilir. Cron `site:purge-anonymized --days=30` hard delete yapar. Authz (SitePolicy::delete): - Superadmin ✓ - Bağımsız owner ✓ - Bayi cascade (müşterisinin sitesi) ✓ — 2026-05-24 eklendi - Bayi müşterisi ✗ (reseller_id != null) - Sub-user/agent ✗ (parent_user_id != null)

Example request:
curl --request DELETE \
    "https://dowaba.com/api/sites/1"
const url = new URL(
    "https://dowaba.com/api/sites/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/sites/{id}

URL Parameters

id   integer     

The ID of the site. Example: 1

API anahtarını yeniden üret (eski geçersiz olur). Widget script + 3rd-party entegrasyonlar yeni key ile güncellenir.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/regenerate-key" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/regenerate-key"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/regenerate-key';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "site": {
        "id": 1,
        "api_key": "[REDACTED]"
    },
    "message": "API anahtarı yenilendi. Widget ve 3. taraf entegrasyonları yeni key ile güncellenmelidir."
}
 

Example response (403):


{
    "message": "This action is unauthorized."
}
 

Request      

POST api/sites/{site_id}/regenerate-key

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 1

Silinmiş (anonymize edilmiş) siteyi 30 gün penceresinde geri yükle. Mesaj içerikleri GERİ YÜKLENMEZ — anonymize tek-yönlüdür (KVKK kanıt). Sadece site ayarları (name, widget config, vs.) audit snapshot'tan geri döner. Authz: aynı SitePolicy::restore — silebilen geri de yükleyebilir.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/restore"
const url = new URL(
    "https://dowaba.com/api/sites/1/restore"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/restore';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{siteId}/restore

URL Parameters

siteId   integer     

Example: 1

Site için tanımlı domain'leri listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/domains"
const url = new URL(
    "https://dowaba.com/api/sites/1/domains"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/domains';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/domains

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Siteye yeni izinli alan adı (domain) ekle. Widget yalnızca buraya eklenmiş domain'lerde çalışır (api_key + domain whitelist). Panelden ekleyen, `authorize('update')` ile zaten sitenin sahibi/yöneticisi olduğu için domain DOĞRUDAN güvenilir kabul edilir (`is_verified=true`) — DNS/meta dansı yok. Gizli `api_key` widget'ın asıl korumasıdır; domain whitelist ikincil anti-abuse'tür ve sahip olmadığın bir domain'i eklemek işine yaramaz (kendi key'ini o domain'e gömemezsin).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/domains" \
    --header "Content-Type: application/json" \
    --data "{
    \"domain\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/domains"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "domain": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/domains';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'domain' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/domains

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

domain   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

Domain kaydını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/domains/1"
const url = new URL(
    "https://dowaba.com/api/domains/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/domains/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/domains/{id}

URL Parameters

id   integer     

The ID of the domain. Example: 1

Domain sahipliğini doğrula (DNS TXT veya meta tag kontrolü).

Example request:
curl --request POST \
    "https://dowaba.com/api/domains/1/verify"
const url = new URL(
    "https://dowaba.com/api/domains/1/verify"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/domains/1/verify';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/domains/{domain_id}/verify

URL Parameters

domain_id   integer     

The ID of the domain. Example: 1

AI ile widget teması üret. Kullanıcının doğal dildeki tema tarifinden ("koyu mor, lüks hissiyat") widget'ın tüm renk paletini + başlatıcı ikonunu üretir (kontrast/erişilebilirlik gözetilir). Sonuç KAYDEDİLMEZ — öneri döner; panel "Kaydet" deyince site update (settings.widget_theme) ile kalıcılaşır. Yetki: site sahibi, bayisi veya superadmin (sites update policy).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/widget-theme/ai" \
    --header "Content-Type: application/json" \
    --data "{
    \"prompt\": \"Koyu lacivert zemin, altın vurgulu lüks bir hava\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/widget-theme/ai"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "prompt": "Koyu lacivert zemin, altın vurgulu lüks bir hava"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/widget-theme/ai';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'prompt' => 'Koyu lacivert zemin, altın vurgulu lüks bir hava',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "summary": "Koyu lacivert üzerine altın vurgulu, lüks bir tema kurdum.",
    "theme": {
        "primary": "#1e2a4a",
        "secondary": "#0f1830",
        "header_text": "#f5e6c8",
        "chat_bg": "#f7f7f5",
        "bot_bubble_bg": "#ffffff",
        "bot_bubble_text": "#1e293b",
        "user_bubble_bg": "#1e2a4a",
        "user_bubble_text": "#f5e6c8",
        "launcher_bg": "#1e2a4a",
        "launcher_icon_color": "#f5e6c8",
        "launcher_icon": "sparkles"
    }
}
 

Example response (422):


{
    "success": false,
    "error": "no_key"
}
 

Request      

POST api/sites/{site_id}/widget-theme/ai

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

prompt   string     

Tema tarifi (doğal dil). Example: Koyu lacivert zemin, altın vurgulu lüks bir hava

Otomatik sistem mesajını AI ile güzelle (kaydetmez, öneri döner). "Otomatik Mesajlar" modalındaki alan metnini (boşsa site dilindeki varsayılanı) aynı dilde daha akıcı/profesyonel tek metne dönüştürür. Kullanıcı beğenirse Kaydet ile settings.auto_messages'a yazılır.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/auto-messages/beautify" \
    --header "Content-Type: application/json" \
    --data "{
    \"field\": \"ai_error\",
    \"text\": \"Şu an cevap veremiyoruz\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/auto-messages/beautify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "field": "ai_error",
    "text": "Şu an cevap veremiyoruz"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/auto-messages/beautify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'field' => 'ai_error',
            'text' => 'Şu an cevap veremiyoruz',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "text": "Şu anda size yanıt veremiyoruz; mesajınız bize ulaştı ve ekibimiz en kısa sürede dönüş yapacak."
}
 

Request      

POST api/sites/{site_id}/auto-messages/beautify

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

field   string     

Alan: unpaid_notice | ai_error. Example: ai_error

text   string  optional    

Mevcut metin; boşsa sitenin dilindeki varsayılan baz alınır. Example: Şu an cevap veremiyoruz

Siteler — Bilgi Tabanı

Sitenin SSS'lerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/faqs"
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/faqs

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Yeni SSS oluştur (embedding üretilir).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/faqs" \
    --header "Content-Type: application/json" \
    --data "{
    \"question\": \"vmqeopfuudtdsufvyvddq\",
    \"answer\": \"amniihfqcoynlazghdtqt\",
    \"category\": \"qxbajwbpilpmufinllwlo\",
    \"priority\": 1,
    \"is_active\": false,
    \"media_file_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "question": "vmqeopfuudtdsufvyvddq",
    "answer": "amniihfqcoynlazghdtqt",
    "category": "qxbajwbpilpmufinllwlo",
    "priority": 1,
    "is_active": false,
    "media_file_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'question' => 'vmqeopfuudtdsufvyvddq',
            'answer' => 'amniihfqcoynlazghdtqt',
            'category' => 'qxbajwbpilpmufinllwlo',
            'priority' => 1,
            'is_active' => false,
            'media_file_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/faqs

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

question   string     

Must not be greater than 500 characters. Example: vmqeopfuudtdsufvyvddq

answer   string     

Must not be greater than 5000 characters. Example: amniihfqcoynlazghdtqt

category   string  optional    

Must not be greater than 50 characters. Example: qxbajwbpilpmufinllwlo

priority   integer  optional    

Must be at least 0. Must not be greater than 100. Example: 1

is_active   boolean  optional    

Example: false

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

Tek SSS detayı.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/faqs/1"
const url = new URL(
    "https://dowaba.com/api/faqs/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/faqs/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/faqs/{id}

URL Parameters

id   integer     

The ID of the faq. Example: 1

SSS'yi güncelle (içerik değişirse embedding regen).

Example request:
curl --request PUT \
    "https://dowaba.com/api/faqs/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"question\": \"vmqeopfuudtdsufvyvddq\",
    \"answer\": \"amniihfqcoynlazghdtqt\",
    \"category\": \"qxbajwbpilpmufinllwlo\",
    \"priority\": 1,
    \"is_active\": false,
    \"media_file_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/faqs/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "question": "vmqeopfuudtdsufvyvddq",
    "answer": "amniihfqcoynlazghdtqt",
    "category": "qxbajwbpilpmufinllwlo",
    "priority": 1,
    "is_active": false,
    "media_file_id": 17
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/faqs/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'question' => 'vmqeopfuudtdsufvyvddq',
            'answer' => 'amniihfqcoynlazghdtqt',
            'category' => 'qxbajwbpilpmufinllwlo',
            'priority' => 1,
            'is_active' => false,
            'media_file_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/faqs/{id}

PATCH api/faqs/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the faq. Example: 1

Body Parameters

question   string  optional    

Must not be greater than 500 characters. Example: vmqeopfuudtdsufvyvddq

answer   string  optional    

Must not be greater than 5000 characters. Example: amniihfqcoynlazghdtqt

category   string  optional    

Must not be greater than 50 characters. Example: qxbajwbpilpmufinllwlo

priority   integer  optional    

Must be at least 0. Must not be greater than 100. Example: 1

is_active   boolean  optional    

Example: false

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

SSS'yi sil. Yetki: 'update' (içerik yönetimi) — 'delete' DEĞİL. SSS silme, SSS ekleme/düzenleme (store/update) ile aynı kategoridedir: site İÇERİĞİ yönetimi. SitePolicy::delete site LIFECYCLE'ıdır (KVKK anonimleştirme + soft-delete) ve bayi müşterisini (reseller_id != null) bilinçli engeller → o gate'e bağlamak müşterinin kendi sitesindeki SSS'yi silmesini yanlışlıkla 403'lüyordu (ekleyebiliyor ama silemiyordu). Müşteri kendi sitesinin owner'ı olduğu için SitePolicy::update owner kısayolundan geçer.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/faqs/1"
const url = new URL(
    "https://dowaba.com/api/faqs/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/faqs/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/faqs/{id}

URL Parameters

id   integer     

The ID of the faq. Example: 1

Tek SSS için embedding'i yeniden üret.

Example request:
curl --request POST \
    "https://dowaba.com/api/faqs/1/regenerate-embedding"
const url = new URL(
    "https://dowaba.com/api/faqs/1/regenerate-embedding"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/faqs/1/regenerate-embedding';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/faqs/{faq_id}/regenerate-embedding

URL Parameters

faq_id   integer     

The ID of the faq. Example: 1

Sitenin tüm SSS embedding'lerini yeniden üret.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/faqs/regenerate-all-embeddings"
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs/regenerate-all-embeddings"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs/regenerate-all-embeddings';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/faqs/regenerate-all-embeddings

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Sitenin tüm SSS'lerini toplu sil. Yetki: 'update' (içerik yönetimi) — destroy() ile aynı gerekçe. Toplu silme, toplu ekleme (batchStore) / toplu güncelleme (batchUpdate) ile simetrik içerik işlemidir; bayi müşterisi kendi sitesinde yapabilmeli.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/sites/1/faqs/delete-all"
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs/delete-all"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs/delete-all';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/sites/{site_id}/faqs/delete-all

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Yapıştırılan metinden AI ile otomatik SSS çıkar.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/faqs/extract-from-text" \
    --header "Content-Type: application/json" \
    --data "{
    \"content\": \"vmqeopfuudtdsufvyvddq\",
    \"auto_save\": false,
    \"product_name\": \"amniihfqcoynlazghdtqt\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs/extract-from-text"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "content": "vmqeopfuudtdsufvyvddq",
    "auto_save": false,
    "product_name": "amniihfqcoynlazghdtqt"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs/extract-from-text';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'content' => 'vmqeopfuudtdsufvyvddq',
            'auto_save' => false,
            'product_name' => 'amniihfqcoynlazghdtqt',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/faqs/extract-from-text

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

content   string     

Must be at least 100 characters. Must not be greater than 500000 characters. Example: vmqeopfuudtdsufvyvddq

auto_save   boolean  optional    

Example: false

product_name   string  optional    

Must not be greater than 100 characters. Example: amniihfqcoynlazghdtqt

Yüklenen tek bir resimden AI ile SSS soru-cevap üret + MediaFile kaydet. Akış: 1. Multipart file upload (alan adı: image) 2. MediaFile create (user_id scope, 'public' disk, dedupe checksum'a göre) 3. FAQExtractionService::extractFromImage → {question, answer, category} 4. auto_save=true ise FAQ create + embedding üret

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/faqs/extract-from-image" \
    --header "Content-Type: multipart/form-data" \
    --form "caption=Mağazamızın çalışma saatleri tablosu"\
    --form "auto_save="\
    --form "image=@/tmp/phpdYs4tA" 
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs/extract-from-image"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('caption', 'Mağazamızın çalışma saatleri tablosu');
body.append('auto_save', '');
body.append('image', document.querySelector('input[name="image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs/extract-from-image';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'caption',
                'contents' => 'Mağazamızın çalışma saatleri tablosu'
            ],
            [
                'name' => 'auto_save',
                'contents' => ''
            ],
            [
                'name' => 'image',
                'contents' => fopen('/tmp/phpdYs4tA', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/faqs/extract-from-image

Headers

Content-Type        

Example: multipart/form-data

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

image   file     

Yüklenecek görsel (jpeg/png/webp/gif, max ~7MB). Example: /tmp/phpdYs4tA

caption   string  optional    

optional Kullanıcının görsele eklediği opsiyonel açıklama (Gemini prompt'una enjekte edilir). Example: Mağazamızın çalışma saatleri tablosu

auto_save   boolean  optional    

optional true ise FAQ direkt kaydedilir; false ise sadece önizleme döner. Example: false

Birden fazla SSS'yi tek seferde toplu oluştur.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/faqs/batch" \
    --header "Content-Type: application/json" \
    --data "{
    \"faqs\": [
        {
            \"question\": \"vmqeopfuudtdsufvyvddq\",
            \"answer\": \"amniihfqcoynlazghdtqt\",
            \"category\": \"qxbajwbpilpmufinllwlo\",
            \"is_active\": true,
            \"media_file_id\": 17
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs/batch"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "faqs": [
        {
            "question": "vmqeopfuudtdsufvyvddq",
            "answer": "amniihfqcoynlazghdtqt",
            "category": "qxbajwbpilpmufinllwlo",
            "is_active": true,
            "media_file_id": 17
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs/batch';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'faqs' => [
                [
                    'question' => 'vmqeopfuudtdsufvyvddq',
                    'answer' => 'amniihfqcoynlazghdtqt',
                    'category' => 'qxbajwbpilpmufinllwlo',
                    'is_active' => true,
                    'media_file_id' => 17,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/faqs/batch

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

faqs   object[]     

Must have at least 1 items.

question   string     

Must not be greater than 500 characters. Example: vmqeopfuudtdsufvyvddq

answer   string     

Must not be greater than 5000 characters. Example: amniihfqcoynlazghdtqt

category   string  optional    

Must not be greater than 50 characters. Example: qxbajwbpilpmufinllwlo

is_active   boolean  optional    

Example: true

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

Tek bir SSS'yi doğal dil talimatına göre AI ile yeniden yaz (KAYDETMEZ). "SSS Toplu Değiştir" akışının atomudur: frontend, kullanıcının yazdığı tek talimatı (örn. "5551234567 numaralı telefonu kaldır") her SSS için sırayla bu endpoint'e gönderir → küçük payload, timeout yok. Dönen öneri panelde eski/yeni olarak gösterilir; kullanıcı "Kaydet" deyince batchUpdate yazar. Model: gemini-flash-latest SABİT (FaqBulkRewriteService).

Example request:
curl --request POST \
    "https://dowaba.com/api/faqs/1/ai-rewrite" \
    --header "Content-Type: application/json" \
    --data "{
    \"instruction\": \"5551234567 numaralı telefonu kaldır, SSS\'leri buna göre düzenle\"
}"
const url = new URL(
    "https://dowaba.com/api/faqs/1/ai-rewrite"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "instruction": "5551234567 numaralı telefonu kaldır, SSS'leri buna göre düzenle"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/faqs/1/ai-rewrite';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'instruction' => '5551234567 numaralı telefonu kaldır, SSS\'leri buna göre düzenle',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/faqs/{faq_id}/ai-rewrite

Headers

Content-Type        

Example: application/json

URL Parameters

faq_id   integer     

The ID of the faq. Example: 1

Body Parameters

instruction   string     

Tüm SSS'lere uygulanacak düzenleme talimatı. Example: 5551234567 numaralı telefonu kaldır, SSS'leri buna göre düzenle

Birden fazla mevcut SSS'yi tek seferde toplu GÜNCELLE. "SSS Toplu Değiştir" akışının kayıt adımı: kullanıcının onayladığı/düzenlediği yeni soru-cevap-kategorileri tek istekte yazar. Site-scope: yalnız bu siteye ait FAQ id'leri güncellenir (IDOR koruması — başkasının FAQ'sı sessizce atlanır). Embedding garantisi: soru değişende FAQObserver otomatik yeniler; soru aynı kalmış ama embedding'i eksik olan FAQ'lara burada üretilir (varsa boşuna yazılmaz) → kaydettikten sonra ayrıca "Embedding Yenile" gerekmez.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/faqs/batch-update" \
    --header "Content-Type: application/json" \
    --data "{
    \"updates\": [
        {
            \"id\": 17,
            \"question\": \"consequatur\",
            \"answer\": \"consequatur\",
            \"category\": \"consequatur\"
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/faqs/batch-update"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "updates": [
        {
            "id": 17,
            "question": "consequatur",
            "answer": "consequatur",
            "category": "consequatur"
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/faqs/batch-update';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'updates' => [
                [
                    'id' => 17,
                    'question' => 'consequatur',
                    'answer' => 'consequatur',
                    'category' => 'consequatur',
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/faqs/batch-update

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

updates   object[]     

Güncellenecek SSS listesi.

id   integer     

Güncellenecek SSS id'si. Example: 17

question   string     

Yeni soru. Example: consequatur

answer   string     

Yeni cevap. Example: consequatur

category   string  optional    

Kategori (opsiyonel). Example: consequatur

Sitenin yüklenmiş dokümanlarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/documents"
const url = new URL(
    "https://dowaba.com/api/sites/1/documents"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/documents';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/documents

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Yeni doküman yükle (PDF/TXT/DOCX).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/documents" \
    --header "Content-Type: multipart/form-data" \
    --form "title=vmqeopfuudtdsufvyvddq"\
    --form "file=@/tmp/phpZjF6qZ" 
const url = new URL(
    "https://dowaba.com/api/sites/1/documents"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('title', 'vmqeopfuudtdsufvyvddq');
body.append('file', document.querySelector('input[name="file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/documents';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'title',
                'contents' => 'vmqeopfuudtdsufvyvddq'
            ],
            [
                'name' => 'file',
                'contents' => fopen('/tmp/phpZjF6qZ', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/documents

Headers

Content-Type        

Example: multipart/form-data

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

title   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

file   file     

Must be a file. Must not be greater than 10240 kilobytes. Example: /tmp/phpZjF6qZ

Doküman detayı.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/documents/17"
const url = new URL(
    "https://dowaba.com/api/documents/17"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/documents/17';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/documents/{id}

URL Parameters

id   integer     

The ID of the document. Example: 17

Doküman bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/documents/17" \
    --header "Content-Type: application/json" \
    --data "{
    \"title\": \"vmqeopfuudtdsufvyvddq\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/documents/17"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "vmqeopfuudtdsufvyvddq",
    "is_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/documents/17';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'title' => 'vmqeopfuudtdsufvyvddq',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/documents/{id}

PATCH api/documents/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the document. Example: 17

Body Parameters

title   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

is_active   boolean  optional    

Example: false

Dokümanı sil (chunk'lar cascade silinir). Yetki: 'update' (içerik yönetimi) — FAQController::destroy ile aynı gerekçe. Belge yükleme/düzenleme (store/update) zaten 'update' gate'inden geçiyor; silme de aynı Bilgi Tabanı içerik kategorisi → bayi müşterisi kendi sitesinin belgesini silebilmeli. SitePolicy::delete site LIFECYCLE'ıdır (müşteriyi engeller).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/documents/17"
const url = new URL(
    "https://dowaba.com/api/documents/17"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/documents/17';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/documents/{id}

URL Parameters

id   integer     

The ID of the document. Example: 17

Dokümanı işle (chunk'a böl, embedding üret).

Example request:
curl --request POST \
    "https://dowaba.com/api/documents/17/process"
const url = new URL(
    "https://dowaba.com/api/documents/17/process"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/documents/17/process';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/documents/{document_id}/process

URL Parameters

document_id   integer     

The ID of the document. Example: 17

Bundle (e-ticaret / 3. taraf entegrasyon) manifest URL'inden function paketini içe aktar.

Manifest formatı: https://example.com/.well-known/dowaba-bundle.json (schema_version=1.0). Manifest → SiteConnection + FunctionDefinition[] yaratır; mevcut bundle adı zaten varsa 409 Conflict döner (?replace=true ile üzerine yazılır).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/bundles/import" \
    --header "Content-Type: application/json" \
    --data "{
    \"manifest\": [],
    \"manifest_url\": \"https:\\/\\/example.com\\/.well-known\\/dowaba-bundle.json\",
    \"api_key\": \"bundle_secret_token\",
    \"replace\": false
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/bundles/import"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "manifest": [],
    "manifest_url": "https:\/\/example.com\/.well-known\/dowaba-bundle.json",
    "api_key": "bundle_secret_token",
    "replace": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/bundles/import';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'manifest' => [],
            'manifest_url' => 'https://example.com/.well-known/dowaba-bundle.json',
            'api_key' => 'bundle_secret_token',
            'replace' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Başarılı):


{
    "ok": true,
    "connection": {
        "id": 42,
        "name": "Shopify",
        "type": "http_api"
    },
    "functions": {
        "created": [
            {
                "id": 101,
                "slug": "shopify_get_orders"
            }
        ],
        "updated": []
    },
    "note": "Eklenen fonksiyonlar pasif durumda. Aşağıdaki listeden tek tek aktive et."
}
 

Example response (409, Zaten import edilmiş):


{
    "error": "already_imported",
    "message": "...",
    "existing_connection_id": 7
}
 

Example response (422, Manifest hatası):


{
    "error": "schema_invalid",
    "message": "..."
}
 

Request      

POST api/sites/{site_id}/bundles/import

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

manifest   object  optional    

Manifest'i doğrudan JSON gövde olarak gönder (URL fetch yok → SSRF yüzeyi sıfır). manifest veya manifest_url'den biri zorunlu.

manifest_url   string  optional    

Bundle manifest URL'i (alternatif; SSRF-guard'lı fetch edilir). Example: https://example.com/.well-known/dowaba-bundle.json

api_key   string     

Manifest sahibi servis için API key (Bearer/api_key auth — connection.credentials.token). Example: bundle_secret_token

replace   boolean  optional    

Var olan bundle'ı üzerine yaz. Example: false

Siteler — AI Analiz

SSS analizi: müşteri mesajlarını tarar, eklenebilecek yeni SSS'leri, güncellenecek mevcut SSS'leri, çelişkileri ve botun hatalı cevaplarını çıkarır.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/analysis/faqs"
const url = new URL(
    "https://dowaba.com/api/sites/1/analysis/faqs"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/analysis/faqs';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/analysis/faqs

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Onaylanan SSS önerilerini uygula. new_faqs create, faq_updates update edilir.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/analysis/faqs/apply" \
    --header "Content-Type: application/json" \
    --data "{
    \"new_faqs\": [
        {
            \"question\": \"vmqeopfuudtdsufvyvddq\",
            \"answer\": \"amniihfqcoynlazghdtqt\",
            \"category\": \"qxbajwbpilpmufinllwlo\"
        }
    ],
    \"faq_updates\": [
        {
            \"faq_id\": 17,
            \"question\": \"mqeopfuudtdsufvyvddqa\",
            \"answer\": \"mniihfqcoynlazghdtqtq\",
            \"category\": \"xbajwbpilpmufinllwloa\"
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/analysis/faqs/apply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "new_faqs": [
        {
            "question": "vmqeopfuudtdsufvyvddq",
            "answer": "amniihfqcoynlazghdtqt",
            "category": "qxbajwbpilpmufinllwlo"
        }
    ],
    "faq_updates": [
        {
            "faq_id": 17,
            "question": "mqeopfuudtdsufvyvddqa",
            "answer": "mniihfqcoynlazghdtqtq",
            "category": "xbajwbpilpmufinllwloa"
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/analysis/faqs/apply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'new_faqs' => [
                [
                    'question' => 'vmqeopfuudtdsufvyvddq',
                    'answer' => 'amniihfqcoynlazghdtqt',
                    'category' => 'qxbajwbpilpmufinllwlo',
                ],
            ],
            'faq_updates' => [
                [
                    'faq_id' => 17,
                    'question' => 'mqeopfuudtdsufvyvddqa',
                    'answer' => 'mniihfqcoynlazghdtqtq',
                    'category' => 'xbajwbpilpmufinllwloa',
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/analysis/faqs/apply

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

new_faqs   object[]  optional    

Eklenecek yeni SSS'ler (question, answer, category).

question   string  optional    

This field is required when new_faqs is present. Must not be greater than 500 characters. Example: vmqeopfuudtdsufvyvddq

answer   string  optional    

This field is required when new_faqs is present. Must not be greater than 5000 characters. Example: amniihfqcoynlazghdtqt

category   string  optional    

Must not be greater than 50 characters. Example: qxbajwbpilpmufinllwlo

faq_updates   object[]  optional    

Güncellenecek SSS'ler (faq_id, question, answer, category).

faq_id   integer  optional    

This field is required when faq_updates is present. Example: 17

question   string  optional    

Must not be greater than 500 characters. Example: mqeopfuudtdsufvyvddqa

answer   string  optional    

This field is required when faq_updates is present. Must not be greater than 5000 characters. Example: mniihfqcoynlazghdtqtq

category   string  optional    

Must not be greater than 50 characters. Example: xbajwbpilpmufinllwloa

Bot performans analizi (salt-okunur). Metrikler + AI yorumu + öneriler.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/analysis/bot-performance"
const url = new URL(
    "https://dowaba.com/api/sites/1/analysis/bot-performance"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/analysis/bot-performance';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/analysis/bot-performance

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Müşteri duygu / memnuniyet analizi (salt-okunur).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/analysis/sentiment"
const url = new URL(
    "https://dowaba.com/api/sites/1/analysis/sentiment"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/analysis/sentiment';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/analysis/sentiment

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/analysis/trends"
const url = new URL(
    "https://dowaba.com/api/sites/1/analysis/trends"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/analysis/trends';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Bir sitenin kaydedilmiş raporlarını listele (metadata; result HARİÇ).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/analysis-reports?type=faqs"
const url = new URL(
    "https://dowaba.com/api/sites/1/analysis-reports"
);

const params = {
    "type": "faqs",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/analysis-reports';
$response = $client->get(
    $url,
    [
        'query' => [
            'type' => 'faqs',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/analysis-reports

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Query Parameters

type   string  optional    

Tek tipe filtrele (faqs|bot_performance|sentiment|trends). Example: faqs

Bir analiz sonucunu kaydet.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/analysis-reports" \
    --header "Content-Type: application/json" \
    --data "{
    \"type\": \"faqs\",
    \"result\": [],
    \"params\": [],
    \"title\": \"Mayıs ayı SSS analizi\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/analysis-reports"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "type": "faqs",
    "result": [],
    "params": [],
    "title": "Mayıs ayı SSS analizi"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/analysis-reports';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'type' => 'faqs',
            'result' => [],
            'params' => [],
            'title' => 'Mayıs ayı SSS analizi',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/analysis-reports

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

type   string     

faqs|bot_performance|sentiment|trends. Example: faqs

result   object     

Analiz JSON'u (SiteAnalysisService çıktısı).

params   object  optional    

Çalıştırma parametreleri (days, channels, max_messages).

title   string  optional    

Opsiyonel başlık. Example: Mayıs ayı SSS analizi

Tek raporu tam (result dahil) getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/analysis-reports/1"
const url = new URL(
    "https://dowaba.com/api/analysis-reports/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/analysis-reports/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/analysis-reports/{report_id}

URL Parameters

report_id   integer     

The ID of the report. Example: 1

Raporu sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/analysis-reports/1"
const url = new URL(
    "https://dowaba.com/api/analysis-reports/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/analysis-reports/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/analysis-reports/{report_id}

URL Parameters

report_id   integer     

The ID of the report. Example: 1

Ekip & Alt Kullanıcılar

Site'in tüm üyelerini listele (owner + agent + permissions).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/team"
const url = new URL(
    "https://dowaba.com/api/sites/1/team"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/team';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/team

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Yeni üye ekle. Doğrudan aktif eder + bilgilendirme SMS'i gönderir. Body: - phone (zorunlu) - name (opsiyonel) - email (opsiyonel — yoksa otomatik üretilir) - modules (opsiyonel string[]) — verilmezse tümü açık (null)

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/team/invite" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"vmqeopfuudtdsufvyvddq\",
    \"name\": \"amniihfqcoynlazghdtqt\",
    \"email\": \"andreanne00@example.org\",
    \"modules\": [
        \"wbpilpmufinllwloauydl\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/team/invite"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "vmqeopfuudtdsufvyvddq",
    "name": "amniihfqcoynlazghdtqt",
    "email": "andreanne00@example.org",
    "modules": [
        "wbpilpmufinllwloauydl"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/team/invite';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => 'vmqeopfuudtdsufvyvddq',
            'name' => 'amniihfqcoynlazghdtqt',
            'email' => 'andreanne00@example.org',
            'modules' => [
                'wbpilpmufinllwloauydl',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/team/invite

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

phone   string     

Must not be greater than 30 characters. Example: vmqeopfuudtdsufvyvddq

name   string  optional    

Must not be greater than 100 characters. Example: amniihfqcoynlazghdtqt

email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: andreanne00@example.org

modules   string[]  optional    

Must not be greater than 30 characters.

Bir agent'ın görebileceği modülleri güncelle. Body: { modules: string[] | null } - null → tüm modüller (default) - [] → hiçbiri (agent boş bir panel görür)

Example request:
curl --request PUT \
    "https://dowaba.com/api/sites/1/team/1562/permissions" \
    --header "Content-Type: application/json" \
    --data "{
    \"modules\": [
        \"vmqeopfuudtdsufvyvddq\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/team/1562/permissions"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "modules": [
        "vmqeopfuudtdsufvyvddq"
    ]
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/team/1562/permissions';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'modules' => [
                'vmqeopfuudtdsufvyvddq',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/sites/{site_id}/team/{userId}/permissions

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

userId   string     

Example: 1562

Body Parameters

modules   string[]  optional    

Must not be greater than 30 characters.

Agent'ın temel bilgilerini güncelle (ad, telefon, e-posta). Body: - name (opsiyonel) - phone (opsiyonel — boş gönderirse silinmez, mevcut korunur) - email (opsiyonel — geçerli e-posta veya null)

Example request:
curl --request PUT \
    "https://dowaba.com/api/sites/1/team/1562/profile" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"phone\": \"amniihfqcoynlazghdtqt\",
    \"email\": \"andreanne00@example.org\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/team/1562/profile"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "phone": "amniihfqcoynlazghdtqt",
    "email": "andreanne00@example.org"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/team/1562/profile';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'phone' => 'amniihfqcoynlazghdtqt',
            'email' => 'andreanne00@example.org',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/sites/{site_id}/team/{userId}/profile

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

userId   string     

Example: 1562

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

phone   string  optional    

Must not be greater than 30 characters. Example: amniihfqcoynlazghdtqt

email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: andreanne00@example.org

Agent'ın şifresini sıfırla. Yeni şifre üret + SMS gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/team/1562/reset-password"
const url = new URL(
    "https://dowaba.com/api/sites/1/team/1562/reset-password"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/team/1562/reset-password';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/team/{userId}/reset-password

URL Parameters

site_id   integer     

The ID of the site. Example: 1

userId   string     

Example: 1562

Bir agent'ı siteden çıkar.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/sites/1/team/1562"
const url = new URL(
    "https://dowaba.com/api/sites/1/team/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/team/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/sites/{site_id}/team/{userId}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

userId   string     

Example: 1562

Mesaj Kutusu

Gönderilemeyen mesajı tekrar dene. Failed (teslim edilemedi) durumundaki giden mesajı aynı kanaldan yerinde yeniden gönderir. Yalnız text mesajlar; medyalı mesajda 422 döner. Mesajlaşma penceresi (WhatsApp/Instagram/Messenger 24 saat) kapalıysa 422 döner.

Example request:
curl --request POST \
    "https://dowaba.com/api/inbox/messages/whatsapp/12345/retry"
const url = new URL(
    "https://dowaba.com/api/inbox/messages/whatsapp/12345/retry"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/inbox/messages/whatsapp/12345/retry';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "delivery_status": "sent",
    "message_id": "wamid.xxx"
}
 

Example response (422):


{
    "error": "Mesajlaşma penceresi (24 saat) kapalı"
}
 

Request      

POST api/inbox/messages/{channel}/{id}/retry

URL Parameters

channel   string     

Kanal: whatsapp | instagram | messenger | telegram. Example: whatsapp

id   integer     

Failed mesajın DB id'si. Example: 12345

Inbox Media

Inbox mesajlarına eklenmiş medya dosyalarını serve eder. İki giriş:

  1. GET /api/inbox/media/{channel}/{messageId}?download=1 — auth:sanctum (Bearer; mobil uygulama bu yolu kullanır) + Site::isAccessibleBy scope.
  2. GET /api/inbox/media-signed/{channel}/{messageId}?expires=..&signature=.. — RELATIVE signed URL ('signed:relative' middleware). Panel /

channel: whatsapp | instagram | telegram | messenger messageId: kanal tablosundaki message PK ?download=1 → Content-Disposition: attachment (browser indir butonu için) yoksa inline (image/video/audio preview için)

Storage: storage/app/inbound-media/{channel}/{siteId}/{yyyy-mm}/{uuid}.{ext} public/storage symlink ALTINDA DEĞİL — direct serve gerekiyor.

Signed URL ile medya stream — <img> tag'leri için (header'sız erişim).

İmza doğrulaması route'taki 'signed:relative' middleware'inde; geçersiz/expired imza 403 ile buraya hiç ulaşmaz. İmzalı URL yalnızca o mesaja erişimi olan kullanıcıya üretildiği için ek user scope kontrolü gerekmez (capability URL).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/inbox/media-signed/whatsapp/7114?download=1&expires=1760000000&signature=abc123"
const url = new URL(
    "https://dowaba.com/api/inbox/media-signed/whatsapp/7114"
);

const params = {
    "download": "1",
    "expires": "1760000000",
    "signature": "abc123",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/inbox/media-signed/whatsapp/7114';
$response = $client->get(
    $url,
    [
        'query' => [
            'download' => '1',
            'expires' => '1760000000',
            'signature' => 'abc123',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (403):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Forbidden</title>

        <style>
            /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}code{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-xl{max-width:36rem}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.uppercase{text-transform:uppercase}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tracking-wider{letter-spacing:.05em}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@-webkit-keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@-webkit-keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-300 { --text-opacity: 1; color: #e2e8f0; color: rgba(226,232,240,var(--text-opacity)) }}
        </style>

        <style>
            body {
                font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
            }
        </style>
    </head>
    <body class="antialiased">
        <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center sm:pt-0" role="main">
            <div class="max-w-xl mx-auto sm:px-6 lg:px-8">
                <div class="flex items-center pt-8 sm:justify-start sm:pt-0">
                    <h1 class="px-4 text-lg dark:text-gray-300 text-gray-700 border-r border-gray-400 tracking-wider">
                        403                    </h1>

                    <div class="ml-4 text-lg dark:text-gray-300 text-gray-700 uppercase tracking-wider">
                        Invalid signature.                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

 

Request      

GET api/inbox/media-signed/{channel}/{messageId}

URL Parameters

channel   string     

Kanal: whatsapp, instagram, telegram veya messenger. Example: whatsapp

messageId   integer     

Mesaj ID'si. Example: 7114

Query Parameters

download   integer  optional    

1 ise indirme zorlanır. Example: 1

expires   integer     

İmza geçerlilik bitişi (epoch, otomatik üretilir). Example: 1760000000

signature   string     

HMAC imzası (otomatik üretilir). Example: abc123

Voice — SIP & Çağrılar

Desteklenen SIP sağlayıcılarının (whitelist) listesini döner. Frontend trunk formundaki "Sağlayıcı" dropdown'unu doldurur. Custom seçeneği `allow_custom=true` ise manuel host girilebilir. `match_hosts` ve diğer Asterisk-internal alanlar UI'a leak edilmez — sadece görünür alanlar döner.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sip-providers"
const url = new URL(
    "https://dowaba.com/api/sip-providers"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sip-providers';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "data": {
        "providers": [
            {
                "name": "NetGSM",
                "slug": "netgsm",
                "host": "sip.netgsm.com.tr",
                "port": 5060,
                "description": "...",
                "docs_url": "..."
            }
        ],
        "allow_custom": true,
        "default_server": "sip.netgsm.com.tr",
        "default_port": 5060
    }
}
 

Request      

GET api/sip-providers

Kapasite paketlerim Kullanıcının sahip olduğu aktif kapasite paketleri + atandıkları siteler.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/me/voice-capacity" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/me/voice-capacity"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/voice-capacity';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "subscriptions": [
        {
            "id": 41,
            "plan": {
                "slug": "kapasite-100",
                "name": "Kapasite-100",
                "concurrent_calls_limit": 100,
                "daily_calls_limit": 1000,
                "monthly_voice_calls_limit": 15000
            },
            "period": "monthly",
            "expires_at": "2026-07-12T00:00:00.000000Z",
            "assigned_site": {
                "id": 12,
                "name": "Örnek Site"
            }
        }
    ]
}
 

Request      

GET api/me/voice-capacity

Headers

Authorization        

Example: Bearer {TOKEN}

Site kapasite durumu Atanmış kapasite paketi + güncel kullanım (anlık eşzamanlı + bugünkü çağrı). Paket yoksa platform default limitleri döner.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/voice-capacity" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/voice-capacity"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/voice-capacity';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "package": {
        "subscription_id": 41,
        "plan_slug": "kapasite-100",
        "plan_name": "Kapasite-100",
        "concurrent_calls_limit": 100,
        "daily_calls_limit": 1000,
        "monthly_voice_calls_limit": 15000,
        "expires_at": "2026-07-12T00:00:00.000000Z"
    },
    "usage": {
        "current_concurrent": 3,
        "today_calls": 117
    },
    "defaults": {
        "concurrent_calls_limit": 20
    }
}
 

Request      

GET api/sites/{site_id}/voice-capacity

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Kapasite paketini siteye ata Paket site SAHİBİNE ait ve aktif olmalı; aynı anda tek siteye atanabilir (başka sitedeyse 422 — önce oradan kaldırın).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/voice-capacity" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"subscription_id\": 41
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/voice-capacity"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "subscription_id": 41
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/voice-capacity';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'subscription_id' => 41,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true
}
 

Example response (422, Paket başka sitede):


{
    "success": false,
    "error": "Bu paket başka bir siteye atanmış. Önce oradan kaldırın."
}
 

Request      

POST api/sites/{site_id}/voice-capacity

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Body Parameters

subscription_id   integer     

Kapasite paketi abonelik ID'si. Example: 41

Kapasite paketi atamasını kaldır Site default limitlere (20 eşzamanlı, günlük limitsiz) döner; paket başka bir siteye atanabilir hâle gelir.

requires authentication

Example request:
curl --request DELETE \
    "https://dowaba.com/api/sites/1/voice-capacity" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/voice-capacity"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/voice-capacity';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true
}
 

Request      

DELETE api/sites/{site_id}/voice-capacity

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Aktarım rehberini listele (Santral) Santral / canlı çağrı aktarımı hedef listesi + opt-in durumu. AI, telefon görüşmesinde arayanı SADECE bu rehberdeki kişilere canlı aktarabilir. `enabled=false` ise özellik kapalıdır (telefonu_aktar AI'ya deklare edilmez); açmak için `PUT /api/sites/{site}` body `{"settings":{"voice_transfer_enabled":true}}`. Not: aktarım, sitenin SIP sağlayıcısı üzerinden DIŞA ARAMA yapar — sağlayıcıda dış arama paketi/bakiyesi yoksa aktarımlar "meşgul" hatasıyla düşer.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/transfer-targets" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/transfer-targets"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/transfer-targets';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Başarılı):


{
    "success": true,
    "enabled": true,
    "translate_enabled": false,
    "targets": [
        {
            "id": 3,
            "site_id": 5,
            "name": "Ahmet Yılmaz",
            "department": "Teknik Ekip",
            "phone": "+90 555 *** ** **",
            "user_id": null,
            "is_active": true,
            "sort": 0,
            "created_at": "2026-06-12T10:00:00.000000Z",
            "updated_at": "2026-06-12T10:00:00.000000Z"
        }
    ]
}
 

Request      

GET api/sites/{site_id}/transfer-targets

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Aktarım hedefi ekle (Santral) Site başına en fazla 20 hedef. Telefon otomatik normalize edilir (boşluk/tire temizlenir, baştaki 0 atılır, 90 öneki eklenir → 905xxxxxxxxx). `user_id` verilirse sitenin sahibi veya site ekibinden biri olmalıdır.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/transfer-targets" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Ahmet Yılmaz\",
    \"department\": \"Teknik Ekip\",
    \"language\": \"tr\",
    \"phone\": \"5551112233\",
    \"user_id\": 12,
    \"is_active\": true,
    \"sort\": 0
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/transfer-targets"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Ahmet Yılmaz",
    "department": "Teknik Ekip",
    "language": "tr",
    "phone": "5551112233",
    "user_id": 12,
    "is_active": true,
    "sort": 0
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/transfer-targets';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Ahmet Yılmaz',
            'department' => 'Teknik Ekip',
            'language' => 'tr',
            'phone' => '5551112233',
            'user_id' => 12,
            'is_active' => true,
            'sort' => 0,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201, Oluşturuldu):


{
    "success": true,
    "target": {
        "id": 7,
        "site_id": 5,
        "name": "Ahmet Yılmaz",
        "department": "Teknik Ekip",
        "phone": "+90 555 *** ** **",
        "user_id": null,
        "is_active": true,
        "sort": 0
    }
}
 

Example response (422, Geçersiz telefon veya 20 hedef sınırı):


{
    "success": false,
    "error": "Telefon numarası geçersiz: 123"
}
 

Request      

POST api/sites/{site_id}/transfer-targets

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Body Parameters

name   string     

Kişi/birim adı. Example: Ahmet Yılmaz

department   string  optional    

Departman/etiket — AI eşleştirmede kullanır ("teknik ekip" → bu kişi). Example: Teknik Ekip

language   string  optional    

Temsilci dili (BCP-47: tr/en/ru/de/ar/fr/it). Müşteri farklı dildeyse VE settings.voice_translate_enabled açıksa çağrı canlı çeviriyle aktarılır. Boş = çeviri yok (düz aktarım). Example: tr

phone   string     

Telefon (90 prefix otomatik normalize). Example: 5551112233

user_id   integer  optional    

Opsiyonel panel kullanıcısı bağlantısı (site ekibinden olmalı). Example: 12

is_active   boolean  optional    

Aktif mi (pasif hedefler AI'ya sunulmaz). Example: true

sort   integer  optional    

Sıralama. Example: 0

Aktarım hedefi güncelle (Santral) Kısmi güncelleme desteklenir — yalnızca gönderilen alanlar değişir.

requires authentication

Example request:
curl --request PUT \
    "https://dowaba.com/api/sites/1/transfer-targets/1" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Ahmet Y.\",
    \"department\": \"Satış\",
    \"language\": \"en\",
    \"phone\": \"5551112244\",
    \"user_id\": 12,
    \"is_active\": false,
    \"sort\": 1
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/transfer-targets/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Ahmet Y.",
    "department": "Satış",
    "language": "en",
    "phone": "5551112244",
    "user_id": 12,
    "is_active": false,
    "sort": 1
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/transfer-targets/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Ahmet Y.',
            'department' => 'Satış',
            'language' => 'en',
            'phone' => '5551112244',
            'user_id' => 12,
            'is_active' => false,
            'sort' => 1,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Güncellendi):


{
    "success": true,
    "target": {
        "id": 3,
        "is_active": false
    }
}
 

Request      

PUT api/sites/{site_id}/transfer-targets/{target_id}

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

target_id   integer     

The ID of the target. Example: 1

site   integer     

Site ID. Example: 5

target   integer     

Hedef ID. Example: 3

Body Parameters

name   string  optional    

Kişi/birim adı. Example: Ahmet Y.

department   string  optional    

Departman/etiket. Example: Satış

language   string  optional    

Temsilci dili (tr/en/ru/de/ar/fr/it) — canlı çeviri için. Boş = çeviri yok. Example: en

phone   string  optional    

Telefon (otomatik normalize). Example: 5551112244

user_id   integer  optional    

Panel kullanıcısı bağlantısı. Example: 12

is_active   boolean  optional    

Aktif mi. Example: false

sort   integer  optional    

Sıralama. Example: 1

Aktarım hedefi sil (Santral) Geçmiş çağrı kayıtlarındaki aktarım bilgisi (transferred_to_name/phone) korunur.

requires authentication

Example request:
curl --request DELETE \
    "https://dowaba.com/api/sites/1/transfer-targets/1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/transfer-targets/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/transfer-targets/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Silindi):


{
    "success": true
}
 

Request      

DELETE api/sites/{site_id}/transfer-targets/{target_id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

target_id   integer     

The ID of the target. Example: 1

site   integer     

Site ID. Example: 5

target   integer     

Hedef ID. Example: 3

Voice — Konuşma Geçmişi

Sitenin sesli konuşma geçmişini listele (sadece temizlenmiş transkriptler).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/voice-conversations"
const url = new URL(
    "https://dowaba.com/api/sites/1/voice-conversations"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/voice-conversations';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/voice-conversations

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Tek bir sesli konuşmanın ham mesajları + temizlenmiş transkripti.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/voice-conversations/1"
const url = new URL(
    "https://dowaba.com/api/voice-conversations/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-conversations/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/voice-conversations/{voiceConversation_id}

URL Parameters

voiceConversation_id   integer     

The ID of the voiceConversation. Example: 1

Konuşma kaydı için HMAC imzalı geçici URL üretir (TTL 10 dk).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/voice-conversations/1/recording-url"
const url = new URL(
    "https://dowaba.com/api/voice-conversations/1/recording-url"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-conversations/1/recording-url';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/voice-conversations/{voiceConversation_id}/recording-url

URL Parameters

voiceConversation_id   integer     

The ID of the voiceConversation. Example: 1

Manuel transkript temizleme tetikle — UI "Yeniden Temizle" butonu (senkron).

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-conversations/1/clean"
const url = new URL(
    "https://dowaba.com/api/voice-conversations/1/clean"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-conversations/1/clean';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voice-conversations/{voiceConversation_id}/clean

URL Parameters

voiceConversation_id   integer     

The ID of the voiceConversation. Example: 1

Birden fazla voice conversation'ı toplu sil. Yalnızca kullanıcının erişebildiği site'lere ait kayıtlar silinir; erişim dışı ID'ler sessizce atlanır.

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-conversations/bulk-destroy" \
    --header "Content-Type: application/json" \
    --data "{
    \"ids\": [
        12,
        13,
        14
    ]
}"
const url = new URL(
    "https://dowaba.com/api/voice-conversations/bulk-destroy"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ids": [
        12,
        13,
        14
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-conversations/bulk-destroy';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ids' => [
                12,
                13,
                14,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voice-conversations/bulk-destroy

Headers

Content-Type        

Example: application/json

Body Parameters

ids   integer[]     

Silinecek conversation ID'leri (1-200 arası).

Outbound Calls

Outbound (giden) çağrı niyetlerini (intent) yöneten endpoint'ler. Üç iş tipinin (manual / appointment_reminder / ai_followup) merkezi yönetim noktası. Worker (voice:run-outbound-intents artisan komutu, her dakika çalışır) bu tablodaki status=approved kayıtları çekip Asterisk ARI üzerinden gerçek çağrıyı başlatır.

Outbound (giden) çağrı tetikle Tek seferlik / hemen aranacak çağrılar için. Tetiklendiği anda Asterisk ARI üzerinden NetGSM trunk'a `originate` komutu gönderilir; karşı taraf cevap verince AI (sitenin sistem promptu + opsiyonel `prompt_override`) konuşmaya başlar. Zamanlanmış / tekrarlayan çağrılar için `POST /api/sites/{site}/outbound-intents` endpoint'ini kullan (worker tarafından batch çalıştırılır). Rate limit: dakikada 5 (per user). Site bazında günlük limit `sites.daily_outbound_limit` (default 50).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/voice/call" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"to_number\": \"5551112233\",
    \"prompt_override\": \"Sen randevu hatırlatma temsilcisisin.\",
    \"initial_message\": \"Merhaba, dowaba\'dan arıyorum.\"
}"
const url = new URL(
    "https://dowaba.com/api/voice/call"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "to_number": "5551112233",
    "prompt_override": "Sen randevu hatırlatma temsilcisisin.",
    "initial_message": "Merhaba, dowaba'dan arıyorum."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice/call';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'to_number' => '5551112233',
            'prompt_override' => 'Sen randevu hatırlatma temsilcisisin.',
            'initial_message' => 'Merhaba, dowaba\'dan arıyorum.',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Çağrı başarıyla tetiklendi):


{
    "success": true,
    "message": "Çağrı başlatıldı, karşı taraf çalıyor.",
    "data": {
        "conversation_id": 78,
        "channel_id": "1777189978.2",
        "audiosocket_uuid": "e52b6f00-693c-48b2-9b3e-6c843b9744ef",
        "today_count": 12,
        "limit": 50
    }
}
 

Example response (422, Trunk yok veya numara geçersiz):


{
    "success": false,
    "error": "Bu siteye bağlı aktif SIP trunk yok. Önce telefon entegrasyonunu yapın."
}
 

Example response (429, Günlük limit doldu):


{
    "success": false,
    "error": "Günlük outbound çağrı limitiniz (50) doldu. Yarın tekrar deneyebilirsiniz.",
    "today_count": 50,
    "limit": 50
}
 

Example response (503, Asterisk ulaşılamaz):


{
    "success": false,
    "error": "Asterisk çağrı başlatılamadı: Connection refused",
    "conversation_id": 79
}
 

Request      

POST api/voice/call

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Site ID. Example: 5

to_number   string     

Aranacak telefon. +90 prefix otomatik eklenir. Example: 5551112233

prompt_override   string  optional    

Özel rol promptu — site default kişiliği EZER. Example: Sen randevu hatırlatma temsilcisisin.

initial_message   string  optional    

AI'ın söyleyeceği ilk cümle. Boşsa default. Example: Merhaba, dowaba'dan arıyorum.

Outbound çağrı niyetlerini listele

requires authentication

Site'a ait planlanmış / onay bekleyen / tamamlanmış outbound çağrıları döner. Kind ve status filtrelenebilir; AI follow-up önerileri pending_approval statüsünde gelir, kullanıcı onaylarsa worker çağrıyı başlatır.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/outbound-intents?kind=ai_followup&status=pending_approval&per_page=25&page=1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/outbound-intents"
);

const params = {
    "kind": "ai_followup",
    "status": "pending_approval",
    "per_page": "25",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/outbound-intents';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
        'query' => [
            'kind' => 'ai_followup',
            'status' => 'pending_approval',
            'per_page' => '25',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Başarılı liste):


{
    "success": true,
    "data": {
        "current_page": 1,
        "per_page": 25,
        "total": 47,
        "data": [
            {
                "id": 314,
                "site_id": 5,
                "kind": "ai_followup",
                "status": "pending_approval",
                "target_phone": "905551112233",
                "target_name": "Ali Veli",
                "scheduled_at": null,
                "initial_message": "Merhaba Ali Bey, konuştuğumuz randevu için arıyorum...",
                "ai_reasoning": "Müşteri 3000 TL üstü ürün fiyatı sordu, AI net fiyat veremedi.",
                "source_voice_conversation_id": 8821,
                "created_at": "2026-04-26T14:35:02Z"
            }
        ]
    },
    "pending_count": 3
}
 

Example response (403, Site sahipliği yok):


{
    "message": "forbidden"
}
 

Request      

GET api/sites/{site_id}/outbound-intents

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Query Parameters

kind   string  optional    

Intent türü filtre. Tek değer veya virgülle ayrılmış çoklu (örn. manual,appointment_reminder). Geçerli değerler: manual, appointment_reminder, ai_followup. Example: ai_followup

status   string  optional    

Durum filtre. pending_approval, approved, queued, in_progress, completed, failed, declined, cancelled. Example: pending_approval

per_page   integer  optional    

Sayfa başına kayıt (default 25, max 100). Example: 25

page   integer  optional    

Sayfa numarası. Example: 1

Manuel outbound çağrı niyeti oluştur

requires authentication

Kullanıcı panelden veya 3rd party API'den "şu numarayı şu zamanda ara" dediğinde kullanılır. status=approved olarak yaratılır — worker (voice:run-outbound-intents cron'u) bir sonraki tetiklemede çağrıyı başlatır. scheduled_at boş bırakılırsa hemen aranır (max 1dk gecikme).

Site daily_outbound_limit aşımında 429 döner (manuel kontrol için önce GET /sites/{site}/outbound-intents?status=in_progress sayısını çek).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/outbound-intents" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"target_phone\": \"5551112233\",
    \"target_name\": \"Ali Veli\",
    \"initial_message\": \"Merhaba Ali Bey, salı randevunuzu hatırlatmak için aradım.\",
    \"prompt_override\": \"Sen randevu hatırlatma temsilcisisin.\",
    \"scheduled_at\": \"2026-04-27T14:00:00Z\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/outbound-intents"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "target_phone": "5551112233",
    "target_name": "Ali Veli",
    "initial_message": "Merhaba Ali Bey, salı randevunuzu hatırlatmak için aradım.",
    "prompt_override": "Sen randevu hatırlatma temsilcisisin.",
    "scheduled_at": "2026-04-27T14:00:00Z"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/outbound-intents';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'target_phone' => '5551112233',
            'target_name' => 'Ali Veli',
            'initial_message' => 'Merhaba Ali Bey, salı randevunuzu hatırlatmak için aradım.',
            'prompt_override' => 'Sen randevu hatırlatma temsilcisisin.',
            'scheduled_at' => '2026-04-27T14:00:00Z',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201, Başarılı):


{
    "success": true,
    "message": "Çağrı planlandı. Worker bir sonraki tetiklemede başlatacak.",
    "data": {
        "id": 412,
        "site_id": 5,
        "kind": "manual",
        "status": "approved",
        "target_phone": "5551112233",
        "scheduled_at": "2026-04-27T14:00:00Z",
        "approved_at": "2026-04-26T10:35:00Z"
    }
}
 

Example response (422, Validation hatası):


{
    "message": "The target phone field is required."
}
 

Request      

POST api/sites/{site_id}/outbound-intents

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Body Parameters

target_phone   string     

Aranacak telefon. +90 prefix otomatik eklenir. Example: 5551112233

target_name   string  optional    

Müşteri adı (loglarda görünür). Example: Ali Veli

initial_message   string  optional    

AI'ın söyleyeceği ilk cümle. Boşsa default karşılama. Example: Merhaba Ali Bey, salı randevunuzu hatırlatmak için aradım.

prompt_override   string  optional    

Özel rol promptu — site default kişiliği EZER. Boşsa site varsayılanı. Example: Sen randevu hatırlatma temsilcisisin.

scheduled_at   datetime  optional    

İleri tarihli çağrı (ISO 8601). Boşsa hemen. Example: 2026-04-27T14:00:00Z

POST /api/outbound-intents/{intent}/approve AI follow-up önerisini onaylar (status=pending_approval → approved).

Opsiyonel olarak initial_message / scheduled_at güncellenebilir (kullanıcı düzenler).

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-intents/1/approve" \
    --header "Content-Type: application/json" \
    --data "{
    \"initial_message\": \"vmqeopfuudtdsufvyvddq\",
    \"prompt_override\": \"amniihfqcoynlazghdtqt\",
    \"scheduled_at\": \"2026-07-09T20:56:00\",
    \"target_phone\": \"qxbajwbpilpmufinl\",
    \"target_name\": \"lwloauydlsmsjuryvojcy\"
}"
const url = new URL(
    "https://dowaba.com/api/outbound-intents/1/approve"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "initial_message": "vmqeopfuudtdsufvyvddq",
    "prompt_override": "amniihfqcoynlazghdtqt",
    "scheduled_at": "2026-07-09T20:56:00",
    "target_phone": "qxbajwbpilpmufinl",
    "target_name": "lwloauydlsmsjuryvojcy"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-intents/1/approve';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'initial_message' => 'vmqeopfuudtdsufvyvddq',
            'prompt_override' => 'amniihfqcoynlazghdtqt',
            'scheduled_at' => '2026-07-09T20:56:00',
            'target_phone' => 'qxbajwbpilpmufinl',
            'target_name' => 'lwloauydlsmsjuryvojcy',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-intents/{intent_id}/approve

Headers

Content-Type        

Example: application/json

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

Body Parameters

initial_message   string  optional    

Must not be greater than 1000 characters. Example: vmqeopfuudtdsufvyvddq

prompt_override   string  optional    

Must not be greater than 5000 characters. Example: amniihfqcoynlazghdtqt

scheduled_at   string  optional    

Must be a valid date. Example: 2026-07-09T20:56:00

target_phone   string  optional    

Must not be greater than 20 characters. Example: qxbajwbpilpmufinl

target_name   string  optional    

Must not be greater than 200 characters. Example: lwloauydlsmsjuryvojcy

POST /api/outbound-intents/{intent}/decline AI follow-up önerisini reddet (kullanıcı bu çağrıya gerek yok der).

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-intents/1/decline"
const url = new URL(
    "https://dowaba.com/api/outbound-intents/1/decline"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-intents/1/decline';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-intents/{intent_id}/decline

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

POST /api/outbound-intents/{intent}/cancel Henüz çağrılmamış approved/queued intent'i iptal et.

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-intents/1/cancel"
const url = new URL(
    "https://dowaba.com/api/outbound-intents/1/cancel"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-intents/1/cancel';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-intents/{intent_id}/cancel

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

Birden fazla AI follow-up önerisini toplu onayla.

requires authentication

Yalnızca status=pending_approval olanlar approved olur; diğerleri sessizce atlanır. Worker (voice:run-outbound-intents cron'u) bir sonraki tetiklemede çağrıları başlatır.

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-intents/bulk-approve" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"ids\": [
        12,
        13,
        14
    ]
}"
const url = new URL(
    "https://dowaba.com/api/outbound-intents/bulk-approve"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ids": [
        12,
        13,
        14
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-intents/bulk-approve';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ids' => [
                12,
                13,
                14,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "approved": 12,
    "skipped": 2,
    "requested": 14
}
 

Request      

POST api/outbound-intents/bulk-approve

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

ids   integer[]     

Onaylanacak intent ID'leri (1-200 arası).

Birden fazla AI follow-up önerisini toplu reddet.

requires authentication

Yalnızca pending_approval veya approved (henüz çağrılmamış) intent'ler reddedilebilir. Worker zaten başlattıysa (queued/in_progress) skip edilir.

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-intents/bulk-decline" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"ids\": [
        12,
        13,
        14
    ]
}"
const url = new URL(
    "https://dowaba.com/api/outbound-intents/bulk-decline"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ids": [
        12,
        13,
        14
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-intents/bulk-decline';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ids' => [
                12,
                13,
                14,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "declined": 10,
    "skipped": 4,
    "requested": 14
}
 

Request      

POST api/outbound-intents/bulk-decline

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

ids   integer[]     

Reddedilecek intent ID'leri (1-200 arası).

Voice — Çağrı Kampanyası

Kampanya listesi (status + site filter).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/voice-campaigns?site_id=12&status=running"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns"
);

const params = {
    "site_id": "12",
    "status": "running",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns';
$response = $client->get(
    $url,
    [
        'query' => [
            'site_id' => '12',
            'status' => 'running',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "Haziran kampanyası",
            "status": "running",
            "total_recipients": 120
        }
    ]
}
 

Request      

GET api/voice-campaigns

Query Parameters

site_id   integer  optional    

Site filtresi. Example: 12

status   string  optional    

Durum filtresi (draft|running|paused|completed|cancelled). Example: running

Yeni çağrı kampanyası (status=draft) + alıcı SNAPSHOT + ARAMA onay delili. İlk kullanımda "Sesli Arama Kampanyası Taahhütnamesi" onayı gerekir — eksikse 422 `consent_required` döner; onay `POST /consent/channel/voice_campaign/accept` ile verilir (kopyası e-postayla gönderilir). Başlatmak için /start çağrılır.

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-campaigns" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 12,
    \"contact_group_id\": 5,
    \"name\": \"Haziran kampanyası\",
    \"initial_message\": \"Merhaba, size kampanyamızı anlatmak için aradım.\",
    \"prompt_override\": \"consequatur\",
    \"scheduled_at\": \"2026-06-14T07:00:00Z\",
    \"max_concurrent_calls\": 10,
    \"consent_source\": \"HS_WEB\",
    \"consent_date\": \"2026-06-01 10:00:00\",
    \"consent_confirmed\": true
}"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 12,
    "contact_group_id": 5,
    "name": "Haziran kampanyası",
    "initial_message": "Merhaba, size kampanyamızı anlatmak için aradım.",
    "prompt_override": "consequatur",
    "scheduled_at": "2026-06-14T07:00:00Z",
    "max_concurrent_calls": 10,
    "consent_source": "HS_WEB",
    "consent_date": "2026-06-01 10:00:00",
    "consent_confirmed": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 12,
            'contact_group_id' => 5,
            'name' => 'Haziran kampanyası',
            'initial_message' => 'Merhaba, size kampanyamızı anlatmak için aradım.',
            'prompt_override' => 'consequatur',
            'scheduled_at' => '2026-06-14T07:00:00Z',
            'max_concurrent_calls' => 10,
            'consent_source' => 'HS_WEB',
            'consent_date' => '2026-06-01 10:00:00',
            'consent_confirmed' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "data": {
        "id": 1,
        "status": "draft",
        "total_recipients": 118
    },
    "skipped_no_phone": 2
}
 

Example response (422):


{
    "success": false,
    "error": "consent_required",
    "channel": "voice_campaign",
    "missing_consents": [
        "arama_kampanya"
    ]
}
 

Example response (422):


{
    "success": false,
    "error": "no_trunk",
    "message": "Bu sitede aktif SIP trunk yok."
}
 

Request      

POST api/voice-campaigns

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Erişebildiğin site. Example: 12

contact_group_id   integer     

Aranacak kişi grubu (CSV import sonrası grup). Example: 5

name   string     

Kampanya adı. Example: Haziran kampanyası

initial_message   string  optional    

AI açılış cümlesi. Example: Merhaba, size kampanyamızı anlatmak için aradım.

prompt_override   string  optional    

Kampanya senaryosu / AI talimatı. Example: consequatur

scheduled_at   string  optional    

Başlangıç zamanı (UTC ISO; boş=start ile hemen). Example: 2026-06-14T07:00:00Z

max_concurrent_calls   integer  optional    

Kampanya eşzamanlı tavanı (site limitinin altı). Example: 10

consent_source   string     

İzin kaynağı kodu (değerler /iys/consents/meta). Example: HS_WEB

consent_date   string     

Onayın alındığı gerçek tarih. Example: 2026-06-01 10:00:00

consent_confirmed   boolean     

"Bu listenin arama onayı var" beyanı (true olmalı). Example: true

Kampanya detayı (güncel sayaçlarla).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/voice-campaigns/1"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/voice-campaigns/{id}

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanya güncelle — yalnız status=draft.

Example request:
curl --request PUT \
    "https://dowaba.com/api/voice-campaigns/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"initial_message\": \"amniihfqcoynlazghdtqt\",
    \"prompt_override\": \"qxbajwbpilpmufinllwlo\",
    \"scheduled_at\": \"2026-07-09T20:55:59\",
    \"max_concurrent_calls\": 3
}"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "initial_message": "amniihfqcoynlazghdtqt",
    "prompt_override": "qxbajwbpilpmufinllwlo",
    "scheduled_at": "2026-07-09T20:55:59",
    "max_concurrent_calls": 3
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'initial_message' => 'amniihfqcoynlazghdtqt',
            'prompt_override' => 'qxbajwbpilpmufinllwlo',
            'scheduled_at' => '2026-07-09T20:55:59',
            'max_concurrent_calls' => 3,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/voice-campaigns/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Kampanya id. Example: 1

Body Parameters

name   string  optional    

Must not be greater than 200 characters. Example: vmqeopfuudtdsufvyvddq

initial_message   string  optional    

Must not be greater than 2000 characters. Example: amniihfqcoynlazghdtqt

prompt_override   string  optional    

Must not be greater than 10000 characters. Example: qxbajwbpilpmufinllwlo

scheduled_at   string  optional    

Must be a valid date. Example: 2026-07-09T20:55:59

max_concurrent_calls   integer  optional    

Must be at least 1. Example: 3

Kampanya sil — koşan kampanya silinemez (önce iptal).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/voice-campaigns/1"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/voice-campaigns/{id}

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanyayı başlat (draft→running). scheduled_at doluysa o andan itibaren aranır.

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-campaigns/1/start"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1/start"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1/start';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voice-campaigns/{id}/start

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanyayı duraklat (running→paused). Süren çağrılar kesilmez, yenisi başlamaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-campaigns/1/pause"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1/pause"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1/pause';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voice-campaigns/{id}/pause

URL Parameters

id   integer     

Kampanya id. Example: 1

Duraklatılmış kampanyayı devam ettir (paused→running).

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-campaigns/1/resume"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1/resume"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1/resume';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voice-campaigns/{id}/resume

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanyayı iptal et — bekleyen alıcılar 'skipped' (cancelled) olur, geri alınamaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-campaigns/1/cancel"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1/cancel"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1/cancel';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voice-campaigns/{id}/cancel

URL Parameters

id   integer     

Kampanya id. Example: 1

Ulaşılamayanları tekrar ara — no_answer + failed alıcıları pending'e döndürür ve kampanyayı yeniden başlatır. 'skipped' (opt-out/İYS RET) ASLA yeniden aranmaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/voice-campaigns/1/retry-failed"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1/retry-failed"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1/retry-failed';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 1,
        "status": "running"
    },
    "requeued": 17
}
 

Request      

POST api/voice-campaigns/{id}/retry-failed

URL Parameters

id   integer     

Kampanya id. Example: 1

Alıcı logları (sayfalı, status filtreli). voice_conversation_id transkripte link verir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/voice-campaigns/1/recipients?status=failed&page=1"
const url = new URL(
    "https://dowaba.com/api/voice-campaigns/1/recipients"
);

const params = {
    "status": "failed",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice-campaigns/1/recipients';
$response = $client->get(
    $url,
    [
        'query' => [
            'status' => 'failed',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/voice-campaigns/{id}/recipients

URL Parameters

id   integer     

Kampanya id. Example: 1

Query Parameters

status   string  optional    

Durum filtresi (pending|calling|completed|no_answer|failed|skipped). Example: failed

page   integer  optional    

Sayfa. Example: 1

Outbound Messages (Re-engagement)

Faz 6.B — Outbound mesaj niyetlerini (4 kanal: WA/Telegram/Messenger/Instagram) yöneten endpoint'ler. OutboundIntentController (voice) klonu — voice çağrı yerine kanal mesajı.

Kullanıcının erişebileceği TÜM site'lerdeki intent'leri tek listede döndür.

Merkezi panel için (örn. global re-engagement inbox).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/outbound-messages/all?channel=whatsapp&kind=message_24h_reengagement&status=pending_approval&per_page=17"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/all"
);

const params = {
    "channel": "whatsapp",
    "kind": "message_24h_reengagement",
    "status": "pending_approval",
    "per_page": "17",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/all';
$response = $client->get(
    $url,
    [
        'query' => [
            'channel' => 'whatsapp',
            'kind' => 'message_24h_reengagement',
            'status' => 'pending_approval',
            'per_page' => '17',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/outbound-messages/all

Query Parameters

channel   string  optional    

Kanal filtre (virgülle çoklu). Example: whatsapp

kind   string  optional    

Tür filtre (virgülle çoklu). Example: message_24h_reengagement

status   string  optional    

Durum filtre. Example: pending_approval

per_page   integer  optional    

Sayfa başına (default 25, max 100). Example: 17

Toplu AI mesaj önerisi onayla.

requires authentication

Sadece status=pending_approval olanlar approved olur; diğerleri sessizce atlanır. Re-engagement worker (her dakika) bir sonraki tetiklemede mesajları iletir (24h pencere içinde uygun şablon/free-form ile).

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-messages/bulk-approve" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"ids\": [
        12,
        13,
        14
    ]
}"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/bulk-approve"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ids": [
        12,
        13,
        14
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/bulk-approve';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ids' => [
                12,
                13,
                14,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-messages/bulk-approve

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

ids   integer[]     

Onaylanacak intent ID'leri (1-200).

Toplu AI mesaj önerisi reddet.

requires authentication

Yalnızca pending_approval veya approved (henüz gönderilmemiş) intent'ler reddedilebilir. Worker zaten başlattıysa (queued/in_progress/sent) skip.

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-messages/bulk-decline" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"ids\": [
        12,
        13,
        14
    ]
}"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/bulk-decline"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ids": [
        12,
        13,
        14
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/bulk-decline';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ids' => [
                12,
                13,
                14,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-messages/bulk-decline

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

ids   integer[]     

Reddedilecek intent ID'leri (1-200).

Outbound mesaj niyetlerini listele.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/outbound-messages?channel=whatsapp&kind=message_24h_reengagement&status=pending_approval&per_page=25" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/outbound-messages"
);

const params = {
    "channel": "whatsapp",
    "kind": "message_24h_reengagement",
    "status": "pending_approval",
    "per_page": "25",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/outbound-messages';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
        'query' => [
            'channel' => 'whatsapp',
            'kind' => 'message_24h_reengagement',
            'status' => 'pending_approval',
            'per_page' => '25',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/outbound-messages

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Query Parameters

channel   string  optional    

Kanal filtre (virgülle çoklu). whatsapp,telegram,messenger,instagram. Example: whatsapp

kind   string  optional    

Tür filtre (virgülle çoklu). manual,message_24h_reengagement. Example: message_24h_reengagement

status   string  optional    

Durum filtre. Example: pending_approval

per_page   integer  optional    

Sayfa başına kayıt (default 25, max 100). Example: 25

Manuel outbound mesaj niyeti oluştur (status=approved direkt → worker gönderir).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/outbound-messages" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"channel\": \"whatsapp\",
    \"target_identifier\": \"+90 555 *** ** **\",
    \"target_name\": \"Ali Veli\",
    \"initial_message\": \"Merhaba, konuştuğumuz konudan devam edebilir miyiz?\",
    \"scheduled_at\": \"2026-08-02T10:00:00Z\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/outbound-messages"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "channel": "whatsapp",
    "target_identifier": "+90 555 *** ** **",
    "target_name": "Ali Veli",
    "initial_message": "Merhaba, konuştuğumuz konudan devam edebilir miyiz?",
    "scheduled_at": "2026-08-02T10:00:00Z"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/outbound-messages';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'channel' => 'whatsapp',
            'target_identifier' => '+90 555 *** ** **',
            'target_name' => 'Ali Veli',
            'initial_message' => 'Merhaba, konuştuğumuz konudan devam edebilir miyiz?',
            'scheduled_at' => '2026-08-02T10:00:00Z',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/outbound-messages

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 17

Body Parameters

channel   string     

whatsapp/telegram/messenger/instagram/tiktok/mail/x. Example: whatsapp

target_identifier   string     

Hedef kişinin kanal id'si. Example: +90 555 *** ** **

target_name   string  optional    

Müşteri adı (opsiyonel). Example: Ali Veli

initial_message   string     

Gönderilecek mesaj. Example: Merhaba, konuştuğumuz konudan devam edebilir miyiz?

scheduled_at   datetime  optional    

İleri tarihli (boşsa hemen). Example: 2026-08-02T10:00:00Z

Re-engagement ("Mesaj Önerileri") site ayarlarını getir.

requires authentication

OKUMA yetkisi = SitePolicy::view (isAccessibleBy cascade). Ayarlar mesaj İÇERİĞİ değil operasyonel config → messaging privacy-lock DEĞİL site-görünürlük cascade'i geçerli; yazan herkesin (SitePolicy::update: owner/superadmin/bayi) okuyabilmesi garanti (update ⊂ view). Aksi halde bayi PUT yapabilip GET'te 403 alır (form kırılır).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/outbound-messages/settings" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/sites/1/outbound-messages/settings"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/outbound-messages/settings';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "settings": {
        "window_minutes": 240,
        "auto_approve": false,
        "voice_handoff_enabled": false,
        "voice_handoff_days": 10,
        "voice_handoff_channel": "sip"
    },
    "readiness": {
        "sip_trunk_active": false,
        "whatsapp_calling_active": false,
        "gemini_key_present": "[REDACTED]"
    }
}
 

Request      

GET api/sites/{site_id}/outbound-messages/settings

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Re-engagement site ayarlarını güncelle. Body kısmi olabilir (yalnız gönderilen alanlar yazılır). YAZMA yetkisi = SitePolicy::update (owner + superadmin + bayi cascade; site-team agent politikayı değiştiremez — SiteController::update ile birebir).

requires authentication

Example request:
curl --request PUT \
    "https://dowaba.com/api/sites/1/outbound-messages/settings" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"window_minutes\": 240,
    \"auto_approve\": false,
    \"voice_handoff_enabled\": false,
    \"voice_handoff_days\": 10,
    \"voice_handoff_channel\": \"sip\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/outbound-messages/settings"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "window_minutes": 240,
    "auto_approve": false,
    "voice_handoff_enabled": false,
    "voice_handoff_days": 10,
    "voice_handoff_channel": "sip"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/outbound-messages/settings';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'window_minutes' => 240,
            'auto_approve' => false,
            'voice_handoff_enabled' => false,
            'voice_handoff_days' => 10,
            'voice_handoff_channel' => 'sip',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "settings": {
        "window_minutes": 240,
        "auto_approve": true,
        "voice_handoff_enabled": false,
        "voice_handoff_days": 10,
        "voice_handoff_channel": "sip"
    },
    "readiness": {
        "sip_trunk_active": false,
        "whatsapp_calling_active": false,
        "gemini_key_present": "[REDACTED]"
    }
}
 

Request      

PUT api/sites/{site_id}/outbound-messages/settings

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Body Parameters

window_minutes   integer  optional    

Müşteri sessizliği eşiği (30..1380 dk). Example: 240

auto_approve   boolean  optional    

AI önerisini onay beklemeden otomatik onayla. Example: false

voice_handoff_enabled   boolean  optional    

Uzun sessizlikte telefon devri aç. Example: false

voice_handoff_days   integer  optional    

Telefon devri eşiği (1..60 gün). Example: 10

voice_handoff_channel   string  optional    

Devir kanalı (yalnız sip). Example: sip

Bir konuşmadan (kanal + identifier) AI ile re-engagement mesaj önerisi üret + ONAY BEKLEYEN (pending_approval) manuel intent yarat. storeManual'dan bilinçli FARK: o direkt APPROVED yaratır (mesajı kullanıcı yazdı); bu AI ürettiği için kullanıcı ÖNCE gözden geçirsin diye pending_approval doğar.

requires authentication

IDOR: identifier client'tan gelir → konuşmanın bu site'ın kanal profillerine ait mesajları olduğu site-scope'lu sorgu (conversationMessages) ile DOĞRULANIR; başka tenant'ın identifier'ı boş döner → 404. Bu endpoint'in ANA IDOR yüzeyi budur.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/outbound-messages/generate" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"channel\": \"whatsapp\",
    \"identifier\": \"+90 555 *** ** **\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/outbound-messages/generate"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "channel": "whatsapp",
    "identifier": "+90 555 *** ** **"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/outbound-messages/generate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'channel' => 'whatsapp',
            'identifier' => '+90 555 *** ** **',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "intent": {
        "id": 51,
        "status": "pending_approval"
    },
    "created": false
}
 

Example response (201):


{
    "intent": {
        "id": 51,
        "channel": "whatsapp",
        "kind": "manual",
        "status": "pending_approval",
        "target_identifier": "+90 555 *** ** **",
        "initial_message": "Merhaba, ilettiğiniz konuda size nasıl yardımcı olabilirim?"
    },
    "created": true
}
 

Example response (404):


{
    "message": "conversation_not_found"
}
 

Request      

POST api/sites/{site_id}/outbound-messages/generate

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Site ID. Example: 5

Body Parameters

channel   string     

whatsapp/telegram/messenger/instagram/mail/x. Example: whatsapp

identifier   string     

Hedef müşterinin kanal id'si (telefon/chat_id/PSID/IGSID/e-posta). Example: +90 555 *** ** **

AI önerisini onayla (status=pending_approval → approved).

2026-06-11: declined/cancelled/failed durumları da tekrar onaylanabilir ("Tekrar Onayla"). Worker 24h penceresini gönderim anında zaten kontrol eder (pencere kapalıysa anlamlı failure_reason ile failed'e çeker) — burada ekstra pencere kontrolü gerekmez. completed/queued/in_progress onaylanamaz (çift gönderim riski).

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-messages/1/approve" \
    --header "Content-Type: application/json" \
    --data "{
    \"initial_message\": \"vmqeopfuudtdsufvyvddq\",
    \"scheduled_at\": \"2026-07-09T20:56:00\",
    \"target_identifier\": \"amniihfqcoynlazghdtqt\",
    \"target_name\": \"qxbajwbpilpmufinllwlo\"
}"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/1/approve"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "initial_message": "vmqeopfuudtdsufvyvddq",
    "scheduled_at": "2026-07-09T20:56:00",
    "target_identifier": "amniihfqcoynlazghdtqt",
    "target_name": "qxbajwbpilpmufinllwlo"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/1/approve';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'initial_message' => 'vmqeopfuudtdsufvyvddq',
            'scheduled_at' => '2026-07-09T20:56:00',
            'target_identifier' => 'amniihfqcoynlazghdtqt',
            'target_name' => 'qxbajwbpilpmufinllwlo',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-messages/{intent_id}/approve

Headers

Content-Type        

Example: application/json

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

Body Parameters

initial_message   string  optional    

Must not be greater than 1000 characters. Example: vmqeopfuudtdsufvyvddq

scheduled_at   string  optional    

Must be a valid date. Example: 2026-07-09T20:56:00

target_identifier   string  optional    

Must not be greater than 120 characters. Example: amniihfqcoynlazghdtqt

target_name   string  optional    

Must not be greater than 200 characters. Example: qxbajwbpilpmufinllwlo

AI önerisini reddet.

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-messages/1/decline"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/1/decline"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/1/decline';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-messages/{intent_id}/decline

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

Henüz gönderilmemiş approved/queued intent'i iptal et.

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-messages/1/cancel"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/1/cancel"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/1/cancel';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/outbound-messages/{intent_id}/cancel

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

AI ile öneri mesajını YENİDEN YAZ (preview — KAYDETMEZ). Panel operatörünün serbest-metin talimatını mevcut öneriye uygular, sonucu döndürür ama intent'e YAZMAZ (kullanıcı beğenirse PATCH /outbound-messages/{intent} ile kaydeder).

requires authentication

Yalnız pending_approval intent'lerde çalışır — onaylanmış/gönderilmiş bir öneriyi yeniden yazmak anlamsız. Gemini çağrısı yapar (throttle:30,1 route'ta).

Example request:
curl --request POST \
    "https://dowaba.com/api/outbound-messages/1/ai-rewrite" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"instruction\": \"Daha kısa ve resmi yaz, indirim önerme\"
}"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/1/ai-rewrite"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "instruction": "Daha kısa ve resmi yaz, indirim önerme"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/1/ai-rewrite';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'instruction' => 'Daha kısa ve resmi yaz, indirim önerme',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "current": "Merhaba, konuştuğumuz konudan devam edebilir miyiz?",
    "suggested": "Merhaba, ilettiğiniz konuda size nasıl yardımcı olabilirim?",
    "language": "tr"
}
 

Example response (422):


{
    "success": false,
    "error": "Bu intent 'approved' durumunda — yalnız onay bekleyen öneriler AI ile düzenlenebilir."
}
 

Request      

POST api/outbound-messages/{intent_id}/ai-rewrite

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

intent   integer     

OutboundMessageIntent ID. Example: 42

Body Parameters

instruction   string     

Düzenleme talimatı (3-2000 karakter). Example: Daha kısa ve resmi yaz, indirim önerme

Onay bekleyen öneri mesajını ELLE düzenle (kaydeder). ai-rewrite'ın preview çıktısını veya kullanıcının kendi yazdığını initial_message'a yazar — yalnız pending_approval intent'lerde (onaylanmış/gönderilmiş mesaj değiştirilemez).

requires authentication

metadata.ai_edited_at damgası güncellenir; diğer metadata alanları korunur.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/outbound-messages/1" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"initial_message\": \"Merhaba, ilettiğiniz konuda size nasıl yardımcı olabilirim?\"
}"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "initial_message": "Merhaba, ilettiğiniz konuda size nasıl yardımcı olabilirim?"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/1';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'initial_message' => 'Merhaba, ilettiğiniz konuda size nasıl yardımcı olabilirim?',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "intent": {
        "id": 42,
        "channel": "whatsapp",
        "kind": "message_24h_reengagement",
        "status": "pending_approval",
        "target_identifier": "+90 555 *** ** **",
        "initial_message": "Merhaba, size nasıl yardımcı olabilirim?"
    }
}
 

Example response (422):


{
    "success": false,
    "error": "Bu intent 'approved' durumunda — yalnız onay bekleyen öneriler düzenlenebilir."
}
 

Request      

PATCH api/outbound-messages/{intent_id}

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

intent   integer     

OutboundMessageIntent ID. Example: 42

Body Parameters

initial_message   string     

Yeni mesaj metni (1-4000 karakter). Example: Merhaba, ilettiğiniz konuda size nasıl yardımcı olabilirim?

Konuşma geçmişi — peek modal için (re-engagement önerisinin dayandığı mesajlar).

requires authentication

Tüm kanallar (WA/Telegram/Messenger/Instagram/Mail) için TEK yol: intent.site_id + intent.target_identifier ile MessageContextAnalyzerService'in kanal-başı sorgularından son N mesaj. Instagram bug fix (2026-05-29): eski frontend kanal-spesifik ad-hoc çağrı yapıyordu, IG'de profile_id olmadığı için boş dönüyordu — artık intent üzerinden, authz cascade ile.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/outbound-messages/1/conversation" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/outbound-messages/1/conversation"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/outbound-messages/1/conversation';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "messages": [
        {
            "direction": "in",
            "text": "Merhaba",
            "created_at": "2026-05-29T14:07:47+00:00"
        }
    ]
}
 

Request      

GET api/outbound-messages/{intent_id}/conversation

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

intent_id   integer     

The ID of the intent. Example: 1

intent   integer     

OutboundMessageIntent ID. Example: 42

Randevu Sistemi — Randevular

Randevuları filtreli listele (tarih aralığı, durum, hizmet, personel, müşteri arama).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/appointments"
const url = new URL(
    "https://dowaba.com/api/appointments"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/appointments

Yeni randevu oluştur (admin tarafı). SMS + e-posta bildirimleri tetiklenir.

Example request:
curl --request POST \
    "https://dowaba.com/api/appointments" \
    --header "Content-Type: application/json" \
    --data "{
    \"customer_name\": \"vmqeopfuudtdsufvyvddq\",
    \"customer_phone\": \"amniihfqcoynlazgh\",
    \"customer_email\": \"roob.mona@example.org\",
    \"date\": \"2107-08-08\",
    \"start_time\": \"20:55\",
    \"end_time\": \"2107-08-08\",
    \"notes\": \"mqeopfuudtdsufvyvddqa\",
    \"source\": \"admin\"
}"
const url = new URL(
    "https://dowaba.com/api/appointments"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "customer_name": "vmqeopfuudtdsufvyvddq",
    "customer_phone": "amniihfqcoynlazgh",
    "customer_email": "roob.mona@example.org",
    "date": "2107-08-08",
    "start_time": "20:55",
    "end_time": "2107-08-08",
    "notes": "mqeopfuudtdsufvyvddqa",
    "source": "admin"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'customer_name' => 'vmqeopfuudtdsufvyvddq',
            'customer_phone' => 'amniihfqcoynlazgh',
            'customer_email' => 'roob.mona@example.org',
            'date' => '2107-08-08',
            'start_time' => '20:55',
            'end_time' => '2107-08-08',
            'notes' => 'mqeopfuudtdsufvyvddqa',
            'source' => 'admin',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/appointments

Headers

Content-Type        

Example: application/json

Body Parameters

service_id   string  optional    

The id of an existing record in the appointment_services table.

staff_id   string  optional    

The id of an existing record in the appointment_staff table.

customer_name   string     

value alanı 255 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

customer_phone   string  optional    

value alanı 20 karakterden uzun olmamalıdır. Example: amniihfqcoynlazgh

customer_email   string  optional    

value alanı geçerli bir e-posta adresi olmalıdır. value alanı 255 karakterden uzun olmamalıdır. Example: roob.mona@example.org

date   string     

value alanı geçerli bir tarih olmalıdır. value alanı today tarihine eşit veya ondan sonraki bir tarih olmalıdır. Example: 2107-08-08

start_time   string     

Must be a valid date in the format H:i. Example: 20:55

end_time   string     

Must be a valid date in the format H:i. value alanı start_time tarihinden sonraki bir tarih olmalıdır. Example: 2107-08-08

notes   string  optional    

value alanı 1000 karakterden uzun olmamalıdır. Example: mqeopfuudtdsufvyvddqa

site_id   string  optional    

The id of an existing record in the sites table.

source   string  optional    

Example: admin

Must be one of:
  • widget
  • whatsapp
  • admin
  • phone
  • instagram

Randevu istatistikleri (toplam, durum dağılımı, vb.).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/appointments/stats"
const url = new URL(
    "https://dowaba.com/api/appointments/stats"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments/stats';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/appointments/stats

Belirli bir tarih için müsait randevu slot'larını getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/appointments/available-slots" \
    --header "Content-Type: application/json" \
    --data "{
    \"date\": \"2026-07-09T20:55:56\"
}"
const url = new URL(
    "https://dowaba.com/api/appointments/available-slots"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "date": "2026-07-09T20:55:56"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments/available-slots';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'date' => '2026-07-09T20:55:56',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/appointments/available-slots

Headers

Content-Type        

Example: application/json

Body Parameters

date   string     

value alanı geçerli bir tarih olmalıdır. Example: 2026-07-09T20:55:56

service_id   string  optional    

The id of an existing record in the appointment_services table.

staff_id   string  optional    

The id of an existing record in the appointment_staff table.

site_id   string  optional    

The id of an existing record in the sites table.

Tek randevu detayı (hizmet + personel ile).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/appointments/42"
const url = new URL(
    "https://dowaba.com/api/appointments/42"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments/42';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/appointments/{id}

URL Parameters

id   integer     

Randevu ID'si. Example: 42

Randevuyu güncelle (saat/tarih değişirse mail bildirimi gider).

Example request:
curl --request PUT \
    "https://dowaba.com/api/appointments/7" \
    --header "Content-Type: application/json" \
    --data "{
    \"customer_name\": \"vmqeopfuudtdsufvyvddq\",
    \"customer_phone\": \"amniihfqcoynlazgh\",
    \"customer_email\": \"roob.mona@example.org\",
    \"date\": \"2026-07-09T20:55:56\",
    \"start_time\": \"20:55\",
    \"end_time\": \"20:55\",
    \"status\": \"completed\",
    \"notes\": \"xbajwbpilpmufinllwloa\",
    \"cancel_reason\": \"uydlsmsjuryvojcybzvrb\"
}"
const url = new URL(
    "https://dowaba.com/api/appointments/7"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "customer_name": "vmqeopfuudtdsufvyvddq",
    "customer_phone": "amniihfqcoynlazgh",
    "customer_email": "roob.mona@example.org",
    "date": "2026-07-09T20:55:56",
    "start_time": "20:55",
    "end_time": "20:55",
    "status": "completed",
    "notes": "xbajwbpilpmufinllwloa",
    "cancel_reason": "uydlsmsjuryvojcybzvrb"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments/7';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'customer_name' => 'vmqeopfuudtdsufvyvddq',
            'customer_phone' => 'amniihfqcoynlazgh',
            'customer_email' => 'roob.mona@example.org',
            'date' => '2026-07-09T20:55:56',
            'start_time' => '20:55',
            'end_time' => '20:55',
            'status' => 'completed',
            'notes' => 'xbajwbpilpmufinllwloa',
            'cancel_reason' => 'uydlsmsjuryvojcybzvrb',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/appointments/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Randevu ID'si. Example: 7

Body Parameters

service_id   string  optional    

The id of an existing record in the appointment_services table.

staff_id   string  optional    

The id of an existing record in the appointment_staff table.

customer_name   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

customer_phone   string  optional    

value alanı 20 karakterden uzun olmamalıdır. Example: amniihfqcoynlazgh

customer_email   string  optional    

value alanı geçerli bir e-posta adresi olmalıdır. value alanı 255 karakterden uzun olmamalıdır. Example: roob.mona@example.org

date   string  optional    

value alanı geçerli bir tarih olmalıdır. Example: 2026-07-09T20:55:56

start_time   string  optional    

Must be a valid date in the format H:i. Example: 20:55

end_time   string  optional    

Must be a valid date in the format H:i. Example: 20:55

status   string  optional    

Example: completed

Must be one of:
  • pending
  • confirmed
  • cancelled
  • completed
  • no_show
notes   string  optional    

value alanı 1000 karakterden uzun olmamalıdır. Example: xbajwbpilpmufinllwloa

cancel_reason   string  optional    

value alanı 500 karakterden uzun olmamalıdır. Example: uydlsmsjuryvojcybzvrb

Randevuyu sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/appointments/12"
const url = new URL(
    "https://dowaba.com/api/appointments/12"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments/12';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/appointments/{id}

URL Parameters

id   integer     

Randevu ID'si. Example: 12

Randevu durumunu güncelle (pending/confirmed/cancelled/completed/no_show). SMS + e-posta tetikler.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/appointments/42/status" \
    --header "Content-Type: application/json" \
    --data "{
    \"status\": \"confirmed\",
    \"cancel_reason\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/appointments/42/status"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "status": "confirmed",
    "cancel_reason": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointments/42/status';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'status' => 'confirmed',
            'cancel_reason' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/appointments/{id}/status

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Randevu ID'si. Example: 42

Body Parameters

status   string     

Example: confirmed

Must be one of:
  • pending
  • confirmed
  • cancelled
  • completed
  • no_show
cancel_reason   string  optional    

value alanı 500 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

Randevu Sistemi — Hizmetler

Hizmet listesi (sıralı).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/appointment-services"
const url = new URL(
    "https://dowaba.com/api/appointment-services"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-services';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/appointment-services

Yeni hizmet oluştur (süre + opsiyonel fiyat).

Example request:
curl --request POST \
    "https://dowaba.com/api/appointment-services" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"description\": \"Saç kesimi ve fön, yıkama dahil\",
    \"duration_minutes\": 8,
    \"price\": 18,
    \"currency\": \"qco\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/appointment-services"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "description": "Saç kesimi ve fön, yıkama dahil",
    "duration_minutes": 8,
    "price": 18,
    "currency": "qco",
    "is_active": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-services';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'description' => 'Saç kesimi ve fön, yıkama dahil',
            'duration_minutes' => 8,
            'price' => 18,
            'currency' => 'qco',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/appointment-services

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

value alanı 255 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

description   string  optional    

Hizmetin kısa açıklaması. Example: Saç kesimi ve fön, yıkama dahil

duration_minutes   integer     

value alanı en az 5 olmalıdır. value alanı 480 değerinden büyük olmamalıdır. Example: 8

price   number  optional    

value alanı en az 0 olmalıdır. Example: 18

currency   string  optional    

value alanı 3 karakterden uzun olmamalıdır. Example: qco

is_active   boolean  optional    

Example: false

site_id   string  optional    

The id of an existing record in the sites table.

Tüm hizmetlerin fiyatını yüzde veya sabit tutar ile artır/azalt.

Example request:
curl --request POST \
    "https://dowaba.com/api/appointment-services/bulk-price" \
    --header "Content-Type: application/json" \
    --data "{
    \"type\": \"fixed\",
    \"direction\": \"increase\",
    \"value\": 73
}"
const url = new URL(
    "https://dowaba.com/api/appointment-services/bulk-price"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "type": "fixed",
    "direction": "increase",
    "value": 73
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-services/bulk-price';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'type' => 'fixed',
            'direction' => 'increase',
            'value' => 73,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/appointment-services/bulk-price

Headers

Content-Type        

Example: application/json

Body Parameters

type   string     

Example: fixed

Must be one of:
  • percentage
  • fixed
direction   string     

Example: increase

Must be one of:
  • increase
  • decrease
value   number     

value alanı en az 0.01 olmalıdır. Example: 73

Hizmeti güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/appointment-services/7" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"description\": \"Saç kesimi ve fön, yıkama dahil\",
    \"duration_minutes\": 8,
    \"price\": 18,
    \"currency\": \"qco\",
    \"is_active\": true
}"
const url = new URL(
    "https://dowaba.com/api/appointment-services/7"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "description": "Saç kesimi ve fön, yıkama dahil",
    "duration_minutes": 8,
    "price": 18,
    "currency": "qco",
    "is_active": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-services/7';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'description' => 'Saç kesimi ve fön, yıkama dahil',
            'duration_minutes' => 8,
            'price' => 18,
            'currency' => 'qco',
            'is_active' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/appointment-services/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Hizmet ID'si. Example: 7

Body Parameters

name   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

description   string  optional    

Hizmetin kısa açıklaması. Example: Saç kesimi ve fön, yıkama dahil

duration_minutes   integer  optional    

value alanı en az 5 olmalıdır. value alanı 480 değerinden büyük olmamalıdır. Example: 8

price   number  optional    

value alanı en az 0 olmalıdır. Example: 18

currency   string  optional    

value alanı 3 karakterden uzun olmamalıdır. Example: qco

is_active   boolean  optional    

Example: true

Hizmeti sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/appointment-services/7"
const url = new URL(
    "https://dowaba.com/api/appointment-services/7"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-services/7';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/appointment-services/{id}

URL Parameters

id   integer     

Hizmet ID'si. Example: 7

Randevu Sistemi — Personel

Personel listesi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/appointment-staff"
const url = new URL(
    "https://dowaba.com/api/appointment-staff"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-staff';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/appointment-staff

Yeni personel ekle (ad, ünvan, çalışma saatleri).

Example request:
curl --request POST \
    "https://dowaba.com/api/appointment-staff" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"title\": \"amniihfqcoynlazghdtqt\",
    \"phone\": \"qxbajwbpilpmufinl\",
    \"email\": \"imogene.mante@example.com\",
    \"is_active\": false,
    \"sort_order\": 72
}"
const url = new URL(
    "https://dowaba.com/api/appointment-staff"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "title": "amniihfqcoynlazghdtqt",
    "phone": "qxbajwbpilpmufinl",
    "email": "imogene.mante@example.com",
    "is_active": false,
    "sort_order": 72
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-staff';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'title' => 'amniihfqcoynlazghdtqt',
            'phone' => 'qxbajwbpilpmufinl',
            'email' => 'imogene.mante@example.com',
            'is_active' => false,
            'sort_order' => 72,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/appointment-staff

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

value alanı 255 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

title   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: amniihfqcoynlazghdtqt

phone   string  optional    

value alanı 20 karakterden uzun olmamalıdır. Example: qxbajwbpilpmufinl

email   string  optional    

value alanı geçerli bir e-posta adresi olmalıdır. value alanı 255 karakterden uzun olmamalıdır. Example: imogene.mante@example.com

working_hours   object  optional    
is_active   boolean  optional    

Example: false

sort_order   integer  optional    

value alanı en az 0 olmalıdır. Example: 72

Personel bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/appointment-staff/5" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"title\": \"amniihfqcoynlazghdtqt\",
    \"phone\": \"qxbajwbpilpmufinl\",
    \"email\": \"imogene.mante@example.com\",
    \"is_active\": true,
    \"sort_order\": 72
}"
const url = new URL(
    "https://dowaba.com/api/appointment-staff/5"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "title": "amniihfqcoynlazghdtqt",
    "phone": "qxbajwbpilpmufinl",
    "email": "imogene.mante@example.com",
    "is_active": true,
    "sort_order": 72
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-staff/5';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'title' => 'amniihfqcoynlazghdtqt',
            'phone' => 'qxbajwbpilpmufinl',
            'email' => 'imogene.mante@example.com',
            'is_active' => true,
            'sort_order' => 72,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/appointment-staff/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Personel ID'si. Example: 5

Body Parameters

name   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

title   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: amniihfqcoynlazghdtqt

phone   string  optional    

value alanı 20 karakterden uzun olmamalıdır. Example: qxbajwbpilpmufinl

email   string  optional    

value alanı geçerli bir e-posta adresi olmalıdır. value alanı 255 karakterden uzun olmamalıdır. Example: imogene.mante@example.com

working_hours   object  optional    
is_active   boolean  optional    

Example: true

sort_order   integer  optional    

value alanı en az 0 olmalıdır. Example: 72

Personel kaydını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/appointment-staff/5"
const url = new URL(
    "https://dowaba.com/api/appointment-staff/5"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-staff/5';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/appointment-staff/{id}

URL Parameters

id   integer     

Personel ID'si. Example: 5

Randevu Sistemi — Ayarlar

Randevu ayarlarını getir (çalışma saatleri, slot süresi, tatiller, vb.).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/appointment-settings"
const url = new URL(
    "https://dowaba.com/api/appointment-settings"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-settings';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/appointment-settings

Randevu ayarlarını güncelle (saat dilimleri, otomatik onay, sesli hatırlatma vb.).

Example request:
curl --request PUT \
    "https://dowaba.com/api/appointment-settings" \
    --header "Content-Type: application/json" \
    --data "{
    \"slot_duration\": 21,
    \"break_between\": 13,
    \"advance_booking_days\": 16,
    \"auto_confirm\": true,
    \"send_sms_notification\": true,
    \"send_whatsapp_notification\": false,
    \"send_email_notification\": true,
    \"notify_admin_phone\": \"eopfuudtdsufvyvdd\",
    \"notify_admin_email\": \"jaylan50@example.com\",
    \"send_sms_to_staff_on_confirm\": true,
    \"confirmation_message\": \"ihfqcoynlazghdtqtqxba\",
    \"cancellation_message\": \"jwbpilpmufinllwloauyd\",
    \"reminder_message\": \"lsmsjuryvojcybzvrbyic\",
    \"send_call_reminder\": true,
    \"call_reminder_hours_before\": 11,
    \"call_reminder_message_template\": \"znkygloigmkwxphlvazjr\",
    \"send_wa_reminder\": true,
    \"wa_reminder_minutes_before\": 3,
    \"wa_reminder_profile_id\": 17,
    \"wa_reminder_customer_enabled\": true,
    \"wa_reminder_customer_template\": \"mqeopfuudtdsufvyvddqa\",
    \"wa_reminder_customer_language\": \"mniihfqco\",
    \"wa_reminder_staff_enabled\": false,
    \"wa_reminder_staff_template\": \"ynlazghdtqtqxbajwbpil\",
    \"wa_reminder_staff_language\": \"pmufinllw\"
}"
const url = new URL(
    "https://dowaba.com/api/appointment-settings"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "slot_duration": 21,
    "break_between": 13,
    "advance_booking_days": 16,
    "auto_confirm": true,
    "send_sms_notification": true,
    "send_whatsapp_notification": false,
    "send_email_notification": true,
    "notify_admin_phone": "eopfuudtdsufvyvdd",
    "notify_admin_email": "jaylan50@example.com",
    "send_sms_to_staff_on_confirm": true,
    "confirmation_message": "ihfqcoynlazghdtqtqxba",
    "cancellation_message": "jwbpilpmufinllwloauyd",
    "reminder_message": "lsmsjuryvojcybzvrbyic",
    "send_call_reminder": true,
    "call_reminder_hours_before": 11,
    "call_reminder_message_template": "znkygloigmkwxphlvazjr",
    "send_wa_reminder": true,
    "wa_reminder_minutes_before": 3,
    "wa_reminder_profile_id": 17,
    "wa_reminder_customer_enabled": true,
    "wa_reminder_customer_template": "mqeopfuudtdsufvyvddqa",
    "wa_reminder_customer_language": "mniihfqco",
    "wa_reminder_staff_enabled": false,
    "wa_reminder_staff_template": "ynlazghdtqtqxbajwbpil",
    "wa_reminder_staff_language": "pmufinllw"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/appointment-settings';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'slot_duration' => 21,
            'break_between' => 13,
            'advance_booking_days' => 16,
            'auto_confirm' => true,
            'send_sms_notification' => true,
            'send_whatsapp_notification' => false,
            'send_email_notification' => true,
            'notify_admin_phone' => 'eopfuudtdsufvyvdd',
            'notify_admin_email' => 'jaylan50@example.com',
            'send_sms_to_staff_on_confirm' => true,
            'confirmation_message' => 'ihfqcoynlazghdtqtqxba',
            'cancellation_message' => 'jwbpilpmufinllwloauyd',
            'reminder_message' => 'lsmsjuryvojcybzvrbyic',
            'send_call_reminder' => true,
            'call_reminder_hours_before' => 11,
            'call_reminder_message_template' => 'znkygloigmkwxphlvazjr',
            'send_wa_reminder' => true,
            'wa_reminder_minutes_before' => 3,
            'wa_reminder_profile_id' => 17,
            'wa_reminder_customer_enabled' => true,
            'wa_reminder_customer_template' => 'mqeopfuudtdsufvyvddqa',
            'wa_reminder_customer_language' => 'mniihfqco',
            'wa_reminder_staff_enabled' => false,
            'wa_reminder_staff_template' => 'ynlazghdtqtqxbajwbpil',
            'wa_reminder_staff_language' => 'pmufinllw',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/appointment-settings

Headers

Content-Type        

Example: application/json

Body Parameters

working_hours   object  optional    
slot_duration   integer  optional    

value alanı en az 5 olmalıdır. value alanı 240 değerinden büyük olmamalıdır. Example: 21

break_between   integer  optional    

value alanı en az 0 olmalıdır. value alanı 120 değerinden büyük olmamalıdır. Example: 13

holidays   object  optional    
advance_booking_days   integer  optional    

value alanı en az 1 olmalıdır. value alanı 365 değerinden büyük olmamalıdır. Example: 16

auto_confirm   boolean  optional    

Example: true

send_sms_notification   boolean  optional    

Example: true

send_whatsapp_notification   boolean  optional    

Example: false

send_email_notification   boolean  optional    

Example: true

notify_admin_phone   string  optional    

value alanı 20 karakterden uzun olmamalıdır. Example: eopfuudtdsufvyvdd

notify_admin_email   string  optional    

value alanı geçerli bir e-posta adresi olmalıdır. value alanı 255 karakterden uzun olmamalıdır. Example: jaylan50@example.com

send_sms_to_staff_on_confirm   boolean  optional    

Example: true

confirmation_message   string  optional    

value alanı 1000 karakterden uzun olmamalıdır. Example: ihfqcoynlazghdtqtqxba

cancellation_message   string  optional    

value alanı 1000 karakterden uzun olmamalıdır. Example: jwbpilpmufinllwloauyd

reminder_message   string  optional    

value alanı 1000 karakterden uzun olmamalıdır. Example: lsmsjuryvojcybzvrbyic

send_call_reminder   boolean  optional    

Faz 4.5 — sesli arama hatırlatması. Example: true

call_reminder_hours_before   integer  optional    

value alanı en az 1 olmalıdır. value alanı 168 değerinden büyük olmamalıdır. Example: 11

call_reminder_message_template   string  optional    

value alanı 2000 karakterden uzun olmamalıdır. Example: znkygloigmkwxphlvazjr

send_wa_reminder   boolean  optional    

WhatsApp şablon randevu hatırlatması (2026-07-02) — DAKİKA bazlı, müşteri + personel. Example: true

wa_reminder_minutes_before   integer  optional    

value alanı en az 5 olmalıdır. value alanı 10080 değerinden büyük olmamalıdır. Example: 3

wa_reminder_profile_id   integer  optional    

5dk .. 7gün. Example: 17

wa_reminder_customer_enabled   boolean  optional    

Example: true

wa_reminder_customer_template   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: mqeopfuudtdsufvyvddqa

wa_reminder_customer_language   string  optional    

value alanı 10 karakterden uzun olmamalıdır. Example: mniihfqco

wa_reminder_customer_vars   object  optional    
wa_reminder_staff_enabled   boolean  optional    

Example: false

wa_reminder_staff_template   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: ynlazghdtqtqxbajwbpil

wa_reminder_staff_language   string  optional    

value alanı 10 karakterden uzun olmamalıdır. Example: pmufinllw

wa_reminder_staff_vars   object  optional    
site_id   string  optional    

The id of an existing record in the sites table.

WhatsApp Entegrasyonu

Kullanıcının tüm WhatsApp profillerini listele (link sayısıyla).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp-profiles"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp-profiles

Yeni WhatsApp profili oluştur (Meta Cloud API veya Evolution API).

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"phone_number_id\": \"102290129340398\",
    \"business_account_id\": \"102290129340399\",
    \"app_id\": \"1234567890\",
    \"graph_version\": \"v24.0\",
    \"waba_id\": \"102290129340399\",
    \"instagram_account_id\": \"17841400000000000\",
    \"notification_phone\": \"mqeopfuudtdsufvyv\",
    \"netgsm_username\": \"ddqamniihfqcoynlazghd\",
    \"netgsm_password\": \"tqtqxbajwbpilpmufinll\",
    \"netgsm_header\": \"wloauydls\"
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "phone_number_id": "102290129340398",
    "business_account_id": "102290129340399",
    "app_id": "1234567890",
    "graph_version": "v24.0",
    "waba_id": "102290129340399",
    "instagram_account_id": "17841400000000000",
    "notification_phone": "mqeopfuudtdsufvyv",
    "netgsm_username": "ddqamniihfqcoynlazghd",
    "netgsm_password": "tqtqxbajwbpilpmufinll",
    "netgsm_header": "wloauydls"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'phone_number_id' => '102290129340398',
            'business_account_id' => '102290129340399',
            'app_id' => '1234567890',
            'graph_version' => 'v24.0',
            'waba_id' => '102290129340399',
            'instagram_account_id' => '17841400000000000',
            'notification_phone' => 'mqeopfuudtdsufvyv',
            'netgsm_username' => 'ddqamniihfqcoynlazghd',
            'netgsm_password' => 'tqtqxbajwbpilpmufinll',
            'netgsm_header' => 'wloauydls',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

phone_number_id   string  optional    

Meta Cloud API telefon numarası ID'si. Example: 102290129340398

business_account_id   string  optional    

Meta Business hesap ID'si. Example: 102290129340399

app_id   string  optional    

Meta uygulama (App) ID'si. Example: 1234567890

app_secret   string  optional    

Meta uygulama gizli anahtarı.

short_token   string  optional    

Meta erişim token'ı (EAA ile başlayan System User token).

graph_version   string  optional    

Graph API sürümü (boş bırakılırsa v24.0). Example: v24.0

waba_id   string  optional    

WhatsApp Business Account (WABA) ID'si. Example: 102290129340399

instagram_account_id   string  optional    

Bağlı Instagram hesap ID'si. Example: 17841400000000000

instagram_page_token   string  optional    

Instagram sayfa erişim token'ı.

webhook_verify_token   string  optional    

Webhook doğrulama token'ı (boşsa otomatik üretilir).

notification_phone   string  optional    

Must not be greater than 20 characters. Example: mqeopfuudtdsufvyv

netgsm_username   string  optional    

Must not be greater than 50 characters. Example: ddqamniihfqcoynlazghd

netgsm_password   string  optional    

Must not be greater than 100 characters. Example: tqtqxbajwbpilpmufinll

netgsm_header   string  optional    

Must not be greater than 11 characters. Example: wloauydls

Tek WhatsApp profilini detayıyla getirir. Profilin sahibi, sahibinin bayisi (yönetim cascade'i) ve superadmin erişebilir; yanıt, entegrasyon ayarlarını düzenleyebilmeniz için profilin bağlantı bilgilerini içerir. Cascade dışındaki profillere erişim 403 döner.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp-profiles/6"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp-profiles/{id}

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

WhatsApp profil bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/whatsapp-profiles/6" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"phone_number_id\": \"102290129340398\",
    \"business_account_id\": \"102290129340399\",
    \"app_id\": \"1234567890\",
    \"short_token\": \"mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjuryvojcybzvrbyickznkygloigmkwxphlvazjrcnfbaqywuxhgjjmzuxjubqouzswiwx\",
    \"graph_version\": \"v24.0\",
    \"waba_id\": \"102290129340399\",
    \"instagram_account_id\": \"17841400000000000\",
    \"notification_phone\": \"mqeopfuudtdsufvyv\",
    \"netgsm_username\": \"ddqamniihfqcoynlazghd\",
    \"netgsm_password\": \"tqtqxbajwbpilpmufinll\",
    \"netgsm_header\": \"wloauydls\",
    \"is_active\": true
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "phone_number_id": "102290129340398",
    "business_account_id": "102290129340399",
    "app_id": "1234567890",
    "short_token": "mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjuryvojcybzvrbyickznkygloigmkwxphlvazjrcnfbaqywuxhgjjmzuxjubqouzswiwx",
    "graph_version": "v24.0",
    "waba_id": "102290129340399",
    "instagram_account_id": "17841400000000000",
    "notification_phone": "mqeopfuudtdsufvyv",
    "netgsm_username": "ddqamniihfqcoynlazghd",
    "netgsm_password": "tqtqxbajwbpilpmufinll",
    "netgsm_header": "wloauydls",
    "is_active": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'phone_number_id' => '102290129340398',
            'business_account_id' => '102290129340399',
            'app_id' => '1234567890',
            'short_token' => 'mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjuryvojcybzvrbyickznkygloigmkwxphlvazjrcnfbaqywuxhgjjmzuxjubqouzswiwx',
            'graph_version' => 'v24.0',
            'waba_id' => '102290129340399',
            'instagram_account_id' => '17841400000000000',
            'notification_phone' => 'mqeopfuudtdsufvyv',
            'netgsm_username' => 'ddqamniihfqcoynlazghd',
            'netgsm_password' => 'tqtqxbajwbpilpmufinll',
            'netgsm_header' => 'wloauydls',
            'is_active' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/whatsapp-profiles/{id}

PATCH api/whatsapp-profiles/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

Body Parameters

name   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

phone_number_id   string  optional    

Meta Cloud API telefon numarası ID'si. Example: 102290129340398

business_account_id   string  optional    

Meta Business hesap ID'si. Example: 102290129340399

app_id   string  optional    

Meta uygulama (App) ID'si. Example: 1234567890

app_secret   string  optional    

Meta uygulama gizli anahtarı.

short_token   string  optional    

Must match the regex /^EAA[A-Za-z0-9_-]+$/. Must be at least 150 characters. Example: mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjuryvojcybzvrbyickznkygloigmkwxphlvazjrcnfbaqywuxhgjjmzuxjubqouzswiwx

graph_version   string  optional    

Graph API sürümü. Example: v24.0

waba_id   string  optional    

WhatsApp Business Account (WABA) ID'si. Example: 102290129340399

instagram_account_id   string  optional    

Bağlı Instagram hesap ID'si. Example: 17841400000000000

instagram_page_token   string  optional    

Instagram sayfa erişim token'ı.

webhook_verify_token   string  optional    

Webhook doğrulama token'ı.

notification_phone   string  optional    

Must not be greater than 20 characters. Example: mqeopfuudtdsufvyv

netgsm_username   string  optional    

Must not be greater than 50 characters. Example: ddqamniihfqcoynlazghd

netgsm_password   string  optional    

Must not be greater than 100 characters. Example: tqtqxbajwbpilpmufinll

netgsm_header   string  optional    

Must not be greater than 11 characters. Example: wloauydls

is_active   boolean  optional    

Example: true

WhatsApp profilini KALICI sil — her yerden temizler: 1. Evolution API: önce logout (oturumu kes), sonra deleteInstance. Logout sırasındaki "instance not connected" hatası normal — yine de delete dene. 2. site_whatsapp_profile pivot satırlarını sil (FK cascade'i bekleme). 3. WhatsappProfile DB satırını sil. Response: evolution_cleaned + warnings array — frontend kullanıcıya net feedback verir. Kullanıcı "her yerden temiz silinsin" istediğinde bu endpoint çağrılır; arta kalan kalıntı kalmaz, aynı telefon yeniden bağlanırsa temiz başlar.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/whatsapp-profiles/6"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/whatsapp-profiles/{id}

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

WhatsApp profil bağlantısını test et (Meta API veya Evolution status).

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/6/test"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles/{whatsapp_profile_id}/test

URL Parameters

whatsapp_profile_id   integer     

The ID of the whatsapp profile. Example: 6

Kanal-bazlı AI bot aç/kapat ("Botu Durdur" / "Botu Başlat" — entegrasyon sayfası). Profil seviyesinde AI otomatik yanıtı durdurur/başlatır; gelen mesajlar inbox'a düşmeye devam eder ve kampanya gönderimleri etkilenmez. Yalnızca sahibi olduğunuz veya yetkilendirildiğiniz (bayi/ekip erişimi) profiller değiştirilebilir. Yanıt anahtarı `bot_active`'tir (tüm kanal API'lerinde ortak).

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/6/toggle-bot"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/toggle-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/toggle-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles/{id}/toggle-bot

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

WhatsApp sesli arama (Calling) bayrağını aç/kapat (Dowaba dahili flag).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/whatsapp-profiles/6/calling" \
    --header "Content-Type: application/json" \
    --data "{
    \"enabled\": true
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/calling"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "enabled": true
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/calling';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'enabled' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/whatsapp-profiles/{whatsapp_profile_id}/calling

Headers

Content-Type        

Example: application/json

URL Parameters

whatsapp_profile_id   integer     

The ID of the whatsapp profile. Example: 6

Body Parameters

enabled   boolean     

Example: true

Profile bazlı KVKK aydınlatma metni toggle. Hiyerarşi: site.settings.kvkk_compliance_mode=false override eder (site OFF → tüm kanallar/hesaplar OFF). Site açıkken bu kolon o WhatsApp hesabı için aydınlatma metnini kapatır (kişisel kullanım vs.). Default true (KVKK Md.10 uyumu yeni profillerde açık).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/whatsapp-profiles/6/kvkk" \
    --header "Content-Type: application/json" \
    --data "{
    \"enabled\": false
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/kvkk"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "enabled": false
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/kvkk';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'enabled' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/whatsapp-profiles/{whatsapp_profile_id}/kvkk

Headers

Content-Type        

Example: application/json

URL Parameters

whatsapp_profile_id   integer     

The ID of the whatsapp profile. Example: 6

Body Parameters

enabled   boolean     

Toggle değeri. Example: false

Platform WABA modu bilgisini döner (selfhosted/platform/evolution).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp-profiles/platform/mode"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/platform/mode"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/platform/mode';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp-profiles/platform/mode

Platform WABA'sındaki telefon numaralarını listele (platform modu). Route 2026 başından beri vardı ama metot HİÇ yazılmamıştı (platform modunda SettingsView çağırınca 500 — 2026-07-02 audit bulgusu). Numaralar Meta Graph'tan çekilir; her satıra `is_taken` (bir kullanıcıda aktif platform profili var) + `is_mine` (o kullanıcı benim) eklenir — frontend seçim kartı `phone.is_taken && !phone.is_mine` ile başkasının numarasını kilitler. Token kullanıcıya asla dönmez (connectPlatformPhone sözleşmesi).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp-profiles/platform/phones"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/platform/phones"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/platform/phones';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp-profiles/platform/phones

Platform telefon numarasını kullanıcıya bağla (token kullanıcıya gösterilmez).

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/platform/connect" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone_number_id\": \"102290129340398\"
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/platform/connect"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone_number_id": "102290129340398"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/platform/connect';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone_number_id' => '102290129340398',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles/platform/connect

Headers

Content-Type        

Example: application/json

Body Parameters

phone_number_id   string     

Platform WABA'sındaki telefon numarasının Meta ID'si. Example: 102290129340398

Platform WABA bağlantısını kes.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/platform/disconnect"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/platform/disconnect"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/platform/disconnect';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles/platform/disconnect

Evolution API ile yeni instance oluştur ve QR kodu döndür.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/evolution/create" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/evolution/create"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/evolution/create';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles/evolution/create

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

Evolution API profili için bağlantı QR kodunu al.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp-profiles/6/evolution/qrcode"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/evolution/qrcode"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/evolution/qrcode';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp-profiles/{id}/evolution/qrcode

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

Evolution API profili bağlantı durumunu kontrol et.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp-profiles/6/evolution/status"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/evolution/status"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/evolution/status';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp-profiles/{id}/evolution/status

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

Evolution API instance'ını logout yap.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/6/evolution/disconnect"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/evolution/disconnect"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/evolution/disconnect';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles/{id}/evolution/disconnect

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

Evolution API instance'ını yeniden başlat ve yeni QR al.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/6/evolution/reconnect"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/evolution/reconnect"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/evolution/reconnect';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp-profiles/{id}/evolution/reconnect

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/6/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 12
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 12
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 12,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp-profiles/6/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 12
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 12
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 12,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

WhatsApp profiline bağlı siteleri listele. Authz: liste cascade'i (whatsappProfileIds — pivot ∪ user_id). Frontend store her listelenen profil için bunu çağırıp "bağlı / bağlanabilir" ayrımını yapar; eski strict user_id check'i bayi/müşteri için hep boş dönmesine ve bağlı profillerin "Bağlanabilir hesaplar"da görünmesine yol açıyordu. Dönen site listesi kullanıcının accessibleSiteIds'ine kelepçelenir — ortak profil başka tenant'ın sitelerini sızdırmaz.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp-profiles/6/linked-sites"
const url = new URL(
    "https://dowaba.com/api/whatsapp-profiles/6/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp-profiles/6/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp-profiles/{id}/linked-sites

URL Parameters

id   integer     

The ID of the whatsapp profile. Example: 6

Tüm konuşmaları listele (kullanıcının sitelerine ait).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp/conversations"
const url = new URL(
    "https://dowaba.com/api/whatsapp/conversations"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/conversations';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp/conversations

Belirli bir numara için mesajları getir. Opt-in sayfalama: `limit`/`before_id` verilmezse TÜM mesajlar (eski davranış, bare array) döner. Verilirse en yeni `limit` mesaj + `{messages, has_more, oldest_id}` (yukarı kaydırma cursor'ı).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp/messages/+905551234567?limit=50&before_id=12345"
const url = new URL(
    "https://dowaba.com/api/whatsapp/messages/+905551234567"
);

const params = {
    "limit": "50",
    "before_id": "12345",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/messages/+905551234567';
$response = $client->get(
    $url,
    [
        'query' => [
            'limit' => '50',
            'before_id' => '12345',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Sayfalı (limit/before_id verildi)):


{
    "messages": [
        {
            "id": 12300,
            "direction": "in",
            "message": "Merhaba",
            "metadata": null,
            "message_id": "wamid.xxx",
            "delivery_status": null,
            "delivery_error": null,
            "media_url": null,
            "media_type": null,
            "media_mime": null,
            "created_at": "14:32",
            "date": "05.06.2026"
        }
    ],
    "has_more": true,
    "oldest_id": 12300
}
 

Request      

GET api/whatsapp/messages/{phone}

URL Parameters

phone   string     

Mesajları getirilecek telefon numarası. Example: +905551234567

id   integer     

Path'in {id} varyantı için mesaj DB id'si. Example: 42

Query Parameters

limit   integer  optional    

Sayfa boyutu (varsayılan 50, maks 200). Verilirse sayfalı yanıt döner. Example: 50

before_id   integer  optional    

Bu id'den ESKİ mesajları getir (scroll-up cursor). Yanıttaki oldest_id ile zincirlenir. Example: 12345

WhatsApp mesajı gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp/send" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"+905551234567\",
    \"site_id\": 17,
    \"message\": \"mqeopfuudtdsufvyvddqa\",
    \"media_url\": \"https:\\/\\/www.lakin.com\\/veniam-sed-fuga-aspernatur-natus-earum\",
    \"media_file_id\": 17,
    \"media_type\": \"video\",
    \"media_mime\": \"mqeopfuudtdsufvyvddqa\",
    \"media_filename\": \"mniihfqcoynlazghdtqtq\"
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp/send"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+905551234567",
    "site_id": 17,
    "message": "mqeopfuudtdsufvyvddqa",
    "media_url": "https:\/\/www.lakin.com\/veniam-sed-fuga-aspernatur-natus-earum",
    "media_file_id": 17,
    "media_type": "video",
    "media_mime": "mqeopfuudtdsufvyvddqa",
    "media_filename": "mniihfqcoynlazghdtqtq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/send';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => '+905551234567',
            'site_id' => 17,
            'message' => 'mqeopfuudtdsufvyvddqa',
            'media_url' => 'https://www.lakin.com/veniam-sed-fuga-aspernatur-natus-earum',
            'media_file_id' => 17,
            'media_type' => 'video',
            'media_mime' => 'mqeopfuudtdsufvyvddqa',
            'media_filename' => 'mniihfqcoynlazghdtqtq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp/send

Headers

Content-Type        

Example: application/json

Body Parameters

phone   string     

Alıcı telefon numarası (E.164). Example: +905551234567

site_id   integer  optional    

Example: 17

message   string  optional    

Must not be greater than 4096 characters. Example: mqeopfuudtdsufvyvddqa

media_url   string  optional    

Must be a valid URL. Must not be greater than 2048 characters. Example: https://www.lakin.com/veniam-sed-fuga-aspernatur-natus-earum

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

media_type   string  optional    

Example: video

Must be one of:
  • image
  • video
  • audio
  • document
media_mime   string  optional    

Must not be greater than 128 characters. Example: mqeopfuudtdsufvyvddqa

media_filename   string  optional    

Must not be greater than 255 characters. Example: mniihfqcoynlazghdtqtq

Konuşmanın bot/engel durumu (READ-ONLY). Unified inbox conversation header'ı bunu kullanır: getMessages düz mesaj array'i döndürür (bot_active taşımaz) → header `botActive` default `true`'da kalıp "bot kapalı ama ikon yeşil + toggle ters çalışıyor" hatasına yol açıyordu (2026-05-30). resolveAccessibleSiteId ile toggleBot ile TAM AYNI (phone, site_id) satırını hedefler → görünen durum = toggle edilecek durum. toggleBot upsert eder; burada `first()` — salt görüntüleme satır YARATMAZ.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp/conversation-state" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"+905551234567\",
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp/conversation-state"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+905551234567",
    "site_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/conversation-state';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => '+905551234567',
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp/conversation-state

Headers

Content-Type        

Example: application/json

Body Parameters

phone   string     

Konuşmanın telefon numarası (E.164). Example: +905551234567

site_id   integer  optional    

Example: 17

Konuşma için AI bot otomatik yanıtını aç/kapat.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp/toggle-bot" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"+905551234567\",
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp/toggle-bot"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+905551234567",
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/toggle-bot';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => '+905551234567',
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp/toggle-bot

Headers

Content-Type        

Example: application/json

Body Parameters

phone   string     

Konuşmanın telefon numarası (E.164). Example: +905551234567

site_id   integer  optional    

Example: 17

Numarayı engelle / engeli kaldır.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp/toggle-block" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"+905551234567\",
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+905551234567",
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/toggle-block';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => '+905551234567',
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp/toggle-block

Headers

Content-Type        

Example: application/json

Body Parameters

phone   string     

Engellenecek/açılacak telefon numarası (E.164). Example: +905551234567

site_id   integer  optional    

Example: 17

Kullanıcının tüm WhatsApp profillerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp/profiles"
const url = new URL(
    "https://dowaba.com/api/whatsapp/profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp/profiles

Tek WhatsApp mesajını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/whatsapp/messages/42"
const url = new URL(
    "https://dowaba.com/api/whatsapp/messages/42"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/messages/42';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/whatsapp/messages/{id}

URL Parameters

id   integer     

Silinecek mesajın DB id'si. Example: 42

phone   string     

Path'in {phone} varyantı için telefon numarası. Example: +905551234567

Konuşmanın tüm mesajlarını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/whatsapp/conversations/+905551234567"
const url = new URL(
    "https://dowaba.com/api/whatsapp/conversations/+905551234567"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/conversations/+905551234567';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/whatsapp/conversations/{phone}

URL Parameters

phone   string     

Mesajları silinecek konuşmanın telefon numarası. Example: +905551234567

WhatsApp — Şablonlar

Şablon header için görsel yükle.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp/upload-header-image" \
    --header "Content-Type: multipart/form-data" \
    --form "image=@/tmp/phpwLUMgL" 
const url = new URL(
    "https://dowaba.com/api/whatsapp/upload-header-image"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('image', document.querySelector('input[name="image"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/upload-header-image';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'image',
                'contents' => fopen('/tmp/phpwLUMgL', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp/upload-header-image

Headers

Content-Type        

Example: multipart/form-data

Body Parameters

image   file     

Must be an image. Must not be greater than 5120 kilobytes. Example: /tmp/phpwLUMgL

Meta WhatsApp Business şablonlarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/whatsapp/templates"
const url = new URL(
    "https://dowaba.com/api/whatsapp/templates"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/templates';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/whatsapp/templates

Yeni Meta WhatsApp şablonu oluştur (header + body + butonlar).

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp/templates" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"guwi\",
    \"category\": \"UTILITY\",
    \"language\": \"tr\",
    \"components\": []
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp/templates"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "guwi",
    "category": "UTILITY",
    "language": "tr",
    "components": []
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/templates';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'guwi',
            'category' => 'UTILITY',
            'language' => 'tr',
            'components' => [],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/whatsapp/templates

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must match the regex /^[a-z0-9_]+$/. Example: guwi

category   string     

Example: UTILITY

Must be one of:
  • MARKETING
  • UTILITY
  • AUTHENTICATION
language   string     

Şablon dil kodu (Meta dil kodu). Example: tr

components   object     

Mevcut şablonu düzenle (Meta API).

Example request:
curl --request PUT \
    "https://dowaba.com/api/whatsapp/templates/17900000000000000" \
    --header "Content-Type: application/json" \
    --data "{
    \"components\": []
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp/templates/17900000000000000"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "components": []
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/templates/17900000000000000';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'components' => [],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/whatsapp/templates/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

Düzenlenecek şablonun Meta (Graph API) ID'si. Example: 17900000000000000

name   string     

Path'in {name} varyantı için şablon adı. Example: order_shipped

Body Parameters

components   object     

Şablona otomatik "Durdur" (vazgeçme) hızlı-yanıt butonu ekle. Kampanya akışındaki seçmeli yardımcı (2026-06-12): kullanıcı isterse şablonuna tek tıkla QUICK_REPLY "Durdur" butonu eklenir. Meta şablonu yeniden onaya alır (status PENDING, genelde dakikalar) — onaylanana dek şablon kampanya listesinde görünmez (frontend APPROVED filtreler). Alıcı butona basınca metin webhook'tan iner ve opt-out suppression'a yazılır (campaign_consents.optout_keywords). Şablonda zaten vazgeçme (buton/metin) varsa hiçbir şey değiştirilmez.

Example request:
curl --request POST \
    "https://dowaba.com/api/whatsapp/templates/add-optout-button" \
    --header "Content-Type: application/json" \
    --data "{
    \"profile_id\": 12,
    \"template_name\": \"kampanya_duyuru\",
    \"template_language\": \"tr\"
}"
const url = new URL(
    "https://dowaba.com/api/whatsapp/templates/add-optout-button"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "profile_id": 12,
    "template_name": "kampanya_duyuru",
    "template_language": "tr"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/templates/add-optout-button';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'profile_id' => 12,
            'template_name' => 'kampanya_duyuru',
            'template_language' => 'tr',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "status": "PENDING"
}
 

Example response (200):


{
    "success": true,
    "already": true
}
 

Request      

POST api/whatsapp/templates/add-optout-button

Headers

Content-Type        

Example: application/json

Body Parameters

profile_id   integer     

WhatsApp profili ID'si. Example: 12

template_name   string     

Şablon adı. Example: kampanya_duyuru

template_language   string     

Şablon dil kodu. Example: tr

Şablonu sil (Meta API).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/whatsapp/templates/order_shipped"
const url = new URL(
    "https://dowaba.com/api/whatsapp/templates/order_shipped"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/whatsapp/templates/order_shipped';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/whatsapp/templates/{name}

URL Parameters

name   string     

Silinecek şablonun adı. Example: order_shipped

id   string     

Path'in {id} varyantı için Meta şablon ID'si. Example: 17900000000000000

WhatsApp — Toplu / Kampanya

Kişi gruplarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/contacts/groups"
const url = new URL(
    "https://dowaba.com/api/contacts/groups"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/contacts/groups

Yeni kişi grubu oluştur.

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/groups" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"description\": \"Kampanya duyuruları için müşteri listesi\"
}"
const url = new URL(
    "https://dowaba.com/api/contacts/groups"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "description": "Kampanya duyuruları için müşteri listesi"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'description' => 'Kampanya duyuruları için müşteri listesi',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/contacts/groups

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

description   string  optional    

Grup açıklaması (en fazla 255 karakter). Example: Kampanya duyuruları için müşteri listesi

Grup adı/açıklamasını güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/contacts/groups/42" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"description\": \"Kampanya duyuruları için müşteri listesi\"
}"
const url = new URL(
    "https://dowaba.com/api/contacts/groups/42"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "description": "Kampanya duyuruları için müşteri listesi"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/42';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'description' => 'Kampanya duyuruları için müşteri listesi',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/contacts/groups/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Kişi grubu ID'si. Example: 42

Body Parameters

name   string     

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

description   string  optional    

Grup açıklaması (en fazla 255 karakter). Example: Kampanya duyuruları için müşteri listesi

Grubu sil (kişiler cascade silinir).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/contacts/groups/42"
const url = new URL(
    "https://dowaba.com/api/contacts/groups/42"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/42';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/contacts/groups/{id}

URL Parameters

id   integer     

Kişi grubu ID'si. Example: 42

Gruptaki kişileri listele (arama desteği).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/contacts/groups/7/contacts"
const url = new URL(
    "https://dowaba.com/api/contacts/groups/7/contacts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/7/contacts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/contacts/groups/{id}/contacts

URL Parameters

id   integer     

Kişi grubu ID'si. Example: 7

Gruba kişi ekle (telefon normalize edilir).

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/groups/42/contacts" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"vmqeopfuudtdsufvy\",
    \"name\": \"vddqamniihfqcoynlazgh\",
    \"email\": \"roob.mona@example.org\",
    \"phone_type\": \"home\"
}"
const url = new URL(
    "https://dowaba.com/api/contacts/groups/42/contacts"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "vmqeopfuudtdsufvy",
    "name": "vddqamniihfqcoynlazgh",
    "email": "roob.mona@example.org",
    "phone_type": "home"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/42/contacts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => 'vmqeopfuudtdsufvy',
            'name' => 'vddqamniihfqcoynlazgh',
            'email' => 'roob.mona@example.org',
            'phone_type' => 'home',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/contacts/groups/{id}/contacts

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Kişi grubu ID'si. Example: 42

Body Parameters

phone   string     

Must not be greater than 20 characters. Example: vmqeopfuudtdsufvy

name   string  optional    

Must not be greater than 100 characters. Example: vddqamniihfqcoynlazgh

email   string  optional    

Must be a valid email address. Must not be greater than 200 characters. Example: roob.mona@example.org

phone_type   string  optional    

Example: home

Must be one of:
  • mobile
  • home
  • work
  • other
  • unknown

Gruptaki TÜM kişileri sil (grup kalır, geri alınamaz). Büyük listelerde (10K+) id listesiyle `contacts/delete` pratik değil — bu endpoint grubu tek seferde boşaltır. Kampanya logları (`scheduled_job_logs.contact_id`) cascade silinir.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/contacts/groups/42/contacts"
const url = new URL(
    "https://dowaba.com/api/contacts/groups/42/contacts"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/42/contacts';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "deleted": 12696
}
 

Request      

DELETE api/contacts/groups/{id}/contacts

URL Parameters

id   integer     

Kişi grubu ID'si. Example: 42

Kişi bilgilerini güncelle (telefon, ad).

Example request:
curl --request PUT \
    "https://dowaba.com/api/contacts/12" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"vmqeopfuudtdsufvy\",
    \"name\": \"vddqamniihfqcoynlazgh\",
    \"email\": \"roob.mona@example.org\",
    \"phone_type\": \"mobile\"
}"
const url = new URL(
    "https://dowaba.com/api/contacts/12"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "vmqeopfuudtdsufvy",
    "name": "vddqamniihfqcoynlazgh",
    "email": "roob.mona@example.org",
    "phone_type": "mobile"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/12';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => 'vmqeopfuudtdsufvy',
            'name' => 'vddqamniihfqcoynlazgh',
            'email' => 'roob.mona@example.org',
            'phone_type' => 'mobile',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/contacts/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Kişi ID'si. Example: 12

Body Parameters

phone   string     

Must not be greater than 20 characters. Example: vmqeopfuudtdsufvy

name   string  optional    

Must not be greater than 100 characters. Example: vddqamniihfqcoynlazgh

email   string  optional    

Must be a valid email address. Must not be greater than 200 characters. Example: roob.mona@example.org

phone_type   string  optional    

Example: mobile

Must be one of:
  • mobile
  • home
  • work
  • other
  • unknown

Birden fazla kişiyi toplu sil (id listesi).

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/delete" \
    --header "Content-Type: application/json" \
    --data "{
    \"ids\": [
        17
    ]
}"
const url = new URL(
    "https://dowaba.com/api/contacts/delete"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ids": [
        17
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/delete';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ids' => [
                17,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/contacts/delete

Headers

Content-Type        

Example: application/json

Body Parameters

ids   integer[]  optional    

CSV/XLSX dosyasından kişi import et (Google/Outlook/Excel formatları). Telefon tipi ayrımı: - CSV header'da "Cep / Ev / İş" kolonları varsa her satırdan birden fazla Contact üretir (her telefon için phone_type=mobile/home/work). - Tek phone kolonu varsa TR prefix heuristic (5xx=mobile, 2/3/4xx=home). Response: added + updated + skipped + by_type breakdown.

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/groups/42/import" \
    --header "Content-Type: multipart/form-data" \
    --form "file=@/tmp/phpBoSuWE" 
const url = new URL(
    "https://dowaba.com/api/contacts/groups/42/import"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('file', document.querySelector('input[name="file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/42/import';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'file',
                'contents' => fopen('/tmp/phpBoSuWE', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/contacts/groups/{id}/import

Headers

Content-Type        

Example: multipart/form-data

URL Parameters

id   integer     

Kişi grubu ID'si. Example: 42

Body Parameters

file   file     

Must be a file. Must not be greater than 5120 kilobytes. Example: /tmp/phpBoSuWE

Dış URL'den (CSV/JSON) kişi listesi çekip YENİ bir gruba aktar — mail kampanyası için. SSRF-safe (ContactImportService internal IP'leri reddeder). Mail-öncelikli: email varsa email-bazlı dedup, yoksa telefon-bazlı. MX doğrulama burada YAPILMAZ (büyük listede senkron timeout) → email_status=unverified; kampanya gönderiminde/bounce takibinde değerlendirilir. AUTO-REFRESH: `auto_refresh=true` ise grubun kaynağı (URL + auth_style + API key ŞİFRELİ) saklanır → kampanya başında ContactImportService::refreshFromSource ile oto-yenilenir. auto_refresh false/yoksa hiçbir kaynak saklanmaz (tek-seferlik import, key DB'ye yazılmaz).

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/groups/import-url" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"url\": \"http:\\/\\/www.kunde.com\\/\",
    \"api_key\": \"iihfqcoynlazghdtqtqxb\",
    \"auth_style\": \"x-api-key\",
    \"query_key_name\": \"ajwbpilpmufinllwloauy\",
    \"auto_refresh\": false
}"
const url = new URL(
    "https://dowaba.com/api/contacts/groups/import-url"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "url": "http:\/\/www.kunde.com\/",
    "api_key": "iihfqcoynlazghdtqtqxb",
    "auth_style": "x-api-key",
    "query_key_name": "ajwbpilpmufinllwloauy",
    "auto_refresh": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/import-url';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'url' => 'http://www.kunde.com/',
            'api_key' => 'iihfqcoynlazghdtqtqxb',
            'auth_style' => 'x-api-key',
            'query_key_name' => 'ajwbpilpmufinllwloauy',
            'auto_refresh' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/contacts/groups/import-url

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

url   string     

Must be a valid URL. Must not be greater than 2048 characters. Example: http://www.kunde.com/

api_key   string  optional    

Must not be greater than 1000 characters. Example: iihfqcoynlazghdtqtqxb

auth_style   string  optional    

Example: x-api-key

Must be one of:
  • bearer
  • x-api-key
  • query
query_key_name   string  optional    

Must not be greater than 64 characters. Example: ajwbpilpmufinllwloauy

auto_refresh   boolean  optional    

Example: false

Bilgisayardan CSV/JSON dosyası yükleyerek YENİ kişi grubu oluştur (mail/WA kampanyası için). importFromUrl ile AYNI parser'ı (ContactImportService) kullanır → esnek kolon eşleme (email / ad / telefon) + email-VEYA-telefon kabulü. importContacts'tan farkı: email-only kişileri de alır (telefon ZORUNLU değil — mail kampanyası email-odaklı) ve JSON destekler. SSRF yok (yerel dosya); tek-seferlik (kaynak saklanmaz, auto_refresh=false).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/groups/import-file" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: multipart/form-data" \
    --form "name=Müşteri listesi"\
    --form "file=@/tmp/php9RQ2N8" 
const url = new URL(
    "https://dowaba.com/api/contacts/groups/import-file"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('name', 'Müşteri listesi');
body.append('file', document.querySelector('input[name="file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/import-file';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'name',
                'contents' => 'Müşteri listesi'
            ],
            [
                'name' => 'file',
                'contents' => fopen('/tmp/php9RQ2N8', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "group": {
        "id": 12,
        "name": "Müşteri listesi",
        "contacts_count": 340,
        "auto_refresh": false
    },
    "stats": {
        "fetched": 350,
        "added": 340,
        "updated": 0,
        "skipped": 10
    }
}
 

Example response (422):


{
    "success": false,
    "message": "Dosyada geçerli kişi (email/telefon) bulunamadı. Kolonlar email / ad / telefon olmalı."
}
 

Request      

POST api/contacts/groups/import-file

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: multipart/form-data

Body Parameters

name   string     

Oluşturulacak liste adı. Example: Müşteri listesi

file   file     

CSV/JSON/TXT dosyası (maks 15 MB). Kolonlar: email / ad / telefon. Example: /tmp/php9RQ2N8

Gruba toplu WhatsApp şablonu gönder (rate limit + media upload).

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/groups/42/send-template" \
    --header "Content-Type: application/json" \
    --data "{
    \"profile_id\": 17,
    \"template_name\": \"kampanya_duyuru\",
    \"template_language\": \"tr\",
    \"header_image_path\": \"whatsapp-headers\\/a1b2c3d4e5f6.jpg\",
    \"header_image_url\": \"https:\\/\\/example.com\\/banner.jpg\"
}"
const url = new URL(
    "https://dowaba.com/api/contacts/groups/42/send-template"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "profile_id": 17,
    "template_name": "kampanya_duyuru",
    "template_language": "tr",
    "header_image_path": "whatsapp-headers\/a1b2c3d4e5f6.jpg",
    "header_image_url": "https:\/\/example.com\/banner.jpg"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/groups/42/send-template';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'profile_id' => 17,
            'template_name' => 'kampanya_duyuru',
            'template_language' => 'tr',
            'header_image_path' => 'whatsapp-headers/a1b2c3d4e5f6.jpg',
            'header_image_url' => 'https://example.com/banner.jpg',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/contacts/groups/{id}/send-template

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Kişi grubu ID'si. Example: 42

Body Parameters

profile_id   integer     

Example: 17

template_name   string     

Meta'da onaylı WhatsApp şablonunun adı. Example: kampanya_duyuru

template_language   string     

Şablonun dil kodu. Example: tr

components   object  optional    
variable_mappings   object  optional    
header_image_path   string  optional    

Header görselinin storage yolu (görsel upload endpoint'inden dönen path). Example: whatsapp-headers/a1b2c3d4e5f6.jpg

header_image_url   string  optional    

Şablon header görseli URL'i (header_image_path verilmezse). Example: https://example.com/banner.jpg

Akıllı segment grubunu canlı kullanıcı sorgusundan tazele (bul-veya-oluştur + UPSERT + PRUNE). Bu gruplar platformdaki TÜM owner+bayi kullanıcı e-postalarını içerir → SADECE superadmin erişebilir. Grup superadmin'in kendi user_id'si altında tutulur.

Example request:
curl --request POST \
    "https://dowaba.com/api/contacts/segments/owner_reseller/sync"
const url = new URL(
    "https://dowaba.com/api/contacts/segments/owner_reseller/sync"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/contacts/segments/owner_reseller/sync';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/contacts/segments/{key}/sync

URL Parameters

key   string     

Segment anahtarı (ContactSegmentService::SEGMENTS). Example: owner_reseller

Zamanlanmış toplu gönderim job'larını listele (ilerleme yüzdesi ile).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/scheduled-jobs"
const url = new URL(
    "https://dowaba.com/api/scheduled-jobs"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/scheduled-jobs';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/scheduled-jobs

Yeni zamanlanmış toplu gönderim oluştur (once/hourly/daily).

Example request:
curl --request POST \
    "https://dowaba.com/api/scheduled-jobs" \
    --header "Content-Type: application/json" \
    --data "{
    \"contact_group_id\": 17,
    \"whatsapp_profile_id\": 17,
    \"template_name\": \"kampanya_duyuru\",
    \"template_language\": \"tr\",
    \"schedule_type\": \"daily\",
    \"schedule_hour\": 12,
    \"scheduled_at\": \"2026-06-12 14:00\",
    \"batch_size\": 16,
    \"delay_ms\": 5,
    \"header_image_path\": \"whatsapp-headers\\/kampanya-gorsel.jpg\",
    \"header_image_url\": \"https:\\/\\/example.com\\/banner.jpg\",
    \"consent_confirmed\": true
}"
const url = new URL(
    "https://dowaba.com/api/scheduled-jobs"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "contact_group_id": 17,
    "whatsapp_profile_id": 17,
    "template_name": "kampanya_duyuru",
    "template_language": "tr",
    "schedule_type": "daily",
    "schedule_hour": 12,
    "scheduled_at": "2026-06-12 14:00",
    "batch_size": 16,
    "delay_ms": 5,
    "header_image_path": "whatsapp-headers\/kampanya-gorsel.jpg",
    "header_image_url": "https:\/\/example.com\/banner.jpg",
    "consent_confirmed": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/scheduled-jobs';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'contact_group_id' => 17,
            'whatsapp_profile_id' => 17,
            'template_name' => 'kampanya_duyuru',
            'template_language' => 'tr',
            'schedule_type' => 'daily',
            'schedule_hour' => 12,
            'scheduled_at' => '2026-06-12 14:00',
            'batch_size' => 16,
            'delay_ms' => 5,
            'header_image_path' => 'whatsapp-headers/kampanya-gorsel.jpg',
            'header_image_url' => 'https://example.com/banner.jpg',
            'consent_confirmed' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/scheduled-jobs

Headers

Content-Type        

Example: application/json

Body Parameters

contact_group_id   integer     

The id of an existing record in the contact_groups table. Example: 17

whatsapp_profile_id   integer     

The id of an existing record in the whatsapp_profiles table. Example: 17

template_name   string     

Gönderilecek onaylı WhatsApp şablonunun adı. Example: kampanya_duyuru

template_language   string     

Şablonun dil kodu. Example: tr

schedule_type   string     

Example: daily

Must be one of:
  • once
  • hourly
  • daily
schedule_hour   integer  optional    

Must be at least 0. Must not be greater than 23. Example: 12

scheduled_at   string  optional    

Sadece schedule_type=once için: kampanyanın başlayacağı tarih-saat (Europe/Istanbul). Boş bırakılırsa hemen başlar. Geçmiş tarih de hemen başlar. Example: 2026-06-12 14:00

batch_size   integer  optional    

Must be at least 1. Must not be greater than 100000. Example: 16

delay_ms   integer  optional    

2026-05-21: mesajlar arası bekleme (ms). NULL → env default 50ms. 0 = throttle yok (Tier 4+), 50 = ~20/sn (Tier 1 güvenli), 250 = ~4/sn defansif. Must be at least 0. Must not be greater than 5000. Example: 5

variable_mappings   object  optional    

Manuel "Toplu Mesaj" akışı (ContactController::sendTemplate) ile birebir aynı parametreler — placeholder + IMAGE header destekli template'ler için. 2026-05-19 fix.

components   object  optional    
header_image_path   string  optional    

Şablonun IMAGE header görseli için public diskteki dosya yolu (store anında Meta Media API'ye yüklenir). Example: whatsapp-headers/kampanya-gorsel.jpg

header_image_url   string  optional    

Şablon header görseli URL'i. Example: https://example.com/banner.jpg

consent_confirmed   boolean     

YASAL ZORUNLU (ETK 6563 / KVKK / İYS): kullanıcı bu listenin pazarlama onayına + İYS kaydına sahip olduğunu beyan etmeli. İspat yükü göndericide (whatsapp-kampanya-uyum.md § 3). consent_confirmed_at = beyan damgası. Must be accepted. Example: true

Zamanlanmış job'un schedule/batch_size'ı güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/scheduled-jobs/42" \
    --header "Content-Type: application/json" \
    --data "{
    \"schedule_type\": \"once\",
    \"schedule_hour\": 19,
    \"scheduled_at\": \"2026-07-09T20:55:59\",
    \"batch_size\": 13,
    \"delay_ms\": 16,
    \"header_image_url\": \"http:\\/\\/luettgen.biz\\/\"
}"
const url = new URL(
    "https://dowaba.com/api/scheduled-jobs/42"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "schedule_type": "once",
    "schedule_hour": 19,
    "scheduled_at": "2026-07-09T20:55:59",
    "batch_size": 13,
    "delay_ms": 16,
    "header_image_url": "http:\/\/luettgen.biz\/"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/scheduled-jobs/42';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'schedule_type' => 'once',
            'schedule_hour' => 19,
            'scheduled_at' => '2026-07-09T20:55:59',
            'batch_size' => 13,
            'delay_ms' => 16,
            'header_image_url' => 'http://luettgen.biz/',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/scheduled-jobs/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Zamanlanmış job ID'si. Example: 42

Body Parameters

schedule_type   string  optional    

Example: once

Must be one of:
  • once
  • hourly
  • daily
schedule_hour   integer  optional    

Must be at least 0. Must not be greater than 23. Example: 19

scheduled_at   string  optional    

Must be a valid date. Example: 2026-07-09T20:55:59

batch_size   integer  optional    

Must be at least 1. Must not be greater than 100000. Example: 13

delay_ms   integer  optional    

Must be at least 0. Must not be greater than 5000. Example: 16

variable_mappings   object  optional    
components   object  optional    
header_image_url   string  optional    

Must be a valid URL. Example: http://luettgen.biz/

Zamanlanmış job'u aktif/pasif yap.

Example request:
curl --request POST \
    "https://dowaba.com/api/scheduled-jobs/7/toggle"
const url = new URL(
    "https://dowaba.com/api/scheduled-jobs/7/toggle"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/scheduled-jobs/7/toggle';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/scheduled-jobs/{id}/toggle

URL Parameters

id   integer     

Zamanlanmış job ID'si. Example: 7

Zamanlanmış job'u sil (log'lar cascade silinir).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/scheduled-jobs/12"
const url = new URL(
    "https://dowaba.com/api/scheduled-jobs/12"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/scheduled-jobs/12';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/scheduled-jobs/{id}

URL Parameters

id   integer     

Zamanlanmış job ID'si. Example: 12

Grup için WhatsApp gönderim istatistiği (modal'da "X hedef, Y atlanacak" özeti). - total: gruptaki toplam kişi - whatsapp_yes: önceki kampanyalarda Meta Cloud API "queued" döndü → kesin WA - whatsapp_no: Meta "Receiver not WA user" döndü (error.code 131026/1008) → atlanacak - unknown: hiç gönderim yapılmadı, ilk kampanyada öğrenilecek - target: gönderilecek = total - whatsapp_no

Example request:
curl --request GET \
    --get "https://dowaba.com/api/scheduled-jobs/whatsapp-stats/42"
const url = new URL(
    "https://dowaba.com/api/scheduled-jobs/whatsapp-stats/42"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/scheduled-jobs/whatsapp-stats/42';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/scheduled-jobs/whatsapp-stats/{contactGroupId}

URL Parameters

contactGroupId   integer     

Kişi grubu ID'si. Example: 42

Instagram Entegrasyonu

Kullanıcının Instagram profillerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram-profiles"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram-profiles

Yeni Instagram profili oluştur (manuel token girerek).

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram-profiles" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"instagram_account_id\": \"amniihfqcoynlazghdtqt\",
    \"instagram_page_token\": \"qxbajwbpilpmufinllwlo\"
}"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "instagram_account_id": "amniihfqcoynlazghdtqt",
    "instagram_page_token": "qxbajwbpilpmufinllwlo"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'instagram_account_id' => 'amniihfqcoynlazghdtqt',
            'instagram_page_token' => 'qxbajwbpilpmufinllwlo',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram-profiles

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

instagram_account_id   string  optional    

Must not be greater than 100 characters. Example: amniihfqcoynlazghdtqt

instagram_page_token   string  optional    

Must not be greater than 1000 characters. Example: qxbajwbpilpmufinllwlo

Tek Instagram profilini token ile getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram-profiles/4"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles/4"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles/4';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram-profiles/{id}

URL Parameters

id   integer     

The ID of the instagram profile. Example: 4

Instagram profil bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/instagram-profiles/4" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"instagram_account_id\": \"amniihfqcoynlazghdtqt\",
    \"instagram_page_token\": \"qxbajwbpilpmufinllwlo\",
    \"webhook_verify_token\": \"auydlsmsjuryvojcybzvr\"
}"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles/4"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "instagram_account_id": "amniihfqcoynlazghdtqt",
    "instagram_page_token": "qxbajwbpilpmufinllwlo",
    "webhook_verify_token": "auydlsmsjuryvojcybzvr"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles/4';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'instagram_account_id' => 'amniihfqcoynlazghdtqt',
            'instagram_page_token' => 'qxbajwbpilpmufinllwlo',
            'webhook_verify_token' => 'auydlsmsjuryvojcybzvr',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/instagram-profiles/{id}

PATCH api/instagram-profiles/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the instagram profile. Example: 4

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

instagram_account_id   string  optional    

Must not be greater than 100 characters. Example: amniihfqcoynlazghdtqt

instagram_page_token   string  optional    

Must not be greater than 1000 characters. Example: qxbajwbpilpmufinllwlo

webhook_verify_token   string  optional    

Must not be greater than 100 characters. Example: auydlsmsjuryvojcybzvr

Instagram profilini sil (bağlı site referansları temizlenir).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/instagram-profiles/4"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles/4"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles/4';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/instagram-profiles/{id}

URL Parameters

id   integer     

The ID of the instagram profile. Example: 4

Instagram profil token'ını test et (graph.instagram.com veya graph.facebook.com).

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram-profiles/4/test"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles/4/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles/4/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram-profiles/{instagram_profile_id}/test

URL Parameters

instagram_profile_id   integer     

The ID of the instagram profile. Example: 4

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram-profiles/4/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles/4/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles/4/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram-profiles/4/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles/4/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles/4/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Instagram profiline bağlı siteleri listele. Authz: liste cascade'i (instagramProfileIds — pivot ∪ user_id). Frontend store her listelenen profil için bunu çağırıp "bağlı / bağlanabilir" ayrımını yapar; eski strict user_id check'i bayi/müşteri için 404 dönüyordu. Dönen site listesi kullanıcının accessibleSiteIds'ine kelepçelenir — ortak profil başka tenant'ın sitelerini sızdırmaz.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram-profiles/4/linked-sites"
const url = new URL(
    "https://dowaba.com/api/instagram-profiles/4/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram-profiles/4/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram-profiles/{id}/linked-sites

URL Parameters

id   integer     

The ID of the instagram profile. Example: 4

Instagram OAuth config (Facebook Login for Business: app_id + config_id).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/oauth/config"
const url = new URL(
    "https://dowaba.com/api/instagram/oauth/config"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/oauth/config';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/oauth/config

Instagram Login (kendi OAuth) authorize URL'i (Facebook'tan bağımsız).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/oauth/ig-config"
const url = new URL(
    "https://dowaba.com/api/instagram/oauth/ig-config"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/oauth/ig-config';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/oauth/ig-config

Cache'deki OAuth verilerini alıp hesap bilgilerini döner. OAuth popup akışı tamamlandıktan sonra frontend bu endpoint ile bağlanan hesabın meta bilgilerini (kullanıcı adı, profil fotoğrafı, takipçi sayısı) okur. Erişim token'ı yanıtta YER ALMAZ — token sunucu tarafında saklanır ve yalnızca kaydetme adımında kullanılır.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/oauth/pending?key=a1b2c3d4e5f6"
const url = new URL(
    "https://dowaba.com/api/instagram/oauth/pending"
);

const params = {
    "key": "a1b2c3d4e5f6",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/oauth/pending';
$response = $client->get(
    $url,
    [
        'query' => [
            'key' => 'a1b2c3d4e5f6',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/oauth/pending

Query Parameters

key   string     

OAuth callback'in ürettiği geçici oturum anahtarı (5 dk geçerli). Example: a1b2c3d4e5f6

Instagram hesabını InstagramProfile olarak kaydet + webhook subscribe. OAuth akışının son adımı. Erişim token'ı istemciden değil, `cache_key` ile sunucu tarafındaki geçici OAuth oturumundan okunur.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/oauth/save" \
    --header "Content-Type: application/json" \
    --data "{
    \"instagram_account_id\": \"17841400000000000\",
    \"instagram_username\": \"acme_store\",
    \"app_scoped_id\": \"1234567890\",
    \"cache_key\": \"a1b2c3d4e5f6\"
}"
const url = new URL(
    "https://dowaba.com/api/instagram/oauth/save"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "instagram_account_id": "17841400000000000",
    "instagram_username": "acme_store",
    "app_scoped_id": "1234567890",
    "cache_key": "a1b2c3d4e5f6"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/oauth/save';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'instagram_account_id' => '17841400000000000',
            'instagram_username' => 'acme_store',
            'app_scoped_id' => '1234567890',
            'cache_key' => 'a1b2c3d4e5f6',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/oauth/save

Headers

Content-Type        

Example: application/json

Body Parameters

instagram_account_id   string     

Bağlanacak Instagram hesabının ID'si. Example: 17841400000000000

access_token   string  optional    

Geriye dönük uyumluluk için opsiyonel; normal akışta gönderilmez.

instagram_username   string  optional    

Hesabın kullanıcı adı. Example: acme_store

app_scoped_id   string  optional    

Bağlı Facebook sayfası ID'si. Example: 1234567890

cache_key   string  optional    

OAuth callback'in ürettiği geçici oturum anahtarı (token sunucu tarafında bu anahtarla saklanır). Example: a1b2c3d4e5f6

FB.login() short-lived token'ı long-lived'a çevir + IG Business hesaplarını bul.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/oauth/exchange" \
    --header "Content-Type: application/json" \
    --data "{
    \"access_token\": null
}"
const url = new URL(
    "https://dowaba.com/api/instagram/oauth/exchange"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "access_token": null
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/oauth/exchange';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'access_token' => null,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/oauth/exchange

Headers

Content-Type        

Example: application/json

Body Parameters

access_token   string     

FB.login() popup'ından dönen short-lived Facebook kullanıcı erişim token'ı.

Bağlı Instagram hesabının bilgilerini getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/account"
const url = new URL(
    "https://dowaba.com/api/instagram/account"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/account';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/account

Instagram DM listesi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/messages"
const url = new URL(
    "https://dowaba.com/api/instagram/messages"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/messages';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/messages

Instagram DM gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/messages/send" \
    --header "Content-Type: application/json" \
    --data "{
    \"recipient_id\": \"1234567890\",
    \"message\": \"mqeopfuudtdsufvyvddqa\",
    \"media_file_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/instagram/messages/send"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "recipient_id": "1234567890",
    "message": "mqeopfuudtdsufvyvddqa",
    "media_file_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/messages/send';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'recipient_id' => '1234567890',
            'message' => 'mqeopfuudtdsufvyvddqa',
            'media_file_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/messages/send

Headers

Content-Type        

Example: application/json

Body Parameters

recipient_id   string     

Alıcının Instagram IGSID'si (konuşmadaki karşı taraf). Example: 1234567890

message   string  optional    

Must not be greater than 1000 characters. Example: mqeopfuudtdsufvyvddqa

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

Bir sender ile olan tüm gelen mesajları okundu olarak işaretle. Kullanıcı admin panelde sohbeti açtığında çağrılır.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/conversations/1234567890/mark-read"
const url = new URL(
    "https://dowaba.com/api/instagram/conversations/1234567890/mark-read"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/conversations/1234567890/mark-read';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/conversations/{senderId}/mark-read

URL Parameters

senderId   string     

Instagram gönderen (sender) ID'si. Example: 1234567890

Kullanıcının erişebildiği TÜM IG profilleri için unread sayıları. Profile bar'ında "diğer hesaplarda 20 unread var" chip listesi için. Sadece unread > 0 olan profilleri döner; sıralama unread DESC.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/unread-by-profile"
const url = new URL(
    "https://dowaba.com/api/instagram/unread-by-profile"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/unread-by-profile';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/unread-by-profile

Hesabın Instagram gönderilerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/posts"
const url = new URL(
    "https://dowaba.com/api/instagram/posts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/posts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/posts

Instagram'a içerik yayınla (tekli görsel, carousel veya Reel).

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/publish" \
    --header "Content-Type: application/json" \
    --data "{
    \"image_urls\": [
        \"http:\\/\\/kunze.biz\\/iste-laborum-eius-est-dolor.html\"
    ],
    \"caption\": \"dtdsufvyvddqamniihfqc\",
    \"media_type\": \"CAROUSEL_ALBUM\"
}"
const url = new URL(
    "https://dowaba.com/api/instagram/publish"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "image_urls": [
        "http:\/\/kunze.biz\/iste-laborum-eius-est-dolor.html"
    ],
    "caption": "dtdsufvyvddqamniihfqc",
    "media_type": "CAROUSEL_ALBUM"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/publish';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'image_urls' => [
                'http://kunze.biz/iste-laborum-eius-est-dolor.html',
            ],
            'caption' => 'dtdsufvyvddqamniihfqc',
            'media_type' => 'CAROUSEL_ALBUM',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/publish

Headers

Content-Type        

Example: application/json

Body Parameters

image_urls   string[]     

Must be a valid URL.

caption   string  optional    

Must not be greater than 2200 characters. Example: dtdsufvyvddqamniihfqc

media_type   string  optional    

Example: CAROUSEL_ALBUM

Must be one of:
  • IMAGE
  • CAROUSEL_ALBUM
  • REELS

Instagram için görsel yükle (opsiyonel kırpma).

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/upload-media" \
    --header "Content-Type: multipart/form-data" \
    --form "aspect_ratio=1:1"\
    --form "images[]=@/tmp/phpD37EEj" 
const url = new URL(
    "https://dowaba.com/api/instagram/upload-media"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('aspect_ratio', '1:1');
body.append('images[]', document.querySelector('input[name="images[]"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/upload-media';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'aspect_ratio',
                'contents' => '1:1'
            ],
            [
                'name' => 'images[]',
                'contents' => fopen('/tmp/phpD37EEj', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/upload-media

Headers

Content-Type        

Example: multipart/form-data

Body Parameters

images   file[]     

Must be an image. Must not be greater than 10240 kilobytes.

aspect_ratio   string  optional    

max 10MB. Example: 1:1

Must be one of:
  • 1:1
  • 4:5
  • 1.91:1
  • original

Instagram gönderisini sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/instagram/posts/17900000000000000"
const url = new URL(
    "https://dowaba.com/api/instagram/posts/17900000000000000"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/posts/17900000000000000';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/instagram/posts/{mediaId}

URL Parameters

mediaId   string     

Instagram medya (gönderi) ID'si. Example: 17900000000000000

Gönderi insights (Meta API).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/posts/17900000000000000/insights"
const url = new URL(
    "https://dowaba.com/api/instagram/posts/17900000000000000/insights"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/posts/17900000000000000/insights';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/posts/{mediaId}/insights

URL Parameters

mediaId   string     

Instagram medya (gönderi) ID'si. Example: 17900000000000000

Yorum listesi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/comments"
const url = new URL(
    "https://dowaba.com/api/instagram/comments"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/comments';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/comments

Yoruma yanıt yaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/comments/17900000000000001/reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"reply\": \"vmqeopfuudtdsufvyvddq\",
    \"type\": \"public\"
}"
const url = new URL(
    "https://dowaba.com/api/instagram/comments/17900000000000001/reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "reply": "vmqeopfuudtdsufvyvddq",
    "type": "public"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/comments/17900000000000001/reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'reply' => 'vmqeopfuudtdsufvyvddq',
            'type' => 'public',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/comments/{id}/reply

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

Instagram yorum ID'si. Example: 17900000000000001

Body Parameters

reply   string     

Must not be greater than 1000 characters. Example: vmqeopfuudtdsufvyvddq

type   string  optional    

Example: public

Must be one of:
  • public
  • dm

Post bazlı oto-yanıt kurallarını getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/rules"
const url = new URL(
    "https://dowaba.com/api/instagram/rules"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/rules';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/rules

Post bazlı oto-yanıt kuralı kaydet/güncelle.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/rules" \
    --header "Content-Type: application/json" \
    --data "{
    \"id\": \"rule_42\",
    \"post_id\": \"17841400000000000\",
    \"post_caption\": \"Yeni koleksiyonumuz yayında!\",
    \"post_media_url\": \"https:\\/\\/example.com\\/post.jpg\",
    \"keywords\": [
        \"fiyat\",
        \"kargo\"
    ],
    \"comment_message\": \"mqeopfuudtdsufvyvddqa\",
    \"dm_message\": \"mniihfqcoynlazghdtqtq\",
    \"dm_closed_reply\": \"xbajwbpilpmufinllwloa\",
    \"use_ai\": true,
    \"custom_prompt\": \"Yorumcuya samimi bir teşekkür yaz, detayları DM\'den ilettiğimizi söyle.\",
    \"enabled\": true
}"
const url = new URL(
    "https://dowaba.com/api/instagram/rules"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id": "rule_42",
    "post_id": "17841400000000000",
    "post_caption": "Yeni koleksiyonumuz yayında!",
    "post_media_url": "https:\/\/example.com\/post.jpg",
    "keywords": [
        "fiyat",
        "kargo"
    ],
    "comment_message": "mqeopfuudtdsufvyvddqa",
    "dm_message": "mniihfqcoynlazghdtqtq",
    "dm_closed_reply": "xbajwbpilpmufinllwloa",
    "use_ai": true,
    "custom_prompt": "Yorumcuya samimi bir teşekkür yaz, detayları DM'den ilettiğimizi söyle.",
    "enabled": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/rules';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'id' => 'rule_42',
            'post_id' => '17841400000000000',
            'post_caption' => 'Yeni koleksiyonumuz yayında!',
            'post_media_url' => 'https://example.com/post.jpg',
            'keywords' => [
                'fiyat',
                'kargo',
            ],
            'comment_message' => 'mqeopfuudtdsufvyvddqa',
            'dm_message' => 'mniihfqcoynlazghdtqtq',
            'dm_closed_reply' => 'xbajwbpilpmufinllwloa',
            'use_ai' => true,
            'custom_prompt' => 'Yorumcuya samimi bir teşekkür yaz, detayları DM\'den ilettiğimizi söyle.',
            'enabled' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/rules

Headers

Content-Type        

Example: application/json

Body Parameters

id   string     

Kural ID'si (istemci üretir; mevcut ID gönderilirse kural güncellenir). Example: rule_42

post_id   string     

Kuralın bağlandığı Instagram gönderi (media) ID'si. Example: 17841400000000000

post_caption   string  optional    

Gönderi açıklaması (panelde önizleme için saklanır). Example: Yeni koleksiyonumuz yayında!

post_media_url   string  optional    

Gönderi görseli URL'i (panelde önizleme). Example: https://example.com/post.jpg

keywords   string[]  optional    

Kuralı tetikleyen anahtar kelimeler (boş = tüm yorumlar).

comment_message   string  optional    

Must not be greater than 2000 characters. Example: mqeopfuudtdsufvyvddqa

dm_message   string  optional    

Must not be greater than 4000 characters. Example: mniihfqcoynlazghdtqtq

dm_closed_reply   string  optional    

DM kapalı/gönderilemezse yoruma yazılacak fallback yanıt (kullanıcı belirler). Must not be greater than 2000 characters. Example: xbajwbpilpmufinllwloa

use_ai   boolean  optional    

Yorum yanıtı AI ile dinamik üretilsin mi (true → gelen yorum + custom_prompt yönergesiyle üretilir; sabit comment_message fallback olur). Example: true

custom_prompt   string  optional    

AI yorum yanıtı yönergesi (use_ai=true iken; boş bırakılırsa profilin genel Instagram prompt'u kullanılır). Example: Yorumcuya samimi bir teşekkür yaz, detayları DM'den ilettiğimizi söyle.

enabled   boolean     

Example: true

Post bazlı oto-yanıt kuralını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/instagram/rules/rule_1700000000000"
const url = new URL(
    "https://dowaba.com/api/instagram/rules/rule_1700000000000"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/rules/rule_1700000000000';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/instagram/rules/{ruleId}

URL Parameters

ruleId   string     

Oto-yanıt kuralı ID'si. Example: rule_1700000000000

Profil bazlı AI bot toggle.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/toggle-profile-bot"
const url = new URL(
    "https://dowaba.com/api/instagram/toggle-profile-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/toggle-profile-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/toggle-profile-bot

Konuşma bazlı bot toggle (sender_id ile).

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/toggle-conversation-bot" \
    --header "Content-Type: application/json" \
    --data "{
    \"sender_id\": \"1234567890\",
    \"sender_username\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/instagram/toggle-conversation-bot"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sender_id": "1234567890",
    "sender_username": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/toggle-conversation-bot';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sender_id' => '1234567890',
            'sender_username' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/toggle-conversation-bot

Headers

Content-Type        

Example: application/json

Body Parameters

sender_id   string     

Konuşmadaki karşı tarafın Instagram IGSID'si. Example: 1234567890

sender_username   string  optional    

Must not be greater than 255 characters. Example: mqeopfuudtdsufvyvddqa

Konuşmadaki kullanıcıyı engelle/engeli kaldır.

Example request:
curl --request POST \
    "https://dowaba.com/api/instagram/toggle-conversation-block" \
    --header "Content-Type: application/json" \
    --data "{
    \"sender_id\": \"1234567890\"
}"
const url = new URL(
    "https://dowaba.com/api/instagram/toggle-conversation-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sender_id": "1234567890"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/toggle-conversation-block';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sender_id' => '1234567890',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/instagram/toggle-conversation-block

Headers

Content-Type        

Example: application/json

Body Parameters

sender_id   string     

Engellenecek/engeli kaldırılacak kullanıcının Instagram IGSID'si. Example: 1234567890

Konuşma bazlı bot durumunu sorgula.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/instagram/conversation-bot-status"
const url = new URL(
    "https://dowaba.com/api/instagram/conversation-bot-status"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/instagram/conversation-bot-status';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/instagram/conversation-bot-status

E-posta Entegrasyonu

Mail hesaplarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail/accounts"
const url = new URL(
    "https://dowaba.com/api/mail/accounts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail/accounts

Yeni mail hesabı oluştur (IMAP + SMTP).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/accounts" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"imap_host\": \"mail.example.com\",
    \"imap_port\": 17,
    \"imap_encryption\": \"ssl\",
    \"imap_username\": \"user@example.com\",
    \"imap_password\": null,
    \"smtp_host\": \"mail.example.com\",
    \"smtp_port\": 17,
    \"smtp_encryption\": \"tls\",
    \"smtp_username\": \"user@example.com\",
    \"smtp_password\": null,
    \"from_name\": \"mqeopfuudtdsufvyvddqa\",
    \"from_email\": \"eloisa.harber@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/mail/accounts"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "imap_host": "mail.example.com",
    "imap_port": 17,
    "imap_encryption": "ssl",
    "imap_username": "user@example.com",
    "imap_password": null,
    "smtp_host": "mail.example.com",
    "smtp_port": 17,
    "smtp_encryption": "tls",
    "smtp_username": "user@example.com",
    "smtp_password": null,
    "from_name": "mqeopfuudtdsufvyvddqa",
    "from_email": "eloisa.harber@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'imap_host' => 'mail.example.com',
            'imap_port' => 17,
            'imap_encryption' => 'ssl',
            'imap_username' => 'user@example.com',
            'imap_password' => null,
            'smtp_host' => 'mail.example.com',
            'smtp_port' => 17,
            'smtp_encryption' => 'tls',
            'smtp_username' => 'user@example.com',
            'smtp_password' => null,
            'from_name' => 'mqeopfuudtdsufvyvddqa',
            'from_email' => 'eloisa.harber@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/accounts

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

site_id   string  optional    

The id of an existing record in the sites table.

imap_host   string     

IMAP sunucu adresi. Example: mail.example.com

imap_port   integer     

Example: 17

imap_encryption   string     

Example: ssl

Must be one of:
  • ssl
  • tls
  • none
imap_username   string     

IMAP kullanıcı adı (genelde e-posta adresi). Example: user@example.com

imap_password   string     

IMAP parolası.

smtp_host   string     

SMTP sunucu adresi. Example: mail.example.com

smtp_port   integer     

Example: 17

smtp_encryption   string     

Example: tls

Must be one of:
  • ssl
  • tls
  • none
smtp_username   string     

SMTP kullanıcı adı (genelde e-posta adresi). Example: user@example.com

smtp_password   string     

SMTP parolası.

from_name   string  optional    

Must not be greater than 255 characters. Example: mqeopfuudtdsufvyvddqa

from_email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: eloisa.harber@example.com

Mail hesabını güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/mail/accounts/42" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"imap_host\": \"mail.example.com\",
    \"imap_port\": 17,
    \"imap_encryption\": \"tls\",
    \"imap_username\": \"user@example.com\",
    \"smtp_host\": \"mail.example.com\",
    \"smtp_port\": 17,
    \"smtp_encryption\": \"none\",
    \"smtp_username\": \"user@example.com\",
    \"from_name\": \"mqeopfuudtdsufvyvddqa\",
    \"from_email\": \"eloisa.harber@example.com\",
    \"bot_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/42"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "imap_host": "mail.example.com",
    "imap_port": 17,
    "imap_encryption": "tls",
    "imap_username": "user@example.com",
    "smtp_host": "mail.example.com",
    "smtp_port": 17,
    "smtp_encryption": "none",
    "smtp_username": "user@example.com",
    "from_name": "mqeopfuudtdsufvyvddqa",
    "from_email": "eloisa.harber@example.com",
    "bot_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/42';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'imap_host' => 'mail.example.com',
            'imap_port' => 17,
            'imap_encryption' => 'tls',
            'imap_username' => 'user@example.com',
            'smtp_host' => 'mail.example.com',
            'smtp_port' => 17,
            'smtp_encryption' => 'none',
            'smtp_username' => 'user@example.com',
            'from_name' => 'mqeopfuudtdsufvyvddqa',
            'from_email' => 'eloisa.harber@example.com',
            'bot_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/mail/accounts/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Mail hesabı ID'si. Example: 42

Body Parameters

name   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

site_id   string  optional    

The id of an existing record in the sites table.

imap_host   string  optional    

IMAP sunucu adresi. Example: mail.example.com

imap_port   integer  optional    

Example: 17

imap_encryption   string  optional    

Example: tls

Must be one of:
  • ssl
  • tls
  • none
imap_username   string  optional    

IMAP kullanıcı adı (genelde e-posta adresi). Example: user@example.com

imap_password   string  optional    

Yeni IMAP parolası (boş gönderilirse mevcut parola korunur).

smtp_host   string  optional    

SMTP sunucu adresi. Example: mail.example.com

smtp_port   integer  optional    

Example: 17

smtp_encryption   string  optional    

Example: none

Must be one of:
  • ssl
  • tls
  • none
smtp_username   string  optional    

SMTP kullanıcı adı (genelde e-posta adresi). Example: user@example.com

smtp_password   string  optional    

Yeni SMTP parolası (boş gönderilirse mevcut parola korunur).

from_name   string  optional    

Must not be greater than 255 characters. Example: mqeopfuudtdsufvyvddqa

from_email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: eloisa.harber@example.com

bot_active   boolean  optional    

Example: false

fetch_settings   object  optional    

Mail hesabını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/mail/accounts/7"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/7"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/7';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/mail/accounts/{id}

URL Parameters

id   integer     

Mail hesabı ID'si. Example: 7

Mail hesabı bağlantı testi (IMAP + SMTP).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/accounts/42/test"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/42/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/42/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/accounts/{id}/test

URL Parameters

id   integer     

Mail hesabı ID'si. Example: 42

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/accounts/12/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/12/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/12/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/accounts/12/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/12/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/12/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Mail hesabına bağlı siteleri listele. Authz: liste cascade'i (mailAccountIds — pivot ∪ user_id ∪ legacy). Frontend her listelenen hesap için bunu çağırıp "bağlı / bağlanabilir" ayrımını yapar. Dönen site listesi kullanıcının accessibleSiteIds'ine kelepçelenir — ortak hesap başka tenant'ın site id+adını sızdırmaz (superadmin bypass).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail/accounts/42/linked-sites"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/42/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/42/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail/accounts/{id}/linked-sites

URL Parameters

id   integer     

Mail hesabı ID'si. Example: 42

Gelen kutusunu çek (IMAP fetch).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/accounts/12/fetch" \
    --header "Content-Type: application/json" \
    --data "{
    \"force\": false
}"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/12/fetch"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "force": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/12/fetch';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'force' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/accounts/{id}/fetch

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Mail hesabı ID'si. Example: 12

Body Parameters

force   boolean  optional    

Manuel "Yenile" butonu icin: true → son fetch_days gun yeniden taranir (last_fetched_at YOK SAY). Cron her dakika delta modunda calistigi icin bu butonu kullanan kullanici "son 5dk'da bir sey kacirildi mi?" diye dusunmesin diye. Example: false

Bir mail hesabının mesajlarını listele (inbox görünümü).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail/accounts/42/messages?email=musteri%40ornek.com"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/42/messages"
);

const params = {
    "email": "musteri@ornek.com",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/42/messages';
$response = $client->get(
    $url,
    [
        'query' => [
            'email' => 'musteri@ornek.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail/accounts/{id}/messages

URL Parameters

id   integer     

Mail hesabı ID'si. Example: 42

Query Parameters

email   string  optional    

Tek konuşmayı açarken karşı taraf e-posta adresi — 200-mesaj penceresi yerine o adrese scope'lu çeker (sessiz konuşma pencere dışına düşünce "mesaj yok" bug'ı). Example: musteri@ornek.com

Bir mail thread'ini getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail/messages/7/thread"
const url = new URL(
    "https://dowaba.com/api/mail/messages/7/thread"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/messages/7/thread';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail/messages/{id}/thread

URL Parameters

id   integer     

Mail mesajı ID'si (thread bu mesajdan türetilir). Example: 7

Mail yanıt gönder (SMTP).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"account_id\": 17,
    \"to\": \"carolyne.luettgen@example.org\",
    \"subject\": \"fuudtdsufvyvddqamniih\",
    \"body\": \"Merhaba, talebiniz alındı. En kısa sürede dönüş yapacağız.\",
    \"in_reply_to\": \"20260519142311.AB12CD@mail.example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/mail/reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "account_id": 17,
    "to": "carolyne.luettgen@example.org",
    "subject": "fuudtdsufvyvddqamniih",
    "body": "Merhaba, talebiniz alındı. En kısa sürede dönüş yapacağız.",
    "in_reply_to": "20260519142311.AB12CD@mail.example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'account_id' => 17,
            'to' => 'carolyne.luettgen@example.org',
            'subject' => 'fuudtdsufvyvddqamniih',
            'body' => 'Merhaba, talebiniz alındı. En kısa sürede dönüş yapacağız.',
            'in_reply_to' => '20260519142311.AB12CD@mail.example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/reply

Headers

Content-Type        

Example: application/json

Body Parameters

account_id   integer     

Example: 17

to   string     

Must be a valid email address. Example: carolyne.luettgen@example.org

subject   string     

Must not be greater than 500 characters. Example: fuudtdsufvyvddqamniih

body   string     

Yanıt metni (mail gövdesi). Example: Merhaba, talebiniz alındı. En kısa sürede dönüş yapacağız.

in_reply_to   string  optional    

Yanıtlanan mailin Message-ID başlığı (konu zinciri için). Example: 20260519142311.AB12CD@mail.example.com

Mail hesabı için AI bot otomatik yanıtını aç/kapat.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/toggle-bot"
const url = new URL(
    "https://dowaba.com/api/mail/toggle-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/toggle-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/toggle-bot

E-posta adresini bot icin engelle/engeli kaldir. Iki liste: - blocked_emails → manuel (kullanici "Engelle" tikladi) - auto_blocked_emails → otomatik (X-Spam-Score esigi asti) Toggle mantigi: - Adres iki listeden BIRINDE ise → her ikisinden de cikar (unblock). - Hicbirinde yoksa → manual blocked_emails listesine ekle. Boylece otomatik engellenen bir adres "Engeli Kaldir" yapildiginda auto listesinden de cikar, bir sonraki yuksek-skor mail'inde tekrar eklenebilir veya kullanici manuel ekleyebilir.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/toggle-block"
const url = new URL(
    "https://dowaba.com/api/mail/toggle-block"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/toggle-block';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/toggle-block

E-posta pattern'ini whitelist'e ekle / cikar (toggle). Whitelist substring pattern listesidir; MailService::fetchEmails bu pattern'lerden herhangi birini icermesi durumunda gondericiyi spam filtresinden ve X-Spam-Score esiginden bypass eder. Ornek pattern'ler: - "mail.byteintl.com" → TikTok no-reply tum mailler - "no-reply@mail.byteintl.com" → spesifik TikTok adresi - "byteintl" → ByteDance subdomain'leri Toggle mantigi: - Pattern listede varsa → cikar (unwhitelist). - Yoksa → ekle. NOTE: blocked_emails > whitelist_emails — manuel engel her zaman onceliklidir, whitelist'le bypass edilemez (kullanici net olarak engel istemis).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/toggle-whitelist" \
    --header "Content-Type: application/json" \
    --data "{
    \"account_id\": 17,
    \"pattern\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/mail/toggle-whitelist"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "account_id": 17,
    "pattern": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/toggle-whitelist';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'account_id' => 17,
            'pattern' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/toggle-whitelist

Headers

Content-Type        

Example: application/json

Body Parameters

account_id   integer     

Example: 17

pattern   string     

Substring pattern: tam email, domain, veya keyword (4-100 char). Must be at least 3 characters. Must not be greater than 100 characters. Example: mqeopfuudtdsufvyvddqa

Spam filtre ayarlarını güncelle (hesabın fetch_settings JSON'ına MERGE edilir — fetch_days/max_per_fetch gibi diğer ayarlar korunur). Varsayılanlar: `block_noreply` ve `block_spam_subjects` kapalı (no-reply / doğrulama mailleri gelir), `spam_score_filter` (sunucu taraflı spam skoru) açık.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/accounts/42/spam-settings" \
    --header "Content-Type: application/json" \
    --data "{
    \"spam_filter\": true,
    \"block_dmarc_reports\": true,
    \"block_noreply\": false,
    \"block_spam_subjects\": false,
    \"spam_score_filter\": true,
    \"spam_score_threshold\": \"8\"
}"
const url = new URL(
    "https://dowaba.com/api/mail/accounts/42/spam-settings"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "spam_filter": true,
    "block_dmarc_reports": true,
    "block_noreply": false,
    "block_spam_subjects": false,
    "spam_score_filter": true,
    "spam_score_threshold": "8"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/accounts/42/spam-settings';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'spam_filter' => true,
            'block_dmarc_reports' => true,
            'block_noreply' => false,
            'block_spam_subjects' => false,
            'spam_score_filter' => true,
            'spam_score_threshold' => '8',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/accounts/{id}/spam-settings

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Mail hesabı ID'si. Example: 42

Body Parameters

spam_filter   boolean  optional    

Ana spam filtresi anahtarı (kapalıysa hiç heuristik yok). Example: true

block_dmarc_reports   boolean  optional    

Example: true

block_noreply   boolean  optional    

no-reply/notification/dmarc gönderenleri ele. Example: false

block_spam_subjects   boolean  optional    

doğrulama/şifre/abonelik konulu mailleri ele. Example: false

spam_score_filter   boolean  optional    

Rspamd yüksek-skor maillerini sil + auto-blacklist. Example: true

spam_score_threshold   numeric  optional    

Rspamd skor eşiği (1-30, düşük=agresif). Example: 8

Konuşmayı okundu olarak işaretle.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/mark-read" \
    --header "Content-Type: application/json" \
    --data "{
    \"account_id\": 17,
    \"email\": \"qkunze@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/mail/mark-read"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "account_id": 17,
    "email": "qkunze@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/mark-read';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'account_id' => 17,
            'email' => 'qkunze@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/mark-read

Headers

Content-Type        

Example: application/json

Body Parameters

account_id   integer     

Example: 17

email   string     

Example: qkunze@example.com

Mail konuşmasını sil.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail/delete-conversation" \
    --header "Content-Type: application/json" \
    --data "{
    \"account_id\": 17,
    \"email\": \"qkunze@example.com\",
    \"delete_from_server\": true
}"
const url = new URL(
    "https://dowaba.com/api/mail/delete-conversation"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "account_id": 17,
    "email": "qkunze@example.com",
    "delete_from_server": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail/delete-conversation';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'account_id' => 17,
            'email' => 'qkunze@example.com',
            'delete_from_server' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail/delete-conversation

Headers

Content-Type        

Example: application/json

Body Parameters

account_id   integer     

Example: 17

email   string     

Example: qkunze@example.com

delete_from_server   boolean  optional    

Example: true

Mail — Template

Kullanıcının erişebildiği site'lerdeki tüm mail template'leri. Query: ?site_id=N (opsiyonel filter)

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail-templates"
const url = new URL(
    "https://dowaba.com/api/mail-templates"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail-templates

Manuel template ekle (subject + body_html).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-templates" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"name\": \"mqeopfuudtdsufvyvddqa\",
    \"subject_template\": \"mniihfqcoynlazghdtqtq\",
    \"body_html\": \"xbajwbpilpmufinllwloa\",
    \"body_text\": \"uydlsmsjuryvojcybzvrb\",
    \"ai_prompt\": \"yickznkygloigmkwxphlv\"
}"
const url = new URL(
    "https://dowaba.com/api/mail-templates"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "name": "mqeopfuudtdsufvyvddqa",
    "subject_template": "mniihfqcoynlazghdtqtq",
    "body_html": "xbajwbpilpmufinllwloa",
    "body_text": "uydlsmsjuryvojcybzvrb",
    "ai_prompt": "yickznkygloigmkwxphlv"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'name' => 'mqeopfuudtdsufvyvddqa',
            'subject_template' => 'mniihfqcoynlazghdtqtq',
            'body_html' => 'xbajwbpilpmufinllwloa',
            'body_text' => 'uydlsmsjuryvojcybzvrb',
            'ai_prompt' => 'yickznkygloigmkwxphlv',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-templates

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

name   string     

Must not be greater than 150 characters. Example: mqeopfuudtdsufvyvddqa

subject_template   string     

Must not be greater than 500 characters. Example: mniihfqcoynlazghdtqtq

body_html   string  optional    

Must not be greater than 200000 characters. Example: xbajwbpilpmufinllwloa

body_text   string  optional    

Must not be greater than 200000 characters. Example: uydlsmsjuryvojcybzvrb

ai_prompt   string  optional    

Must not be greater than 4000 characters. Example: yickznkygloigmkwxphlv

AI ile mail template üret. Site context + system_prompt + dil yönergesi Gemini'ye gönderilir, structured output (subject + body_html + body_text + suggested_variables) döner. Form'a doldurulur, kullanıcı edit + kaydet.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-templates/generate" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"prompt\": \"mqeopfuudtdsufvyvddqa\",
    \"tone\": \"kisa\"
}"
const url = new URL(
    "https://dowaba.com/api/mail-templates/generate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "prompt": "mqeopfuudtdsufvyvddqa",
    "tone": "kisa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates/generate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'prompt' => 'mqeopfuudtdsufvyvddqa',
            'tone' => 'kisa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-templates/generate

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

prompt   string     

2026-06-29: 4000 → 20000 (uzun talimat/şablon yapıştırma 422 vermesin; chat ile uyum). Must not be greater than 20000 characters. Example: mqeopfuudtdsufvyvddqa

tone   string  optional    

Example: kisa

Must be one of:
  • resmi
  • samimi
  • kisa
  • detayli

AI ile mail şablonu SOHBET asistanı (çok-turlu). Kullanıcı sohbet ettikçe AI şablonun KONUSU + HTML gövdesi + düz metin gövdesini birlikte günceller. Stateless: frontend her turda geçmiş mesajları + mevcut taslağı gönderir → {reply, subject, body_html, body_text, done}. generate() ile aynı standart (anahtar/kredi/sanitize) ama tek-seferlik üretim yerine iteratif düzenleme. SystemPromptBuilder'ın prompt-chat akışının mail-şablonu muadili.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-templates/chat" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"subject\": \"mqeopfuudtdsufvyvddqa\",
    \"body_html\": \"mniihfqcoynlazghdtqtq\",
    \"body_text\": \"xbajwbpilpmufinllwloa\",
    \"tone\": \"samimi\",
    \"locale\": \"sl_SI\",
    \"messages\": [
        {
            \"role\": \"user\",
            \"content\": \"mqeopfuudtdsufvyvddqa\"
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/mail-templates/chat"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "subject": "mqeopfuudtdsufvyvddqa",
    "body_html": "mniihfqcoynlazghdtqtq",
    "body_text": "xbajwbpilpmufinllwloa",
    "tone": "samimi",
    "locale": "sl_SI",
    "messages": [
        {
            "role": "user",
            "content": "mqeopfuudtdsufvyvddqa"
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates/chat';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'subject' => 'mqeopfuudtdsufvyvddqa',
            'body_html' => 'mniihfqcoynlazghdtqtq',
            'body_text' => 'xbajwbpilpmufinllwloa',
            'tone' => 'samimi',
            'locale' => 'sl_SI',
            'messages' => [
                [
                    'role' => 'user',
                    'content' => 'mqeopfuudtdsufvyvddqa',
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-templates/chat

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

messages   object[]  optional    

max:60 mesaj — token/maliyet overflow guard (sınırsız birikim → şişen Gemini prompt'u). Must not have more than 60 items.

role   string  optional    

Mesaj rolü (user veya assistant). Example: user

content   string  optional    

2026-06-29: max 8000 KISAYDI — kullanıcı mevcut HTML şablonu/uzun talimatı tek mesaj olarak yapıştırınca 422 ("Bir hata oluştu", log'a düşmez) veriyordu. 50000'e çıkarıldı (asistan turları kısa reply; uzun olan yalnız kullanıcının ara sıra yapıştırdığı içerik). Must not be greater than 50000 characters. Example: mqeopfuudtdsufvyvddqa

subject   string  optional    

Must not be greater than 500 characters. Example: mqeopfuudtdsufvyvddqa

body_html   string  optional    

Must not be greater than 200000 characters. Example: mniihfqcoynlazghdtqtq

body_text   string  optional    

Must not be greater than 200000 characters. Example: xbajwbpilpmufinllwloa

tone   string  optional    

Example: samimi

Must be one of:
  • resmi
  • samimi
  • kisa
  • detayli
locale   string  optional    

Must not be greater than 8 characters. Example: sl_SI

Template'i kendi mail adresine (veya verilen test adresine) test gönderimi. Body: { mail_account_id: int, to_email?: string }

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-templates/42/send-test" \
    --header "Content-Type: application/json" \
    --data "{
    \"mail_account_id\": 17,
    \"to_email\": \"carolyne.luettgen@example.org\"
}"
const url = new URL(
    "https://dowaba.com/api/mail-templates/42/send-test"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "mail_account_id": 17,
    "to_email": "carolyne.luettgen@example.org"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates/42/send-test';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'mail_account_id' => 17,
            'to_email' => 'carolyne.luettgen@example.org',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-templates/{id}/send-test

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Test gönderimi yapılacak mail şablonunun ID'si. Example: 42

Body Parameters

mail_account_id   integer     

Example: 17

to_email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: carolyne.luettgen@example.org

Mail — Kampanya

Kampanya listesi (status + site filter).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail-campaigns"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail-campaigns

Yeni kampanya (status=draft). Başlatmak için /start çağrılır.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-campaigns" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"mail_account_id\": 17,
    \"mail_template_id\": 17,
    \"contact_group_id\": 17,
    \"name\": \"mqeopfuudtdsufvyvddqa\",
    \"recipient_filter\": {
        \"phone_types\": [
            \"other\"
        ],
        \"require_email\": true
    },
    \"schedule_type\": \"once\",
    \"schedule_hour\": 0,
    \"batch_size\": 2,
    \"daily_send_limit_override\": 29,
    \"hourly_send_limit_override\": 30,
    \"consent_confirmed\": true
}"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "mail_account_id": 17,
    "mail_template_id": 17,
    "contact_group_id": 17,
    "name": "mqeopfuudtdsufvyvddqa",
    "recipient_filter": {
        "phone_types": [
            "other"
        ],
        "require_email": true
    },
    "schedule_type": "once",
    "schedule_hour": 0,
    "batch_size": 2,
    "daily_send_limit_override": 29,
    "hourly_send_limit_override": 30,
    "consent_confirmed": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'mail_account_id' => 17,
            'mail_template_id' => 17,
            'contact_group_id' => 17,
            'name' => 'mqeopfuudtdsufvyvddqa',
            'recipient_filter' => [
                'phone_types' => [
                    'other',
                ],
                'require_email' => true,
            ],
            'schedule_type' => 'once',
            'schedule_hour' => 0,
            'batch_size' => 2,
            'daily_send_limit_override' => 29,
            'hourly_send_limit_override' => 30,
            'consent_confirmed' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-campaigns

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

mail_account_id   integer     

Example: 17

mail_template_id   integer     

Example: 17

contact_group_id   integer     

Example: 17

name   string     

Must not be greater than 200 characters. Example: mqeopfuudtdsufvyvddqa

recipient_filter   object  optional    
phone_types   string[]  optional    
Must be one of:
  • mobile
  • home
  • work
  • other
  • unknown
require_email   boolean  optional    

Example: true

schedule_type   string     

Example: once

Must be one of:
  • once
  • hourly
  • daily
schedule_hour   integer  optional    

Must be between 0 and 23. Example: 0

batch_size   integer     

Must be between 1 and 500. Example: 2

daily_send_limit_override   integer  optional    

Must be at least 1. Example: 29

hourly_send_limit_override   integer  optional    

Must be at least 1. Example: 30

consent_confirmed   boolean     

ETK 6563 / İYS uyum: gönderen, bu listenin pazarlama onayı olduğunu beyan etmeli (WhatsApp kampanyasıyla parite — ScheduledJobController::store). Onaysız → 422. Must be accepted. Example: true

Başarısız (status=failed) gönderimleri yeniden dene (manuel retry). Per-recipient auto-retry KALDIRILDI (native Horizon retry'a geçildi — HORIZON.md § 11); manuel retry artık failed log'ları SİLER → o contact'lar log'suz kalır → MailCampaignProcessor pending query'si bir sonraki tick'te yeniden toplar + gönderir. Kampanya completed/paused/failed ise running'e alınır (cron işlesin). skipped (invalid_email / hard_bounce) DOKUNULMAZ. NOT: Senkron fail kotadan düşmediği için (refound.md § 1) bu bir "iade" değildir; iade SADECE bounce için ayrı cron'da yapılır (campaigns:refund-bounced-mail).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-campaigns/42/retry-failed"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/42/retry-failed"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/42/retry-failed';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-campaigns/{id}/retry-failed

URL Parameters

id   integer     

Kampanya ID'si. Example: 42

Telegram / Messenger

Kullanıcının Telegram profillerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/telegram/profiles"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/telegram/profiles

Yeni Telegram botu bağla (BotFather token + webhook ayarla).

Example request:
curl --request POST \
    "https://dowaba.com/api/telegram/profiles" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"bot_token\": null
}"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "bot_token": null
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'bot_token' => null,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/telegram/profiles

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

bot_token   string     

BotFather'dan alınan bot token'ı.

site_id   string  optional    

The id of an existing record in the sites table.

Telegram profil bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/telegram/profiles/5" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"is_active\": false,
    \"bot_active\": true
}"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles/5"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "is_active": false,
    "bot_active": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles/5';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'is_active' => false,
            'bot_active' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/telegram/profiles/{telegramProfile_id}

Headers

Content-Type        

Example: application/json

URL Parameters

telegramProfile_id   integer     

The ID of the telegramProfile. Example: 5

Body Parameters

name   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

site_id   string  optional    

The id of an existing record in the sites table.

is_active   boolean  optional    

Example: false

bot_active   boolean  optional    

Example: true

Telegram profilini sil (webhook da kaldırılır).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/telegram/profiles/5"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles/5"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles/5';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/telegram/profiles/{telegramProfile_id}

URL Parameters

telegramProfile_id   integer     

The ID of the telegramProfile. Example: 5

Telegram bot aktif/pasif yap.

Example request:
curl --request POST \
    "https://dowaba.com/api/telegram/profiles/5/toggle-bot"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles/5/toggle-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles/5/toggle-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/telegram/profiles/{telegramProfile_id}/toggle-bot

URL Parameters

telegramProfile_id   integer     

The ID of the telegramProfile. Example: 5

Telegram bot bağlantı testi (getMe).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/telegram/profiles/5/test"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles/5/test"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles/5/test';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/telegram/profiles/{telegramProfile_id}/test

URL Parameters

telegramProfile_id   integer     

The ID of the telegramProfile. Example: 5

Example request:
curl --request POST \
    "https://dowaba.com/api/telegram/profiles/5/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles/5/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles/5/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/telegram/profiles/5/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles/5/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles/5/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Telegram profiline bağlı siteleri listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/telegram/profiles/5/linked-sites"
const url = new URL(
    "https://dowaba.com/api/telegram/profiles/5/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/profiles/5/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/telegram/profiles/{telegramProfile_id}/linked-sites

URL Parameters

telegramProfile_id   integer     

The ID of the telegramProfile. Example: 5

Kullanıcının Messenger profillerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/messenger/profiles"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/messenger/profiles

Yeni Facebook Messenger sayfası bağla (manuel token ile).

Example request:
curl --request POST \
    "https://dowaba.com/api/messenger/profiles" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"page_id\": \"1234567890\",
    \"page_access_token\": null,
    \"app_id\": \"1234567890\"
}"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "page_id": "1234567890",
    "page_access_token": null,
    "app_id": "1234567890"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'page_id' => '1234567890',
            'page_access_token' => null,
            'app_id' => '1234567890',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/messenger/profiles

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

page_id   string     

Facebook sayfa (Page) ID'si. Example: 1234567890

page_access_token   string     

Facebook sayfa erişim token'ı.

app_id   string  optional    

Meta uygulama (App) ID'si. Example: 1234567890

app_secret   string  optional    

Meta uygulama gizli anahtarı.

site_id   string  optional    

The id of an existing record in the sites table.

Messenger profil bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/messenger/profiles/34" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"is_active\": false,
    \"bot_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles/34"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "is_active": false,
    "bot_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles/34';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'is_active' => false,
            'bot_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/messenger/profiles/{messengerProfile_id}

Headers

Content-Type        

Example: application/json

URL Parameters

messengerProfile_id   integer     

The ID of the messengerProfile. Example: 34

Body Parameters

name   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

site_id   string  optional    

The id of an existing record in the sites table.

is_active   boolean  optional    

Example: false

bot_active   boolean  optional    

Example: false

Messenger profilini sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/messenger/profiles/34"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles/34"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles/34';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/messenger/profiles/{messengerProfile_id}

URL Parameters

messengerProfile_id   integer     

The ID of the messengerProfile. Example: 34

Messenger bot aktif/pasif yap.

Example request:
curl --request POST \
    "https://dowaba.com/api/messenger/profiles/34/toggle-bot"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles/34/toggle-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles/34/toggle-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/messenger/profiles/{messengerProfile_id}/toggle-bot

URL Parameters

messengerProfile_id   integer     

The ID of the messengerProfile. Example: 34

Example request:
curl --request POST \
    "https://dowaba.com/api/messenger/profiles/34/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles/34/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles/34/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/messenger/profiles/34/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles/34/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles/34/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Messenger profiline bağlı siteleri listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/messenger/profiles/34/linked-sites"
const url = new URL(
    "https://dowaba.com/api/messenger/profiles/34/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/profiles/34/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/messenger/profiles/{messengerProfile_id}/linked-sites

URL Parameters

messengerProfile_id   integer     

The ID of the messengerProfile. Example: 34

Telegram konuşma listesini getir (panel görünümü).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/telegram/conversations"
const url = new URL(
    "https://dowaba.com/api/telegram/conversations"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/conversations';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/telegram/conversations

Bir Telegram chat'inin mesajlarını getir + okundu işaretle. Opt-in sayfalama: `limit`/`before_id` verilmezse TÜM mesajlar (eski davranış, bare array) döner. Verilirse en yeni `limit` mesaj + `{messages, has_more, oldest_id}` (yukarı kaydırma cursor'ı).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/telegram/messages/1234567890?limit=50&before_id=12345"
const url = new URL(
    "https://dowaba.com/api/telegram/messages/1234567890"
);

const params = {
    "limit": "50",
    "before_id": "12345",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/messages/1234567890';
$response = $client->get(
    $url,
    [
        'query' => [
            'limit' => '50',
            'before_id' => '12345',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Sayfalı (limit/before_id verildi)):


{
    "messages": [
        {
            "id": 12300,
            "direction": "in",
            "message": "Merhaba",
            "metadata": null,
            "delivery_status": null,
            "delivery_error": null,
            "media_url": null,
            "media_type": null,
            "media_mime": null,
            "created_at": "14:32",
            "date": "05.06.2026"
        }
    ],
    "has_more": true,
    "oldest_id": 12300
}
 

Request      

GET api/telegram/messages/{chatId}

URL Parameters

chatId   string     

Telegram sohbetinin (chat) kimliği. Example: 1234567890

Query Parameters

limit   integer  optional    

Sayfa boyutu (varsayılan 50, maks 200). Verilirse sayfalı yanıt döner. Example: 50

before_id   integer  optional    

Bu id'den ESKİ mesajları getir (scroll-up cursor). Yanıttaki oldest_id ile zincirlenir. Example: 12345

Telegram chat'e mesaj gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/telegram/send" \
    --header "Content-Type: application/json" \
    --data "{
    \"chat_id\": \"1234567890\",
    \"message\": \"mqeopfuudtdsufvyvddqa\",
    \"profile_id\": 17,
    \"media_file_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/telegram/send"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "chat_id": "1234567890",
    "message": "mqeopfuudtdsufvyvddqa",
    "profile_id": 17,
    "media_file_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/send';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'chat_id' => '1234567890',
            'message' => 'mqeopfuudtdsufvyvddqa',
            'profile_id' => 17,
            'media_file_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/telegram/send

Headers

Content-Type        

Example: application/json

Body Parameters

chat_id   string     

Telegram sohbet (chat) kimliği. Example: 1234567890

message   string  optional    

Must not be greater than 4096 characters. Example: mqeopfuudtdsufvyvddqa

profile_id   integer     

Example: 17

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

Konuşma bot/engel durumu (READ-ONLY) — unified inbox header için. getMessages düz mesaj array'i döndürdüğünden header `botActive` default'ta kalıyordu (2026-05-30 fix). toggleBot ile AYNI profil çözümü; firstOrCreate yerine first() (görüntüleme satır yaratmaz).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/telegram/conversation-state" \
    --header "Content-Type: application/json" \
    --data "{
    \"chat_id\": \"1234567890\",
    \"profile_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/telegram/conversation-state"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "chat_id": "1234567890",
    "profile_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/conversation-state';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'chat_id' => '1234567890',
            'profile_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/telegram/conversation-state

Headers

Content-Type        

Example: application/json

Body Parameters

chat_id   string     

Telegram sohbet (chat) kimliği. Example: 1234567890

profile_id   integer  optional    

Example: 17

Telegram konuşma için bot otomatik yanıtını aç/kapat.

Example request:
curl --request POST \
    "https://dowaba.com/api/telegram/toggle-bot" \
    --header "Content-Type: application/json" \
    --data "{
    \"chat_id\": \"1234567890\",
    \"profile_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/telegram/toggle-bot"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "chat_id": "1234567890",
    "profile_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/toggle-bot';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'chat_id' => '1234567890',
            'profile_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/telegram/toggle-bot

Headers

Content-Type        

Example: application/json

Body Parameters

chat_id   string     

Telegram sohbet (chat) kimliği. Example: 1234567890

profile_id   integer  optional    

Example: 17

Telegram konuşmadaki kullanıcıyı engelle / engeli kaldır.

Example request:
curl --request POST \
    "https://dowaba.com/api/telegram/toggle-block" \
    --header "Content-Type: application/json" \
    --data "{
    \"chat_id\": \"1234567890\",
    \"profile_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/telegram/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "chat_id": "1234567890",
    "profile_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/telegram/toggle-block';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'chat_id' => '1234567890',
            'profile_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/telegram/toggle-block

Headers

Content-Type        

Example: application/json

Body Parameters

chat_id   string     

Telegram sohbet (chat) kimliği. Example: 1234567890

profile_id   integer  optional    

Example: 17

Messenger konuşma listesini getir (panel).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/messenger/conversations"
const url = new URL(
    "https://dowaba.com/api/messenger/conversations"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/conversations';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/messenger/conversations

Bir Messenger sender_id'nin mesajlarını getir + okundu işaretle. Opt-in sayfalama: `limit`/`before_id` verilmezse TÜM mesajlar (eski davranış, bare array) döner. Verilirse en yeni `limit` mesaj + `{messages, has_more, oldest_id}` (yukarı kaydırma cursor'ı).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/messenger/messages/1234567890?limit=50&before_id=12345"
const url = new URL(
    "https://dowaba.com/api/messenger/messages/1234567890"
);

const params = {
    "limit": "50",
    "before_id": "12345",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/messages/1234567890';
$response = $client->get(
    $url,
    [
        'query' => [
            'limit' => '50',
            'before_id' => '12345',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Sayfalı (limit/before_id verildi)):


{
    "messages": [
        {
            "id": 12300,
            "direction": "in",
            "message": "Merhaba",
            "metadata": null,
            "delivery_status": null,
            "delivery_error": null,
            "media_url": null,
            "media_type": null,
            "media_mime": null,
            "created_at": "14:32",
            "date": "05.06.2026"
        }
    ],
    "has_more": true,
    "oldest_id": 12300
}
 

Request      

GET api/messenger/messages/{senderId}

URL Parameters

senderId   string     

Messenger görüşmesinin gönderen (PSID) kimliği. Example: 1234567890

Query Parameters

limit   integer  optional    

Sayfa boyutu (varsayılan 50, maks 200). Verilirse sayfalı yanıt döner. Example: 50

before_id   integer  optional    

Bu id'den ESKİ mesajları getir (scroll-up cursor). Yanıttaki oldest_id ile zincirlenir. Example: 12345

Messenger sender'a mesaj gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/messenger/send" \
    --header "Content-Type: application/json" \
    --data "{
    \"sender_id\": \"1234567890\",
    \"message\": \"mqeopfuudtdsufvyvddqa\",
    \"profile_id\": 17,
    \"media_file_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/messenger/send"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sender_id": "1234567890",
    "message": "mqeopfuudtdsufvyvddqa",
    "profile_id": 17,
    "media_file_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/send';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sender_id' => '1234567890',
            'message' => 'mqeopfuudtdsufvyvddqa',
            'profile_id' => 17,
            'media_file_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/messenger/send

Headers

Content-Type        

Example: application/json

Body Parameters

sender_id   string     

Alıcının Messenger PSID'i. Example: 1234567890

message   string  optional    

Must not be greater than 2000 characters. Example: mqeopfuudtdsufvyvddqa

profile_id   integer     

Example: 17

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

Konuşmanın bot/engel durumunu okur (salt-okunur) — inbox başlığı için. Kayıt yoksa oluşturmaz; varsayılan durum döner.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/messenger/conversation-state" \
    --header "Content-Type: application/json" \
    --data "{
    \"sender_id\": \"1234567890\",
    \"profile_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/messenger/conversation-state"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sender_id": "1234567890",
    "profile_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/conversation-state';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sender_id' => '1234567890',
            'profile_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/messenger/conversation-state

Headers

Content-Type        

Example: application/json

Body Parameters

sender_id   string     

Konuşmanın Messenger sender PSID'i. Example: 1234567890

profile_id   integer  optional    

Example: 17

Messenger konuşma için bot otomatik yanıtını aç/kapat.

Example request:
curl --request POST \
    "https://dowaba.com/api/messenger/toggle-bot" \
    --header "Content-Type: application/json" \
    --data "{
    \"sender_id\": \"1234567890\",
    \"profile_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/messenger/toggle-bot"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sender_id": "1234567890",
    "profile_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/toggle-bot';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sender_id' => '1234567890',
            'profile_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/messenger/toggle-bot

Headers

Content-Type        

Example: application/json

Body Parameters

sender_id   string     

Konuşmanın Messenger sender PSID'i. Example: 1234567890

profile_id   integer  optional    

Example: 17

Messenger sender'ı engelle / engeli kaldır.

Example request:
curl --request POST \
    "https://dowaba.com/api/messenger/toggle-block" \
    --header "Content-Type: application/json" \
    --data "{
    \"sender_id\": \"1234567890\",
    \"profile_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/messenger/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sender_id": "1234567890",
    "profile_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/messenger/toggle-block';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sender_id' => '1234567890',
            'profile_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/messenger/toggle-block

Headers

Content-Type        

Example: application/json

Body Parameters

sender_id   string     

Engellenecek/açılacak Messenger sender PSID'i. Example: 1234567890

profile_id   integer  optional    

Example: 17

SMS Entegrasyonu

Kullanıcının SMS hesaplarını listele (NetGSM, Twilio, vb.).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sms-accounts"
const url = new URL(
    "https://dowaba.com/api/sms-accounts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sms-accounts

Yeni SMS hesabı oluştur.

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-accounts" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"provider\": \"vatansms\",
    \"credentials\": [],
    \"is_active\": true
}"
const url = new URL(
    "https://dowaba.com/api/sms-accounts"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "provider": "vatansms",
    "credentials": [],
    "is_active": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'provider' => 'vatansms',
            'credentials' => [],
            'is_active' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sms-accounts

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

provider   string     

Example: vatansms

Must be one of:
  • netgsm
  • twilio
  • iletimerkezi
  • vatansms
  • mutlucell
credentials   object     
is_active   boolean  optional    

Example: true

SMS hesabı detayını getir (credentials görünür).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sms-accounts/1"
const url = new URL(
    "https://dowaba.com/api/sms-accounts/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sms-accounts/{id}

URL Parameters

id   integer     

The ID of the sms account. Example: 1

SMS hesabını güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/sms-accounts/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"provider\": \"iletimerkezi\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/sms-accounts/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "provider": "iletimerkezi",
    "is_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'provider' => 'iletimerkezi',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/sms-accounts/{id}

PATCH api/sms-accounts/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the sms account. Example: 1

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

provider   string  optional    

Example: iletimerkezi

Must be one of:
  • netgsm
  • twilio
  • iletimerkezi
  • vatansms
  • mutlucell
credentials   object  optional    
is_active   boolean  optional    

Example: false

SMS hesabını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/sms-accounts/1"
const url = new URL(
    "https://dowaba.com/api/sms-accounts/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/sms-accounts/{id}

URL Parameters

id   integer     

The ID of the sms account. Example: 1

SMS hesabını gerçek bir numaraya test SMS göndererek dene.

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-accounts/1/test" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"+905551234567\"
}"
const url = new URL(
    "https://dowaba.com/api/sms-accounts/1/test"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+905551234567"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts/1/test';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => '+905551234567',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sms-accounts/{smsAccount_id}/test

Headers

Content-Type        

Example: application/json

URL Parameters

smsAccount_id   integer     

The ID of the smsAccount. Example: 1

Body Parameters

phone   string     

Test SMS gönderilecek telefon numarası (E.164 önerilir). Example: +905551234567

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-accounts/1/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/sms-accounts/1/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts/1/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-accounts/1/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/sms-accounts/1/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts/1/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

SMS hesabına bağlı siteleri listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sms-accounts/1/linked-sites"
const url = new URL(
    "https://dowaba.com/api/sms-accounts/1/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-accounts/1/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sms-accounts/{smsAccount_id}/linked-sites

URL Parameters

smsAccount_id   integer     

The ID of the smsAccount. Example: 1

SMS — Kampanya

Kampanya listesi (status + site filter).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sms-campaigns?site_id=12&status=running"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns"
);

const params = {
    "site_id": "12",
    "status": "running",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns';
$response = $client->get(
    $url,
    [
        'query' => [
            'site_id' => '12',
            'status' => 'running',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "Haziran kampanyası",
            "status": "running",
            "total_recipients": 120
        }
    ]
}
 

Request      

GET api/sms-campaigns

Query Parameters

site_id   integer  optional    

Site filtresi. Example: 12

status   string  optional    

Durum filtresi (draft|running|paused|completed|cancelled). Example: running

Yeni SMS kampanyası (status=draft) + alıcı SNAPSHOT. Başlatmak için /start çağrılır. Mesajda `{ad}` kişi adıyla değişir.

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-campaigns" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 12,
    \"contact_group_id\": 5,
    \"sms_account_id\": 3,
    \"name\": \"Haziran kampanyası\",
    \"message_body\": \"Merhaba {ad}, kampanyamızdan haberdar olun!\",
    \"sender_header\": \"DOWABA\",
    \"scheduled_at\": \"2026-06-18T07:00:00Z\",
    \"batch_size\": 100,
    \"delay_ms\": 100,
    \"consent_confirmed\": true
}"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 12,
    "contact_group_id": 5,
    "sms_account_id": 3,
    "name": "Haziran kampanyası",
    "message_body": "Merhaba {ad}, kampanyamızdan haberdar olun!",
    "sender_header": "DOWABA",
    "scheduled_at": "2026-06-18T07:00:00Z",
    "batch_size": 100,
    "delay_ms": 100,
    "consent_confirmed": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 12,
            'contact_group_id' => 5,
            'sms_account_id' => 3,
            'name' => 'Haziran kampanyası',
            'message_body' => 'Merhaba {ad}, kampanyamızdan haberdar olun!',
            'sender_header' => 'DOWABA',
            'scheduled_at' => '2026-06-18T07:00:00Z',
            'batch_size' => 100,
            'delay_ms' => 100,
            'consent_confirmed' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "data": {
        "id": 1,
        "status": "draft",
        "total_recipients": 118
    },
    "skipped_no_phone": 2
}
 

Example response (422):


{
    "success": false,
    "error": "no_sms_account",
    "message": "Aktif bir NetGSM SMS hesabı seçmelisiniz."
}
 

Request      

POST api/sms-campaigns

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Erişebildiğin site. Example: 12

contact_group_id   integer     

Gönderilecek kişi grubu (CSV import sonrası grup). Example: 5

sms_account_id   integer     

Gönderim yapılacak NetGSM SMS hesabı. Example: 3

name   string     

Kampanya adı. Example: Haziran kampanyası

message_body   string     

SMS metni ({ad} desteklenir). Example: Merhaba {ad}, kampanyamızdan haberdar olun!

sender_header   string  optional    

Onaylı gönderici başlığı (boş=hesabın default'u). Example: DOWABA

scheduled_at   string  optional    

Başlangıç zamanı (UTC ISO; boş=start ile hemen). Example: 2026-06-18T07:00:00Z

batch_size   integer  optional    

Tick başına gönderim (default 100). Example: 100

delay_ms   integer  optional    

Mesajlar arası bekleme (ms). Example: 100

consent_confirmed   boolean     

"Bu listenin İYS/pazarlama onayı var" beyanı (true olmalı). Example: true

Kampanya detayı (güncel sayaçlarla).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sms-campaigns/1"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sms-campaigns/{id}

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanya güncelle — yalnız status=draft.

Example request:
curl --request PUT \
    "https://dowaba.com/api/sms-campaigns/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"message_body\": \"amniihfqcoynlazghdtqt\",
    \"sender_header\": \"qxbajwbpilpmufinl\",
    \"scheduled_at\": \"2026-07-09T20:55:59\",
    \"batch_size\": 11,
    \"delay_ms\": 22
}"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "message_body": "amniihfqcoynlazghdtqt",
    "sender_header": "qxbajwbpilpmufinl",
    "scheduled_at": "2026-07-09T20:55:59",
    "batch_size": 11,
    "delay_ms": 22
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'message_body' => 'amniihfqcoynlazghdtqt',
            'sender_header' => 'qxbajwbpilpmufinl',
            'scheduled_at' => '2026-07-09T20:55:59',
            'batch_size' => 11,
            'delay_ms' => 22,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/sms-campaigns/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Kampanya id. Example: 1

Body Parameters

name   string  optional    

Must not be greater than 200 characters. Example: vmqeopfuudtdsufvyvddq

message_body   string  optional    

Must not be greater than 800 characters. Example: amniihfqcoynlazghdtqt

sender_header   string  optional    

Must not be greater than 20 characters. Example: qxbajwbpilpmufinl

scheduled_at   string  optional    

Must be a valid date. Example: 2026-07-09T20:55:59

batch_size   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 11

delay_ms   integer  optional    

Must be at least 0. Must not be greater than 5000. Example: 22

Kampanya sil — koşan/duraklatılmış kampanya silinemez (önce iptal).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/sms-campaigns/1"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/sms-campaigns/{id}

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanyayı başlat (draft/paused→running). scheduled_at doluysa o andan itibaren gönderilir.

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-campaigns/1/start"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1/start"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1/start';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sms-campaigns/{id}/start

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanyayı duraklat (running→paused). Gönderilenler etkilenmez, yenisi başlamaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-campaigns/1/pause"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1/pause"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1/pause';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sms-campaigns/{id}/pause

URL Parameters

id   integer     

Kampanya id. Example: 1

Duraklatılmış kampanyayı devam ettir (paused→running).

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-campaigns/1/resume"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1/resume"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1/resume';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sms-campaigns/{id}/resume

URL Parameters

id   integer     

Kampanya id. Example: 1

Kampanyayı iptal et — bekleyen alıcılar 'skipped' (cancelled) olur, geri alınamaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-campaigns/1/cancel"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1/cancel"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1/cancel';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sms-campaigns/{id}/cancel

URL Parameters

id   integer     

Kampanya id. Example: 1

Gönderilemeyenleri tekrar dene — 'failed' alıcıları pending'e döndürür ve kampanyayı yeniden başlatır. 'skipped' (opt-out/İYS RET) ASLA yeniden gönderilmez. ⚠️ Tekrar gönderim yeni mesaj hakkı tüketir (charge gönderimde düşer).

Example request:
curl --request POST \
    "https://dowaba.com/api/sms-campaigns/1/retry-failed"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1/retry-failed"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1/retry-failed';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": {
        "id": 1,
        "status": "running"
    },
    "requeued": 17
}
 

Request      

POST api/sms-campaigns/{id}/retry-failed

URL Parameters

id   integer     

Kampanya id. Example: 1

Alıcı logları (sayfalı, status filtreli).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sms-campaigns/1/recipients?status=failed&page=1"
const url = new URL(
    "https://dowaba.com/api/sms-campaigns/1/recipients"
);

const params = {
    "status": "failed",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sms-campaigns/1/recipients';
$response = $client->get(
    $url,
    [
        'query' => [
            'status' => 'failed',
            'page' => '1',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sms-campaigns/{id}/recipients

URL Parameters

id   integer     

Kampanya id. Example: 1

Query Parameters

status   string  optional    

Durum filtresi (pending|sent|failed|skipped). Example: failed

page   integer  optional    

Sayfa. Example: 1

Trendyol Q&A

Trendyol satıcı profillerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/trendyol/profiles"
const url = new URL(
    "https://dowaba.com/api/trendyol/profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/trendyol/profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/trendyol/profiles

Yeni Trendyol profili oluştur (supplier_id + API key).

Example request:
curl --request POST \
    "https://dowaba.com/api/trendyol/profiles" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"seller_id\": \"123456\",
    \"api_key\": null,
    \"api_secret\": null
}"
const url = new URL(
    "https://dowaba.com/api/trendyol/profiles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "seller_id": "123456",
    "api_key": null,
    "api_secret": null
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/trendyol/profiles';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'seller_id' => '123456',
            'api_key' => null,
            'api_secret' => null,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/trendyol/profiles

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

seller_id   string     

Trendyol satıcı (supplier) ID'si. Example: 123456

api_key   string     

Trendyol API anahtarı.

api_secret   string     

Trendyol API gizli anahtarı.

site_id   string  optional    

The id of an existing record in the sites table.

Trendyol profil bilgilerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/trendyol/profiles/17" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"seller_id\": \"123456\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/trendyol/profiles/17"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "seller_id": "123456",
    "is_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/trendyol/profiles/17';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'seller_id' => '123456',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/trendyol/profiles/{trendyolProfile_id}

Headers

Content-Type        

Example: application/json

URL Parameters

trendyolProfile_id   integer     

The ID of the trendyolProfile. Example: 17

Body Parameters

name   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

seller_id   string  optional    

Trendyol satıcı (supplier) ID'si. Example: 123456

api_key   string  optional    

Trendyol API anahtarı.

api_secret   string  optional    

Trendyol API gizli anahtarı.

site_id   string  optional    

The id of an existing record in the sites table.

is_active   boolean  optional    

Example: false

Trendyol profilini sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/trendyol/profiles/17"
const url = new URL(
    "https://dowaba.com/api/trendyol/profiles/17"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/trendyol/profiles/17';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/trendyol/profiles/{trendyolProfile_id}

URL Parameters

trendyolProfile_id   integer     

The ID of the trendyolProfile. Example: 17

Trendyol'dan soruları çek ve senkronize et.

Example request:
curl --request POST \
    "https://dowaba.com/api/trendyol/profiles/17/sync"
const url = new URL(
    "https://dowaba.com/api/trendyol/profiles/17/sync"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/trendyol/profiles/17/sync';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/trendyol/profiles/{trendyolProfile_id}/sync

URL Parameters

trendyolProfile_id   integer     

The ID of the trendyolProfile. Example: 17

Tüm Trendyol sorularını listele (cevaplanmamış öncelikli).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/trendyol/questions"
const url = new URL(
    "https://dowaba.com/api/trendyol/questions"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/trendyol/questions';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/trendyol/questions

Trendyol sorusuna cevap gönder.

Example request:
curl --request POST \
    "https://dowaba.com/api/trendyol/questions/17/answer" \
    --header "Content-Type: application/json" \
    --data "{
    \"text\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/trendyol/questions/17/answer"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/trendyol/questions/17/answer';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'text' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/trendyol/questions/{trendyolQuestion_id}/answer

Headers

Content-Type        

Example: application/json

URL Parameters

trendyolQuestion_id   integer     

The ID of the trendyolQuestion. Example: 17

Body Parameters

text   string     

Must be at least 10 characters. Must not be greater than 2000 characters. Example: vmqeopfuudtdsufvyvddq

TikTok Entegrasyonu

Kullanıcının TikTok profillerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok-profiles"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok-profiles

Manuel olarak TikTok profili oluştur (test/sandbox amaçlı).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok-profiles" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"open_id\": \"amniihfqcoynlazghdtqt\",
    \"username\": \"qxbajwbpilpmufinllwlo\",
    \"access_token\": \"auydlsmsjuryvojcybzvr\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "open_id": "amniihfqcoynlazghdtqt",
    "username": "qxbajwbpilpmufinllwlo",
    "access_token": "auydlsmsjuryvojcybzvr"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'open_id' => 'amniihfqcoynlazghdtqt',
            'username' => 'qxbajwbpilpmufinllwlo',
            'access_token' => 'auydlsmsjuryvojcybzvr',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok-profiles

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

open_id   string  optional    

Must not be greater than 255 characters. Example: amniihfqcoynlazghdtqt

username   string  optional    

Must not be greater than 100 characters. Example: qxbajwbpilpmufinllwlo

access_token   string  optional    

Must not be greater than 2000 characters. Example: auydlsmsjuryvojcybzvr

Access token ile /v2/user/info çağırarak bağlantıyı test et.

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok-profiles/24/test"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles/24/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles/24/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok-profiles/{tiktok_profile_id}/test

URL Parameters

tiktok_profile_id   integer     

The ID of the tiktok profile. Example: 24

TikTok OAuth authorize URL ve client_key.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/oauth/config"
const url = new URL(
    "https://dowaba.com/api/tiktok/oauth/config"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/oauth/config';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/oauth/config

Cache'deki OAuth verisini frontend'e döner (kullanıcı onayı öncesi).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/oauth/pending"
const url = new URL(
    "https://dowaba.com/api/tiktok/oauth/pending"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/oauth/pending';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/oauth/pending

Cache'deki OAuth bilgilerini DB'ye yaz (yeni profil veya güncelleme).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/oauth/save" \
    --header "Content-Type: application/json" \
    --data "{
    \"cache_key\": \"a1b2c3d4e5f6\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/oauth/save"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "cache_key": "a1b2c3d4e5f6"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/oauth/save';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'cache_key' => 'a1b2c3d4e5f6',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/oauth/save

Headers

Content-Type        

Example: application/json

Body Parameters

cache_key   string     

OAuth callback'in ürettiği geçici oturum anahtarı (token sunucu tarafında bu anahtarla saklanır). Example: a1b2c3d4e5f6

Manuel sync — TikTok Display API'den video + yorum listesini DB'ye cek. Frontend'deki "Yenile" butonu bunu cagirir. Idempotent: ayni comment_id / video_id tekrar yazilmaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/profiles/3/sync"
const url = new URL(
    "https://dowaba.com/api/tiktok/profiles/3/sync"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/profiles/3/sync';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/profiles/{id}/sync

URL Parameters

id   integer     

Senkronize edilecek TikTok profilinin DB id'si. Example: 3

Yorum feed (akış) — her video altinda nested yorum tree. Mevcut /tiktok/conversations kullanici-bazli thread listesi donerken (video_id + commenter_open_id), bu endpoint **video-bazli** gosterim icin. Her video kartinin altinda parent_comment_id ile root-reply tree halinde yorumlar gelir. Frontend TiktokView "Akis" sekmesi bunu kullanir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/feed?profile_id=17&limit=17"
const url = new URL(
    "https://dowaba.com/api/tiktok/feed"
);

const params = {
    "profile_id": "17",
    "limit": "17",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/feed';
$response = $client->get(
    $url,
    [
        'query' => [
            'profile_id' => '17',
            'limit' => '17',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/feed

Query Parameters

profile_id   integer  optional    

Tek profile filter; bossa user'in tum profiles. Example: 17

limit   integer  optional    

Max video sayisi (default 30, max 100). Example: 17

TikTok DM & Yorumlar

Upload sonrası publish_id ile status sorgu (frontend polling için).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/videos/upload-status/v_pub_a1b2c3"
const url = new URL(
    "https://dowaba.com/api/tiktok/videos/upload-status/v_pub_a1b2c3"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/videos/upload-status/v_pub_a1b2c3';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/videos/upload-status/{publishId}

URL Parameters

publishId   string     

Upload yanıtında dönen TikTok publish_id. Example: v_pub_a1b2c3

Bir TikTok DM konuşmasının mesajlarını getir + okundu işaretle. Opt-in sayfalama: `limit`/`before_id` verilmezse TÜM mesajlar (eski davranış, bare array) döner. Verilirse en yeni `limit` mesaj + `{messages, has_more, oldest_id}` (yukarı kaydırma cursor'ı). Tercih edilen çağrı: `GET tiktok/dm/messages?open_id=..` — open_id standart base64 ("/" içerebilir), path'e gömülünce route ıskalanır (routes/api.php notu, tiktok.md § 14.7).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/dm/messages?open_id=u-7f3a2b91c4&limit=50&before_id=12345"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/messages"
);

const params = {
    "open_id": "u-7f3a2b91c4",
    "limit": "50",
    "before_id": "12345",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/messages';
$response = $client->get(
    $url,
    [
        'query' => [
            'open_id' => 'u-7f3a2b91c4',
            'limit' => '50',
            'before_id' => '12345',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Sayfalı (limit/before_id verildi)):


{
    "messages": [
        {
            "id": 12300,
            "message_id": "xxx",
            "direction": "in",
            "message": "Merhaba",
            "metadata": null,
            "created_at": "14:32",
            "date": "05.06.2026"
        }
    ],
    "has_more": true,
    "oldest_id": 12300
}
 

Request      

GET api/tiktok/dm/messages

URL Parameters

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

open_id   string  optional    

DM karşı tarafının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

limit   integer  optional    

Sayfa boyutu (varsayılan 50, maks 200). Verilirse sayfalı yanıt döner. Example: 50

before_id   integer  optional    

Bu id'den ESKİ mesajları getir (scroll-up cursor). Yanıttaki oldest_id ile zincirlenir. Example: 12345

Bir TikTok DM konuşmasının mesajlarını getir + okundu işaretle. Opt-in sayfalama: `limit`/`before_id` verilmezse TÜM mesajlar (eski davranış, bare array) döner. Verilirse en yeni `limit` mesaj + `{messages, has_more, oldest_id}` (yukarı kaydırma cursor'ı). Tercih edilen çağrı: `GET tiktok/dm/messages?open_id=..` — open_id standart base64 ("/" içerebilir), path'e gömülünce route ıskalanır (routes/api.php notu, tiktok.md § 14.7).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/dm/conversations/u-7f3a2b91c4/messages?open_id=u-7f3a2b91c4&limit=50&before_id=12345"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/conversations/u-7f3a2b91c4/messages"
);

const params = {
    "open_id": "u-7f3a2b91c4",
    "limit": "50",
    "before_id": "12345",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/conversations/u-7f3a2b91c4/messages';
$response = $client->get(
    $url,
    [
        'query' => [
            'open_id' => 'u-7f3a2b91c4',
            'limit' => '50',
            'before_id' => '12345',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Sayfalı (limit/before_id verildi)):


{
    "messages": [
        {
            "id": 12300,
            "message_id": "xxx",
            "direction": "in",
            "message": "Merhaba",
            "metadata": null,
            "created_at": "14:32",
            "date": "05.06.2026"
        }
    ],
    "has_more": true,
    "oldest_id": 12300
}
 

Request      

GET api/tiktok/dm/conversations/{openId}/messages

URL Parameters

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

open_id   string  optional    

DM karşı tarafının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

limit   integer  optional    

Sayfa boyutu (varsayılan 50, maks 200). Verilirse sayfalı yanıt döner. Example: 50

before_id   integer  optional    

Bu id'den ESKİ mesajları getir (scroll-up cursor). Yanıttaki oldest_id ile zincirlenir. Example: 12345

TikTok DM cevabı gönder (Business Messaging API — message.list.send scope). Kurallar: müşterinin son mesajından 48 saat içinde ve pencere başına max 10 business mesajı (TiktokDmService::canSendMore guard'ı). Metin max 6000 karakter. Görsel gönderimi pazar-kısıtlı (TR: text-only).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/dm/reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"open_id\": \"open-abc123def456\",
    \"message\": \"Merhaba, nasıl yardımcı olabilirim?\",
    \"profile_id\": 24
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "open_id": "open-abc123def456",
    "message": "Merhaba, nasıl yardımcı olabilirim?",
    "profile_id": 24
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'open_id' => 'open-abc123def456',
            'message' => 'Merhaba, nasıl yardımcı olabilirim?',
            'profile_id' => 24,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "message": {
        "id": 15,
        "message_id": "msg-xyz",
        "direction": "out",
        "message": "Merhaba",
        "metadata": {
            "operator": true
        },
        "created_at": "2026-07-02T12:00:00.000000Z",
        "date": "02.07.2026"
    }
}
 

Request      

POST api/tiktok/dm/reply

Headers

Content-Type        

Example: application/json

Body Parameters

open_id   string     

DM karşı tarafının TikTok open_id'si. Example: open-abc123def456

message   string     

Mesaj metni (max 6000 karakter). Example: Merhaba, nasıl yardımcı olabilirim?

profile_id   integer  optional    

TikTok profil id (verilmezse konuşmadan çözülür). Example: 24

TikTok Marketing

developers.tiktok.com Login Kit'ten TAMAMEN AYRI bir OAuth ekosistemi. Bu controller business-api.tiktok.com app credential'ı ile gelen kullanıcıları handle eder. Mevcut TiktokOAuthController (Login Kit) değiştirilmez — ek katman.

İki ayrı flow:

  1. Advertiser flow (Business Center / Ads Manager sahibi) Authorize URL: https://business-api.tiktok.com/portal/auth?app_id=...&redirect_uri=...&state=... Callback: /api/tiktok-marketing/callback?auth_code=...&state=... Token URL: https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/ Param adı: secret, app_id, auth_code (CamelCase! query'de auth_code, body'de farklı yapı olabilir — endpoint'e ilk POST yapınca netleşir).

  2. Account holder flow (creator/business TikTok user) Authorize URL: https://www.tiktok.com/v2/auth/authorize?client_key=...&scope=... Callback: /api/tiktok-marketing/account-callback?code=...&state=... Token URL: https://business-api.tiktok.com/open_api/v1.3/tt_user/oauth/token/ (veya open.tiktokapis.com Login Kit benzeri — TikTok docs'a göre netleşecek)

Token saklama: mevcut tiktok_profiles tablosu kullanılır. Marketing API'den gelen profile'lar ayırt edilebilmesi için future migration tiktok_profiles.source kolonu eklenebilir ('login_kit' | 'marketing_api'). Şimdilik aynı tablo.

Detay: /Users/aydinacar/Documents/dowaba/tiktok.md § 12.10.

Account holder OAuth başlat — frontend bu endpoint'i çağırır, authorize URL döner.

URL'i popup'ta açar; kullanıcı izin verir → TikTok callback'i tetikler.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok-marketing/oauth/start-account"
const url = new URL(
    "https://dowaba.com/api/tiktok-marketing/oauth/start-account"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-marketing/oauth/start-account';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok-marketing/oauth/start-account

Advertiser OAuth başlat — Business Center / Ads Manager flow.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok-marketing/oauth/start-advertiser"
const url = new URL(
    "https://dowaba.com/api/tiktok-marketing/oauth/start-advertiser"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-marketing/oauth/start-advertiser';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok-marketing/oauth/start-advertiser

Advertiser callback — Business Center bağlandığında.

TikTok: redirect_uri?auth_code=...&state=...

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok-marketing/callback"
const url = new URL(
    "https://dowaba.com/api/tiktok-marketing/callback"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-marketing/callback';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (400):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: unsafe-none
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

Invalid state
 

Request      

GET api/tiktok-marketing/callback

Account holder callback — TikTok creator/business account bağlandığında.

TikTok: redirect_uri?code=...&state=...

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok-marketing/account-callback"
const url = new URL(
    "https://dowaba.com/api/tiktok-marketing/account-callback"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-marketing/account-callback';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (400):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: unsafe-none
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

Invalid state
 

Request      

GET api/tiktok-marketing/account-callback

Google Yorumlari Entegrasyonu

Kullanicinin Google Business profillerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/google-business-profiles"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/google-business-profiles

Manuel profil olusturma (admin/debug amaclidir, normalde OAuth flow kullanilir).

Example request:
curl --request POST \
    "https://dowaba.com/api/google-business-profiles" \
    --header "Content-Type: application/json" \
    --data "{
    \"google_account_id\": \"vmqeopfuudtdsufvyvddq\",
    \"google_location_id\": \"amniihfqcoynlazghdtqt\",
    \"business_name\": \"qxbajwbpilpmufinllwlo\"
}"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "google_account_id": "vmqeopfuudtdsufvyvddq",
    "google_location_id": "amniihfqcoynlazghdtqt",
    "business_name": "qxbajwbpilpmufinllwlo"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'google_account_id' => 'vmqeopfuudtdsufvyvddq',
            'google_location_id' => 'amniihfqcoynlazghdtqt',
            'business_name' => 'qxbajwbpilpmufinllwlo',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-business-profiles

Headers

Content-Type        

Example: application/json

Body Parameters

google_account_id   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

google_location_id   string     

Must not be greater than 255 characters. Example: amniihfqcoynlazghdtqt

business_name   string  optional    

Must not be greater than 500 characters. Example: qxbajwbpilpmufinllwlo

Tek Google Business profilinin detayi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/google-business-profiles/17"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles/17"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles/17';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/google-business-profiles/{id}

URL Parameters

id   integer     

The ID of the google business profile. Example: 17

Profil ayarlarini guncelle (bot toggle / otomatik cevap / FAQ kullan).

Example request:
curl --request PUT \
    "https://dowaba.com/api/google-business-profiles/17" \
    --header "Content-Type: application/json" \
    --data "{
    \"is_active\": true,
    \"ai_bot_enabled\": true,
    \"ai_auto_reply_enabled\": false,
    \"reply_prompt_override\": \"Musteriye empati ile yaklas\",
    \"use_faq\": true,
    \"notification_phone\": \"+90 555 *** ** **\"
}"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles/17"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "is_active": true,
    "ai_bot_enabled": true,
    "ai_auto_reply_enabled": false,
    "reply_prompt_override": "Musteriye empati ile yaklas",
    "use_faq": true,
    "notification_phone": "+90 555 *** ** **"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles/17';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'is_active' => true,
            'ai_bot_enabled' => true,
            'ai_auto_reply_enabled' => false,
            'reply_prompt_override' => 'Musteriye empati ile yaklas',
            'use_faq' => true,
            'notification_phone' => '+90 555 *** ** **',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/google-business-profiles/{id}

PATCH api/google-business-profiles/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the google business profile. Example: 17

Body Parameters

is_active   boolean  optional    

Profili aktif/pasif yap. Example: true

ai_bot_enabled   boolean  optional    

AI bot acik/kapali. Example: true

ai_auto_reply_enabled   boolean  optional    

Yeni yoruma otomatik AI cevabi. Example: false

reply_prompt_override   string  optional    

Bu profile ozel AI prompt override. Example: Musteriye empati ile yaklas

use_faq   boolean  optional    

Cevap uretirken sitenin FAQ'unu da kullan. Example: true

notification_phone   string  optional    

Yeni yorum geldiginde bildirim gonderilecek telefon. Example: +90 555 *** ** **

Profili sil + Pub/Sub'tan unsubscribe + site linklerini temizle.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/google-business-profiles/17"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles/17"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles/17';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/google-business-profiles/{id}

URL Parameters

id   integer     

The ID of the google business profile. Example: 17

Profil baglantisini test et - accounts.list ile.

Example request:
curl --request POST \
    "https://dowaba.com/api/google-business-profiles/17/test"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles/17/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles/17/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-business-profiles/{googleBusinessProfile_id}/test

URL Parameters

googleBusinessProfile_id   integer     

The ID of the googleBusinessProfile. Example: 17

Example request:
curl --request POST \
    "https://dowaba.com/api/google-business-profiles/17/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles/17/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles/17/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/google-business-profiles/17/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles/17/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles/17/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Bir profile bagli site listesi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/google-business-profiles/17/linked-sites"
const url = new URL(
    "https://dowaba.com/api/google-business-profiles/17/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business-profiles/17/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/google-business-profiles/{id}/linked-sites

URL Parameters

id   integer     

The ID of the google business profile. Example: 17

Manuel sync - Google'dan yorum listesini cek + DB'ye yaz. "Yenile" butonu bunu cagirir.

Example request:
curl --request POST \
    "https://dowaba.com/api/google-business/profiles/3/sync"
const url = new URL(
    "https://dowaba.com/api/google-business/profiles/3/sync"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business/profiles/3/sync';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-business/profiles/{id}/sync

URL Parameters

id   integer     

Google Business profil ID'si. Example: 3

Site-level auto-reply toggle. Profil baz?nda ai_auto_reply_enabled set eder.

Example request:
curl --request POST \
    "https://dowaba.com/api/google-business/profiles/3/toggle-auto-reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"enabled\": true
}"
const url = new URL(
    "https://dowaba.com/api/google-business/profiles/3/toggle-auto-reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "enabled": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-business/profiles/3/toggle-auto-reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'enabled' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-business/profiles/{id}/toggle-auto-reply

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Google Business profil ID'si. Example: 3

Body Parameters

enabled   boolean     

Example: true

Yorum listesi getir. ?profile_id=X tek profile, yoksa tum profiller. ?filter=pending|answered|all (default: all) ?search=foo reviewer_name/review_comment icinde arar ?rating=1,2,3,4,5 puan filtresi

Example request:
curl --request GET \
    --get "https://dowaba.com/api/google-reviews"
const url = new URL(
    "https://dowaba.com/api/google-reviews"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-reviews';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/google-reviews

Tek bir yorumun detayi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/google-reviews/42"
const url = new URL(
    "https://dowaba.com/api/google-reviews/42"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-reviews/42';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/google-reviews/{id}

URL Parameters

id   integer     

Yorum ID'si. Example: 42

Yoruma manuel yanit gonder. reply_text doluyse overwrite eder.

Example request:
curl --request POST \
    "https://dowaba.com/api/google-reviews/42/reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"text\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/google-reviews/42/reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-reviews/42/reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'text' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-reviews/{id}/reply

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Yorum ID'si. Example: 42

Body Parameters

text   string     

Must not be greater than 4096 characters. Example: vmqeopfuudtdsufvyvddq

Yaniti sil (Google'dan ve DB'den).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/google-reviews/42/reply"
const url = new URL(
    "https://dowaba.com/api/google-reviews/42/reply"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-reviews/42/reply';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/google-reviews/{id}/reply

URL Parameters

id   integer     

Yorum ID'si. Example: 42

AI'dan tekrar oneri al (draft). Google'a gondermez sadece DB'de suggestion field'i yok - frontend response.suggestion'i gosterir.

Example request:
curl --request POST \
    "https://dowaba.com/api/google-reviews/7/regenerate-ai"
const url = new URL(
    "https://dowaba.com/api/google-reviews/7/regenerate-ai"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-reviews/7/regenerate-ai';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-reviews/{id}/regenerate-ai

URL Parameters

id   integer     

Yorum ID'si. Example: 7

Per-review bot toggle (bu yoruma artik AI cevap yazma).

Example request:
curl --request POST \
    "https://dowaba.com/api/google-reviews/12/toggle-bot"
const url = new URL(
    "https://dowaba.com/api/google-reviews/12/toggle-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-reviews/12/toggle-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-reviews/{id}/toggle-bot

URL Parameters

id   integer     

Yorum ID'si. Example: 12

Bu yorumu blokla (AI cevap vermez, panelde de gosterilmez).

Example request:
curl --request POST \
    "https://dowaba.com/api/google-reviews/42/toggle-block"
const url = new URL(
    "https://dowaba.com/api/google-reviews/42/toggle-block"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/google-reviews/42/toggle-block';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/google-reviews/{id}/toggle-block

URL Parameters

id   integer     

Yorum ID'si. Example: 42

X Entegrasyonu

X OAuth authorize URL ve client_id. PKCE code_verifier üretilip state ile eşleşik Cache'e konur — callback'te kullanılır.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/oauth/config"
const url = new URL(
    "https://dowaba.com/api/x/oauth/config"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/oauth/config';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/x/oauth/config

Cache'deki OAuth verisini frontend'e döner (kullanıcı onayı öncesi).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/oauth/pending"
const url = new URL(
    "https://dowaba.com/api/x/oauth/pending"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/oauth/pending';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/x/oauth/pending

Cache'deki OAuth bilgilerini DB'ye yaz (yeni profil veya güncelleme).

Example request:
curl --request POST \
    "https://dowaba.com/api/x/oauth/save" \
    --header "Content-Type: application/json" \
    --data "{
    \"cache_key\": \"a1b2c3d4e5f6\"
}"
const url = new URL(
    "https://dowaba.com/api/x/oauth/save"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "cache_key": "a1b2c3d4e5f6"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/oauth/save';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'cache_key' => 'a1b2c3d4e5f6',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/oauth/save

Headers

Content-Type        

Example: application/json

Body Parameters

cache_key   string     

OAuth callback'in ürettiği geçici oturum anahtarı (token sunucu tarafında bu anahtarla saklanır). Example: a1b2c3d4e5f6

Kullanıcının erişebildiği X profilleri (bayi cascade dahil).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/profiles"
const url = new URL(
    "https://dowaba.com/api/x/profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/x/profiles

Tek profil detay + bağlı siteler.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/profiles/3"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/x/profiles/{profileId}

URL Parameters

profileId   integer     

X profili ID'si. Example: 3

Profil davranış flag'lerini güncelle.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/x/profiles/3" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"is_active\": true,
    \"ai_bot_enabled\": true,
    \"mention_auto_reply_enabled\": true,
    \"dm_auto_reply_enabled\": true,
    \"x_prompt\": \"Sen bir destek asistanısın\",
    \"use_faq\": true,
    \"notification_phone\": \"mqeopfuudtdsufvyv\"
}"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "is_active": true,
    "ai_bot_enabled": true,
    "mention_auto_reply_enabled": true,
    "dm_auto_reply_enabled": true,
    "x_prompt": "Sen bir destek asistanısın",
    "use_faq": true,
    "notification_phone": "mqeopfuudtdsufvyv"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'is_active' => true,
            'ai_bot_enabled' => true,
            'mention_auto_reply_enabled' => true,
            'dm_auto_reply_enabled' => true,
            'x_prompt' => 'Sen bir destek asistanısın',
            'use_faq' => true,
            'notification_phone' => 'mqeopfuudtdsufvyv',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/x/profiles/{profileId}

Headers

Content-Type        

Example: application/json

URL Parameters

profileId   integer     

X profili ID'si. Example: 3

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

is_active   boolean  optional    

Example: true

ai_bot_enabled   boolean  optional    

Example: true

mention_auto_reply_enabled   boolean  optional    

Example: true

dm_auto_reply_enabled   boolean  optional    

Example: true

x_prompt   string  optional    

X profiline özel AI persona prompt'u (boşsa site varsayılanı kullanılır). Example: Sen bir destek asistanısın

use_faq   boolean  optional    

Example: true

notification_phone   string  optional    

Must not be greater than 20 characters. Example: mqeopfuudtdsufvyv

Bağlı X profili sil — token'ı X tarafında revoke et + DB'den soft delete.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/x/profiles/12"
const url = new URL(
    "https://dowaba.com/api/x/profiles/12"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/12';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/x/profiles/{profileId}

URL Parameters

profileId   integer     

X profili ID'si. Example: 12

Kanal-bazlı AI bot aç/kapat ("Botu Durdur" / "Botu Başlat"). GENİŞ liste kademesi (xProfileIds — WA/TikTok toggleBot paritesi): bayinin profilini sitesinde kullanan pivot-only müşteri de botu durdurabilmeli (kill-switch). `ai_bot_enabled` tüm X otomatik cevaplarının master AND kapısı (mention + DM + webhook job'ları) — update (DAR) buna gerek bırakmaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/x/profiles/3/toggle-bot"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3/toggle-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3/toggle-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/profiles/{profileId}/toggle-bot

URL Parameters

profileId   integer     

X profili ID'si. Example: 3

Bağlantıyı test et — `whoami` çağrısı yap.

Example request:
curl --request POST \
    "https://dowaba.com/api/x/profiles/7/test"
const url = new URL(
    "https://dowaba.com/api/x/profiles/7/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/7/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/profiles/{profileId}/test

URL Parameters

profileId   integer     

X profili ID'si. Example: 7

Manuel mention senkron tetikle (cron beklemeden).

Example request:
curl --request POST \
    "https://dowaba.com/api/x/profiles/3/sync"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3/sync"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3/sync';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/profiles/{profileId}/sync

URL Parameters

profileId   integer     

X profili ID'si. Example: 3

Manuel DM senkron tetikle (Faz 2). Scope dm.read gerekir.

Example request:
curl --request POST \
    "https://dowaba.com/api/x/profiles/7/sync-dms"
const url = new URL(
    "https://dowaba.com/api/x/profiles/7/sync-dms"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/7/sync-dms';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/profiles/{profileId}/sync-dms

URL Parameters

profileId   integer     

X profili ID'si. Example: 7

Example request:
curl --request POST \
    "https://dowaba.com/api/x/profiles/3/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/x/profiles/3/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Bu profile bağlı siteler.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/profiles/3/linked-sites"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/x/profiles/{profileId}/linked-sites

URL Parameters

profileId   integer     

X profili ID'si. Example: 3

Bir profilin tüm mention/DM conversation'larını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/conversations" \
    --header "Content-Type: application/json" \
    --data "{
    \"profile_id\": 17,
    \"type\": \"dm\"
}"
const url = new URL(
    "https://dowaba.com/api/x/conversations"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "profile_id": 17,
    "type": "dm"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/conversations';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'profile_id' => 17,
            'type' => 'dm',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/x/conversations

Headers

Content-Type        

Example: application/json

Body Parameters

profile_id   integer     

Example: 17

type   string  optional    

Example: dm

Must be one of:
  • mention
  • dm

Bir conversation'ın mesajlarını döndür. Opt-in sayfalama: `limit`/`before_id` verilmezse ESKİ yanıt ({conversation, messages, marked_read}, tüm mesajlar). Verilirse aynı yanıta `has_more` + `oldest_id` eklenir, `messages` en yeni `limit` ile sınırlanır (yukarı kaydırma cursor'ı).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/conversations/42/messages?limit=50&before_id=12345"
const url = new URL(
    "https://dowaba.com/api/x/conversations/42/messages"
);

const params = {
    "limit": "50",
    "before_id": "12345",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/conversations/42/messages';
$response = $client->get(
    $url,
    [
        'query' => [
            'limit' => '50',
            'before_id' => '12345',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Sayfalı (limit/before_id verildi)):


{
    "conversation": {
        "id": 7
    },
    "messages": [
        {
            "id": 12300,
            "direction": "in",
            "content": "[REDACTED]",
            "created_at": "2026-06-05T14:32:00.000000Z"
        }
    ],
    "marked_read": 0,
    "has_more": true,
    "oldest_id": 12300
}
 

Request      

GET api/x/conversations/{conversationId}/messages

URL Parameters

conversationId   string     

Konuşma kimliği — DB id'si veya conversation_key kabul edilir. Example: 42

Query Parameters

limit   integer  optional    

Sayfa boyutu (varsayılan 50, maks 200). Example: 50

before_id   integer  optional    

Bu XMessage id'sinden ESKİ mesajları getir (scroll-up cursor). oldest_id ile zincirlenir. Example: 12345

Conversation bazında AI bot toggle.

Example request:
curl --request POST \
    "https://dowaba.com/api/x/conversations/toggle-bot" \
    --header "Content-Type: application/json" \
    --data "{
    \"conversation_id\": \"42\",
    \"bot_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/x/conversations/toggle-bot"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "conversation_id": "42",
    "bot_active": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/conversations/toggle-bot';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'conversation_id' => '42',
            'bot_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/conversations/toggle-bot

Headers

Content-Type        

Example: application/json

Body Parameters

conversation_id   string     

Konuşma kimliği — DB id'si veya conversation_key kabul edilir. Example: 42

bot_active   boolean  optional    

Example: false

Conversation engelle / engeli kaldır (reengagement guard).

Example request:
curl --request POST \
    "https://dowaba.com/api/x/conversations/toggle-block" \
    --header "Content-Type: application/json" \
    --data "{
    \"conversation_id\": \"42\",
    \"is_blocked\": false
}"
const url = new URL(
    "https://dowaba.com/api/x/conversations/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "conversation_id": "42",
    "is_blocked": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/conversations/toggle-block';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'conversation_id' => '42',
            'is_blocked' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/conversations/toggle-block

Headers

Content-Type        

Example: application/json

Body Parameters

conversation_id   string     

Konuşma kimliği — DB id'si veya conversation_key kabul edilir. Example: 42

is_blocked   boolean  optional    

Example: false

Bir mention'a yanıt gönder (manuel veya AI önerisi).

Example request:
curl --request POST \
    "https://dowaba.com/api/x/reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"conversation_id\": \"42\",
    \"text\": \"mqeopfuudtdsufvyvddqa\",
    \"in_reply_to_x_message_id\": \"1234567890123456789\"
}"
const url = new URL(
    "https://dowaba.com/api/x/reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "conversation_id": "42",
    "text": "mqeopfuudtdsufvyvddqa",
    "in_reply_to_x_message_id": "1234567890123456789"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'conversation_id' => '42',
            'text' => 'mqeopfuudtdsufvyvddqa',
            'in_reply_to_x_message_id' => '1234567890123456789',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/reply

Headers

Content-Type        

Example: application/json

Body Parameters

conversation_id   string     

Konuşma kimliği — DB id'si veya conversation_key kabul edilir. Example: 42

text   string     

Must not be greater than 280 characters. Example: mqeopfuudtdsufvyvddqa

in_reply_to_x_message_id   string  optional    

Yanıtlanan tweet'in X mesaj ID'si (snowflake; boşsa bağımsız tweet atılır). Example: 1234567890123456789

X Entegrasyonu (Faz 3)

Account Activity API webhook'unu bu profile için aç (kullanıcı subscription'ı). Webhook URL: https://dowaba.com/api/x/webhook

Example request:
curl --request POST \
    "https://dowaba.com/api/x/profiles/3/webhook/subscribe"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3/webhook/subscribe"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3/webhook/subscribe';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/profiles/{profileId}/webhook/subscribe

URL Parameters

profileId   integer     

X profili ID'si. Example: 3

Account Activity API webhook subscription iptal.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/x/profiles/3/webhook"
const url = new URL(
    "https://dowaba.com/api/x/profiles/3/webhook"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/profiles/3/webhook';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/x/profiles/{profileId}/webhook

URL Parameters

profileId   integer     

X profili ID'si. Example: 3

X Paket Sistemi

Paket katalog — frontend modal "Paket Yükle" listesi. 3 sabit paket (starter/pro/enterprise) + fiyat/mesaj/badge bilgisi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/packages/catalog"
const url = new URL(
    "https://dowaba.com/api/x/packages/catalog"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/packages/catalog';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/x/packages/catalog

Site için tüm paket geçmişi (active + exhausted + expired + refunded). Admin/müşteri audit için.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/x/packages"
const url = new URL(
    "https://dowaba.com/api/sites/1/x/packages"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/x/packages';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site}/x/packages

URL Parameters

site   integer     

The site. Example: 1

Site için kota özeti — kalan/kullanılan + aktif paketler. Gauge component için kullanılır.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/x/packages/summary"
const url = new URL(
    "https://dowaba.com/api/sites/1/x/packages/summary"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/x/packages/summary';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site}/x/packages/summary

URL Parameters

site   integer     

The site. Example: 1

PayTR iframe token üret + PaytrPayment pending kaydı oluştur. Bayi-müşteri akışı (authz cascade): - `auth.id == site.user_id` → owner kendi alıyor, sold_by_reseller_id=null - `auth.id != site.user_id` → bayi/superadmin başkası için alıyor - Bayi: site.user.reseller_id == auth.id check, sold_by_reseller_id=auth.id - Superadmin (role bypass): sold_by_reseller_id=null (manuel admin)

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/x/packages/checkout" \
    --header "Content-Type: application/json" \
    --data "{
    \"package_key\": \"starter\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/x/packages/checkout"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "package_key": "starter"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/x/packages/checkout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'package_key' => 'starter',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site}/x/packages/checkout

Headers

Content-Type        

Example: application/json

URL Parameters

site   integer     

The site. Example: 1

Body Parameters

package_key   string     

Example: starter

Must be one of:
  • starter
  • pro
  • enterprise

X Webhook (Account Activity API)

Tek endpoint — method'a göre CRC veya event handle eder.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/webhook"
const url = new URL(
    "https://dowaba.com/api/x/webhook"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/webhook';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (405):

Show headers
cache-control: no-cache, private
content-type: application/json
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Method not allowed"
}
 

Request      

GET api/x/webhook

Tek endpoint — method'a göre CRC veya event handle eder.

Example request:
curl --request POST \
    "https://dowaba.com/api/x/webhook"
const url = new URL(
    "https://dowaba.com/api/x/webhook"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/webhook';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/x/webhook

Shopify Entegrasyonu

Shopify Billing API entegrasyonu — App Store §1.2.1 zorunlu uyumu.

Akış:

  1. Frontend (embedded admin) /create-charge POST → appSubscriptionCreate mutation → confirmationUrl döner → frontend window.top.location'a yönlendirir
  2. Merchant Shopify'da "Activate" → Shopify returnUrl'e redirect (charge_id query param)
  3. /return GET → appSubscriptionQuery ile state oku → ACTIVE ise SubscriptionService::activateSubscription → connection.subscription_id güncelle → admin dashboard'a redirect

Webhook tarafı: ShopifyWebhookController::appSubscriptionsUpdate (status change ACTIVE/CANCELLED/EXPIRED/FROZEN/DECLINED → DB güncelle).

Authorize URL üret + CSRF state cache'le.

Example request:
curl --request POST \
    "https://dowaba.com/api/shopify/oauth/start" \
    --header "Content-Type: application/json" \
    --data "{
    \"shop\": \"dowabademo\",
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/shopify/oauth/start"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "shop": "dowabademo",
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopify/oauth/start';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'shop' => 'dowabademo',
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/shopify/oauth/start

Headers

Content-Type        

Example: application/json

Body Parameters

shop   string     

Shop domain (örn. "mystore" veya "mystore.myshopify.com"). Example: dowabademo

site_id   integer     

Dowaba site ID'si. Example: 17

Aktif user'ın bağlı Shopify mağazalarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/shopify/connections"
const url = new URL(
    "https://dowaba.com/api/shopify/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopify/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/shopify/connections

Connection'ı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/shopify/connections/17"
const url = new URL(
    "https://dowaba.com/api/shopify/connections/17"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopify/connections/17';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/shopify/connections/{connection}

URL Parameters

connection   integer     

ShopifyConnection ID. Example: 17

POST /api/shopify/billing/create-charge — DEPRECATED

Bu endpoint Shopify Manual Pricing (Billing API) modu için yazılmıştı. 2026-05-28: Shopify App Pricing'e geçtik — appSubscriptionCreate mutation artık reject ediliyor ("Managed Pricing Apps cannot use the Billing API").

Yeni akış: Frontend doğrudan connection.pricing_page_url'e yönlendirir, merchant Shopify-hosted page'de plan seçer + onaylar, callback bizim /api/shopify/billing/return'e gelir (eski) veya webhook ile subscription aktivasyonu yapılır.

Bu endpoint legacy frontend'leri (cache'li tarayıcılar) için 410 Gone

Example request:
curl --request POST \
    "https://dowaba.com/api/shopify/billing/create-charge" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/shopify/billing/create-charge"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopify/billing/create-charge';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/shopify/billing/create-charge

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

GET /api/shopify/billing/return?site_id=X&charge_id=Y

Shopify confirmation sonrası kullanıcı buraya yönlenir. Charge state ACTIVE → SubscriptionService::activateSubscription → admin'e redirect.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/shopify/billing/return"
const url = new URL(
    "https://dowaba.com/api/shopify/billing/return"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopify/billing/return';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (302):

Show headers
cache-control: no-cache, private
location: https://dowaba.com/admin/?shopify_billing_error=missing_site_id
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="refresh" content="0;url='https://dowaba.com/admin/?shopify_billing_error=missing_site_id'" />

        <title>Redirecting to https://dowaba.com/admin/?shopify_billing_error=missing_site_id</title>
    </head>
    <body>
        Redirecting to <a href="https://dowaba.com/admin/?shopify_billing_error=missing_site_id">https://dowaba.com/admin/?shopify_billing_error=missing_site_id</a>.
    </body>
</html>
 

Request      

GET api/shopify/billing/return

İkas Entegrasyonu

Authorize URL üret + CSRF state cache'le.

Example request:
curl --request POST \
    "https://dowaba.com/api/ikas/oauth/start" \
    --header "Content-Type: application/json" \
    --data "{
    \"store\": \"dowabademo\",
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ikas/oauth/start"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "store": "dowabademo",
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ikas/oauth/start';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'store' => 'dowabademo',
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ikas/oauth/start

Headers

Content-Type        

Example: application/json

Body Parameters

store   string     

Mağaza adı (subdomain, ".myikas.com" hariç). Example: dowabademo

site_id   integer     

Dowaba site ID'si — başarılı OAuth sonrası bu site'a bağlanır. Example: 17

Private App "Hızlı Bağlan" — Partner onayı BEKLEMEDEN. Kullanıcı İkas panelinden (Uygulamalar → Özel Uygulamalar) aldığı client_id + client_secret ile bağlanır. Dowaba client_credentials grant ile token üretir; credentials connection'da encrypted saklanır (token süresi dolunca otomatik yeniden üretilir — refresh_token gerekmez).

Example request:
curl --request POST \
    "https://dowaba.com/api/ikas/connections/quick-connect" \
    --header "Content-Type: application/json" \
    --data "{
    \"store\": \"dowabademo\",
    \"site_id\": 17,
    \"client_id\": \"consequatur\",
    \"client_secret\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/ikas/connections/quick-connect"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "store": "dowabademo",
    "site_id": 17,
    "client_id": "consequatur",
    "client_secret": "consequatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ikas/connections/quick-connect';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'store' => 'dowabademo',
            'site_id' => 17,
            'client_id' => 'consequatur',
            'client_secret' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ikas/connections/quick-connect

Headers

Content-Type        

Example: application/json

Body Parameters

store   string     

Mağaza adı (subdomain, ".myikas.com" hariç). Example: dowabademo

site_id   integer     

Dowaba site ID'si. Example: 17

client_id   string     

İkas Özel Uygulama Client ID. Example: consequatur

client_secret   string     

İkas Özel Uygulama Client Secret. Example: consequatur

Aktif user'ın (ve bayilik kapsamındaki) İkas connection'larını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ikas/connections"
const url = new URL(
    "https://dowaba.com/api/ikas/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ikas/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ikas/connections

Connection'ı sil — site'ın İkas bağlantısı kesilir.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/ikas/connections/1"
const url = new URL(
    "https://dowaba.com/api/ikas/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ikas/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/ikas/connections/{connection}

URL Parameters

connection   integer     

IkasConnection ID. Example: 1

Shopier Entegrasyonu

PAT ile bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/shopier/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"access_token\": \"consequatur\",
    \"site_id\": 17,
    \"store_name\": \"Butik Moda\"
}"
const url = new URL(
    "https://dowaba.com/api/shopier/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "access_token": "consequatur",
    "site_id": 17,
    "store_name": "Butik Moda"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopier/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'access_token' => 'consequatur',
            'site_id' => 17,
            'store_name' => 'Butik Moda',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/shopier/connections

Headers

Content-Type        

Example: application/json

Body Parameters

access_token   string     

Shopier Personal Access Token. Example: consequatur

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Butik Moda

Aktif user'ın (ve bayilik kapsamındaki) Shopier bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/shopier/connections"
const url = new URL(
    "https://dowaba.com/api/shopier/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopier/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/shopier/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/shopier/connections/1"
const url = new URL(
    "https://dowaba.com/api/shopier/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopier/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/shopier/connections/{connection}

URL Parameters

connection   integer     

ShopierConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/shopier/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/shopier/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopier/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 113
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/shopier/manifest/{manifestToken}

URL Parameters

manifestToken   string     

ShopierConnection.manifest_token. Example: consequatur

AI function call -> Shopier REST proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/shopier/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/shopier/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/shopier/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 112
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/shopier/proxy/{manifestToken}/{action}

POST api/shopier/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı Shopier mağazasının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

İdeaSoft Entegrasyonu

Authorize URL üret + CSRF state cache'le.

Example request:
curl --request POST \
    "https://dowaba.com/api/ideasoft/oauth/start" \
    --header "Content-Type: application/json" \
    --data "{
    \"store\": \"magaza\",
    \"site_id\": 17,
    \"client_id\": \"consequatur\",
    \"client_secret\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/ideasoft/oauth/start"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "store": "magaza",
    "site_id": 17,
    "client_id": "consequatur",
    "client_secret": "consequatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ideasoft/oauth/start';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'store' => 'magaza',
            'site_id' => 17,
            'client_id' => 'consequatur',
            'client_secret' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ideasoft/oauth/start

Headers

Content-Type        

Example: application/json

Body Parameters

store   string     

Mağaza adı (subdomain). Example: magaza

site_id   integer     

DoWaba site ID'si. Example: 17

client_id   string     

İdeaSoft API uygulaması Client ID. Example: consequatur

client_secret   string     

İdeaSoft API uygulaması Client Secret. Example: consequatur

Bağlantıları listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ideasoft/connections"
const url = new URL(
    "https://dowaba.com/api/ideasoft/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ideasoft/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ideasoft/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/ideasoft/connections/1"
const url = new URL(
    "https://dowaba.com/api/ideasoft/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ideasoft/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/ideasoft/connections/{connection}

URL Parameters

connection   integer     

IdeasoftConnection ID. Example: 1

OAuth callback (PUBLIC — İdeaSoft redirect eder, popup postMessage).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ideasoft/oauth/callback"
const url = new URL(
    "https://dowaba.com/api/ideasoft/oauth/callback"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ideasoft/oauth/callback';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html lang="tr"><head><meta charset="utf-8"><title>İdeaSoft bağlantı hatası</title>
<style>
  body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:#fbfaf7;
       display:flex;align-items:center;justify-content:center;height:100vh;margin:0;color:#1a1a2e}
  .card{background:#fff;padding:40px;border-radius:16px;box-shadow:0 8px 24px rgba(0,0,0,0.08);text-align:center;max-width:400px}
  .icon{width:64px;height:64px;border-radius:50%;background:#ef444422;color:#ef4444;
        display:flex;align-items:center;justify-content:center;margin:0 auto 16px;font-size:32px;font-weight:700}
  h1{font-size:20px;margin:0 0 8px} p{color:#525873;font-size:14px;margin:0}
</style></head>
<body>
<div class="card"><div class="icon">✗</div><h1>İdeaSoft bağlantı hatası</h1><p>İdeaSoft izin vermedi</p></div>
<script>
  try { if (window.opener) window.opener.postMessage({source:'ideasoft_oauth', payload:{&quot;error&quot;:&quot;İdeaSoft izin vermedi&quot;}}, '*'); } catch(e){}
  setTimeout(function(){ try{window.close();}catch(e){} }, 2500);
</script>
</body></html>
 

Request      

GET api/ideasoft/oauth/callback

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ideasoft/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/ideasoft/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ideasoft/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 109
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/ideasoft/manifest/{manifestToken}

URL Parameters

manifestToken   string     

IdeasoftConnection.manifest_token. Example: consequatur

AI function call -> İdeaSoft REST proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ideasoft/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/ideasoft/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ideasoft/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 108
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/ideasoft/proxy/{manifestToken}/{action}

POST api/ideasoft/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Opaque token. Example: consequatur

action   string     

Desteklenen action. Example: product_search

T-Soft Entegrasyonu

Web servis kullanıcısıyla bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/tsoft/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"domain\": \"magaza.com\",
    \"username\": \"consequatur\",
    \"password\": \"O[2UZ5ij-e\\/dl4m{o,\",
    \"site_id\": 17,
    \"store_name\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/tsoft/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "domain": "magaza.com",
    "username": "consequatur",
    "password": "O[2UZ5ij-e\/dl4m{o,",
    "site_id": 17,
    "store_name": "consequatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tsoft/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'domain' => 'magaza.com',
            'username' => 'consequatur',
            'password' => 'O[2UZ5ij-e/dl4m{o,',
            'site_id' => 17,
            'store_name' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tsoft/connections

Headers

Content-Type        

Example: application/json

Body Parameters

domain   string     

Mağaza domaini. Example: magaza.com

username   string     

Web servis kullanıcı adı. Example: consequatur

password   string     

Web servis parolası. Example: O[2UZ5ij-e/dl4m{o,

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: consequatur

Bağlantıları listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tsoft/connections"
const url = new URL(
    "https://dowaba.com/api/tsoft/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tsoft/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tsoft/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tsoft/connections/1"
const url = new URL(
    "https://dowaba.com/api/tsoft/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tsoft/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tsoft/connections/{connection}

URL Parameters

connection   integer     

TsoftConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tsoft/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/tsoft/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tsoft/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 111
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/tsoft/manifest/{manifestToken}

URL Parameters

manifestToken   string     

TsoftConnection.manifest_token. Example: consequatur

AI function call -> T-Soft rest1 proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tsoft/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/tsoft/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tsoft/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 110
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/tsoft/proxy/{manifestToken}/{action}

POST api/tsoft/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Opaque token. Example: consequatur

action   string     

Desteklenen action. Example: product_search

Ticimax Entegrasyonu

WS Yetki Kodu ile bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/ticimax/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"domain\": \"magaza.com\",
    \"uye_kodu\": \"consequatur\",
    \"site_id\": 17,
    \"store_name\": \"Butik Moda\"
}"
const url = new URL(
    "https://dowaba.com/api/ticimax/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "domain": "magaza.com",
    "uye_kodu": "consequatur",
    "site_id": 17,
    "store_name": "Butik Moda"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ticimax/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'domain' => 'magaza.com',
            'uye_kodu' => 'consequatur',
            'site_id' => 17,
            'store_name' => 'Butik Moda',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ticimax/connections

Headers

Content-Type        

Example: application/json

Body Parameters

domain   string     

Ticimax mağaza domain'i. Example: magaza.com

uye_kodu   string     

Ticimax WS Yetki Kodu (UyeKodu). Example: consequatur

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Butik Moda

Aktif user'ın (ve bayilik kapsamındaki) Ticimax bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ticimax/connections"
const url = new URL(
    "https://dowaba.com/api/ticimax/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ticimax/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ticimax/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/ticimax/connections/1"
const url = new URL(
    "https://dowaba.com/api/ticimax/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ticimax/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/ticimax/connections/{connection}

URL Parameters

connection   integer     

TicimaxConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ticimax/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/ticimax/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ticimax/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 95
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/ticimax/manifest/{manifestToken}

URL Parameters

manifestToken   string     

TicimaxConnection.manifest_token. Example: consequatur

AI function call -> Ticimax SOAP proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ticimax/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/ticimax/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ticimax/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 94
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/ticimax/proxy/{manifestToken}/{action}

POST api/ticimax/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı Ticimax mağazasının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

N11 Entegrasyonu

appkey + appsecret ile bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/n11/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"app_key\": \"consequatur\",
    \"app_secret\": \"consequatur\",
    \"site_id\": 17,
    \"store_name\": \"Butik Moda\"
}"
const url = new URL(
    "https://dowaba.com/api/n11/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "app_key": "consequatur",
    "app_secret": "consequatur",
    "site_id": 17,
    "store_name": "Butik Moda"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/n11/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'app_key' => 'consequatur',
            'app_secret' => 'consequatur',
            'site_id' => 17,
            'store_name' => 'Butik Moda',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/n11/connections

Headers

Content-Type        

Example: application/json

Body Parameters

app_key   string     

N11 API appkey (mağaza panelinden). Example: consequatur

app_secret   string     

N11 API appsecret (mağaza panelinden). Example: consequatur

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Butik Moda

Aktif user'ın (ve bayilik kapsamındaki) N11 bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/n11/connections"
const url = new URL(
    "https://dowaba.com/api/n11/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/n11/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/n11/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/n11/connections/1"
const url = new URL(
    "https://dowaba.com/api/n11/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/n11/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/n11/connections/{connection}

URL Parameters

connection   integer     

N11Connection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/n11/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/n11/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/n11/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 107
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/n11/manifest/{manifestToken}

URL Parameters

manifestToken   string     

N11Connection.manifest_token. Example: consequatur

AI function call -> N11 REST proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/n11/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/n11/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/n11/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 106
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/n11/proxy/{manifestToken}/{action}

POST api/n11/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı N11 mağazasının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

Hepsiburada Entegrasyonu

Merchant API kimlik bilgileri ile bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/hepsiburada/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"merchant_id\": \"consequatur\",
    \"username\": \"consequatur\",
    \"secret_key\": \"consequatur\",
    \"site_id\": 17,
    \"store_name\": \"Butik Moda\"
}"
const url = new URL(
    "https://dowaba.com/api/hepsiburada/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "merchant_id": "consequatur",
    "username": "consequatur",
    "secret_key": "consequatur",
    "site_id": 17,
    "store_name": "Butik Moda"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/hepsiburada/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'merchant_id' => 'consequatur',
            'username' => 'consequatur',
            'secret_key' => 'consequatur',
            'site_id' => 17,
            'store_name' => 'Butik Moda',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/hepsiburada/connections

Headers

Content-Type        

Example: application/json

Body Parameters

merchant_id   string     

Hepsiburada Merchant ID (GUID). Example: consequatur

username   string     

Basic Auth kullanıcı adı. Example: consequatur

secret_key   string     

Hepsiburada Servis Anahtarı / secret. Example: consequatur

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Butik Moda

Aktif user'ın (ve bayilik kapsamındaki) Hepsiburada bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/hepsiburada/connections"
const url = new URL(
    "https://dowaba.com/api/hepsiburada/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/hepsiburada/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/hepsiburada/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/hepsiburada/connections/1"
const url = new URL(
    "https://dowaba.com/api/hepsiburada/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/hepsiburada/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/hepsiburada/connections/{connection}

URL Parameters

connection   integer     

HepsiburadaConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/hepsiburada/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/hepsiburada/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/hepsiburada/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 105
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/hepsiburada/manifest/{manifestToken}

URL Parameters

manifestToken   string     

HepsiburadaConnection.manifest_token. Example: consequatur

AI function call -> Hepsiburada Merchant API proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/hepsiburada/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/hepsiburada/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/hepsiburada/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 104
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/hepsiburada/proxy/{manifestToken}/{action}

POST api/hepsiburada/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı Hepsiburada hesabının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

Pazarama Entegrasyonu

API Key + API Secret ile bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/pazarama/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"apikey\": \"consequatur\",
    \"apisecret\": \"consequatur\",
    \"site_id\": 17,
    \"store_name\": \"Butik Moda\"
}"
const url = new URL(
    "https://dowaba.com/api/pazarama/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "apikey": "consequatur",
    "apisecret": "consequatur",
    "site_id": 17,
    "store_name": "Butik Moda"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/pazarama/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'apikey' => 'consequatur',
            'apisecret' => 'consequatur',
            'site_id' => 17,
            'store_name' => 'Butik Moda',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/pazarama/connections

Headers

Content-Type        

Example: application/json

Body Parameters

apikey   string     

Pazarama API Key (clientId). Example: consequatur

apisecret   string     

Pazarama API Secret (clientSecret). Example: consequatur

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Butik Moda

Aktif user'ın (ve bayilik kapsamındaki) Pazarama bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/pazarama/connections"
const url = new URL(
    "https://dowaba.com/api/pazarama/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/pazarama/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/pazarama/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/pazarama/connections/1"
const url = new URL(
    "https://dowaba.com/api/pazarama/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/pazarama/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/pazarama/connections/{connection}

URL Parameters

connection   integer     

PazaramaConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/pazarama/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/pazarama/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/pazarama/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 103
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/pazarama/manifest/{manifestToken}

URL Parameters

manifestToken   string     

PazaramaConnection.manifest_token. Example: consequatur

AI function call -> Pazarama satıcı REST proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/pazarama/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/pazarama/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/pazarama/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 102
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/pazarama/proxy/{manifestToken}/{action}

POST api/pazarama/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı Pazarama hesabının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

Çiçeksepeti Entegrasyonu

API anahtarı ile bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/ciceksepeti/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"api_key\": \"consequatur\",
    \"site_id\": 17,
    \"store_name\": \"Çiçek Dünyası\",
    \"supplier_id\": \"12345\"
}"
const url = new URL(
    "https://dowaba.com/api/ciceksepeti/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "api_key": "consequatur",
    "site_id": 17,
    "store_name": "Çiçek Dünyası",
    "supplier_id": "12345"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ciceksepeti/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'api_key' => 'consequatur',
            'site_id' => 17,
            'store_name' => 'Çiçek Dünyası',
            'supplier_id' => '12345',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ciceksepeti/connections

Headers

Content-Type        

Example: application/json

Body Parameters

api_key   string     

Çiçeksepeti satıcı API anahtarı (x-api-key). Example: consequatur

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Çiçek Dünyası

supplier_id   string  optional    

Çiçeksepeti satıcı/supplier id — User-Agent için (opsiyonel). Example: 12345

Aktif user'ın (ve bayilik kapsamındaki) Çiçeksepeti bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ciceksepeti/connections"
const url = new URL(
    "https://dowaba.com/api/ciceksepeti/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ciceksepeti/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ciceksepeti/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/ciceksepeti/connections/1"
const url = new URL(
    "https://dowaba.com/api/ciceksepeti/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ciceksepeti/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/ciceksepeti/connections/{connection}

URL Parameters

connection   integer     

CiceksepetiConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ciceksepeti/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/ciceksepeti/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ciceksepeti/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 101
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/ciceksepeti/manifest/{manifestToken}

URL Parameters

manifestToken   string     

CiceksepetiConnection.manifest_token. Example: consequatur

AI function call -> Çiçeksepeti REST proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ciceksepeti/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/ciceksepeti/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ciceksepeti/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 100
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/ciceksepeti/proxy/{manifestToken}/{action}

POST api/ciceksepeti/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı Çiçeksepeti mağazasının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

BigCommerce Entegrasyonu

Store hash + Access Token ile bağlan. Rehber: BigCommerce panelinde Settings → Store-level API accounts → Create API account. OAuth scope olarak "Products: read-only" + "Orders: read-only" seçmeniz yeterli (DoWaba yalnız okur, sipariş oluşturmaz). Store hash, API path'inde görünür: https://api.bigcommerce.com/stores/{store_hash}/v3/

Example request:
curl --request POST \
    "https://dowaba.com/api/bigcommerce/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"store_hash\": \"abc123xyz\",
    \"access_token\": \"consequatur\",
    \"site_id\": 17,
    \"store_name\": \"Butik Moda\"
}"
const url = new URL(
    "https://dowaba.com/api/bigcommerce/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "store_hash": "abc123xyz",
    "access_token": "consequatur",
    "site_id": 17,
    "store_name": "Butik Moda"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/bigcommerce/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'store_hash' => 'abc123xyz',
            'access_token' => 'consequatur',
            'site_id' => 17,
            'store_name' => 'Butik Moda',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/bigcommerce/connections

Headers

Content-Type        

Example: application/json

Body Parameters

store_hash   string     

BigCommerce store hash (API path'indeki kısa kod). Example: abc123xyz

access_token   string     

Store-level API account Access Token. Example: consequatur

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Butik Moda

Aktif user'ın (ve bayilik kapsamındaki) BigCommerce bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/bigcommerce/connections"
const url = new URL(
    "https://dowaba.com/api/bigcommerce/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/bigcommerce/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/bigcommerce/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/bigcommerce/connections/1"
const url = new URL(
    "https://dowaba.com/api/bigcommerce/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/bigcommerce/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/bigcommerce/connections/{connection}

URL Parameters

connection   integer     

BigcommerceConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/bigcommerce/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/bigcommerce/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/bigcommerce/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 99
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/bigcommerce/manifest/{manifestToken}

URL Parameters

manifestToken   string     

BigcommerceConnection.manifest_token. Example: consequatur

AI function call -> BigCommerce REST proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/bigcommerce/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/bigcommerce/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/bigcommerce/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 98
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/bigcommerce/proxy/{manifestToken}/{action}

POST api/bigcommerce/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı BigCommerce mağazasının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

Wix Entegrasyonu

API Key ile bağlan.

Example request:
curl --request POST \
    "https://dowaba.com/api/wix/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"api_key\": \"consequatur\",
    \"wix_site_id\": \"12345678-1234-1234-1234-123456789012\",
    \"site_id\": 17,
    \"store_name\": \"Butik Moda\"
}"
const url = new URL(
    "https://dowaba.com/api/wix/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "api_key": "consequatur",
    "wix_site_id": "12345678-1234-1234-1234-123456789012",
    "site_id": 17,
    "store_name": "Butik Moda"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/wix/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'api_key' => 'consequatur',
            'wix_site_id' => '12345678-1234-1234-1234-123456789012',
            'site_id' => 17,
            'store_name' => 'Butik Moda',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/wix/connections

Headers

Content-Type        

Example: application/json

Body Parameters

api_key   string     

Wix API Key (Account Settings → API Keys). Example: consequatur

wix_site_id   string     

Wix Site ID (dashboard URL'indeki GUID). Example: 12345678-1234-1234-1234-123456789012

site_id   integer     

DoWaba site ID'si. Example: 17

store_name   string  optional    

Görünen mağaza adı (opsiyonel). Example: Butik Moda

Aktif user'ın (ve bayilik kapsamındaki) Wix bağlantılarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/wix/connections"
const url = new URL(
    "https://dowaba.com/api/wix/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/wix/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/wix/connections

Bağlantıyı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/wix/connections/1"
const url = new URL(
    "https://dowaba.com/api/wix/connections/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/wix/connections/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/wix/connections/{connection}

URL Parameters

connection   integer     

WixConnection ID. Example: 1

Bundle Import manifest JSON (PUBLIC — token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/wix/manifest/consequatur"
const url = new URL(
    "https://dowaba.com/api/wix/manifest/consequatur"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/wix/manifest/consequatur';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 97
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/wix/manifest/{manifestToken}

URL Parameters

manifestToken   string     

WixConnection.manifest_token. Example: consequatur

AI function call -> Wix REST proxy.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/wix/proxy/consequatur/product_search"
const url = new URL(
    "https://dowaba.com/api/wix/proxy/consequatur/product_search"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/wix/proxy/consequatur/product_search';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 120
x-ratelimit-remaining: 96
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya pasif."
}
 

Request      

GET api/wix/proxy/{manifestToken}/{action}

POST api/wix/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

Bağlı Wix mağazasının opaque token'ı. Example: consequatur

action   string     

Desteklenen action. Example: product_search

Entegra Entegrasyonu

Kullanıcının erişebildiği site'lar için tüm Entegra bağlantıları.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/entegra/connections"
const url = new URL(
    "https://dowaba.com/api/entegra/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/entegra/connections

Belirli site için bağlantı detayı (yoksa null).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/entegra/connections/site/17"
const url = new URL(
    "https://dowaba.com/api/entegra/connections/site/17"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/connections/site/17';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/entegra/connections/site/{siteId}

URL Parameters

siteId   integer     

Site ID. Example: 17

Yeni Entegra bağlantısı oluştur + login dene.

Example request:
curl --request POST \
    "https://dowaba.com/api/entegra/connections" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"email\": \"qkunze@example.com\",
    \"password\": \"O[2UZ5ij-e\\/dl4m{o,\",
    \"account_name\": \"Entegra Ana Hesap\",
    \"base_url\": \"http:\\/\\/kunze.biz\\/iste-laborum-eius-est-dolor.html\"
}"
const url = new URL(
    "https://dowaba.com/api/entegra/connections"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "email": "qkunze@example.com",
    "password": "O[2UZ5ij-e\/dl4m{o,",
    "account_name": "Entegra Ana Hesap",
    "base_url": "http:\/\/kunze.biz\/iste-laborum-eius-est-dolor.html"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/connections';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'email' => 'qkunze@example.com',
            'password' => 'O[2UZ5ij-e/dl4m{o,',
            'account_name' => 'Entegra Ana Hesap',
            'base_url' => 'http://kunze.biz/iste-laborum-eius-est-dolor.html',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/entegra/connections

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Hedef site ID. Example: 17

email   string     

Entegra hesap email. Example: qkunze@example.com

password   string     

Entegra hesap parolası. Example: O[2UZ5ij-e/dl4m{o,

account_name   string  optional    

İnsan-okunabilir hesap adı (opsiyonel). Example: Entegra Ana Hesap

base_url   string  optional    

Custom base URL (default: https://api.entegrabilisim.com). Example: http://kunze.biz/iste-laborum-eius-est-dolor.html

Mevcut bağlantı için login'i yeniden dene (parola değişti vs.).

Example request:
curl --request POST \
    "https://dowaba.com/api/entegra/connections/17/reauth"
const url = new URL(
    "https://dowaba.com/api/entegra/connections/17/reauth"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/connections/17/reauth';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/entegra/connections/{connectionId}/reauth

URL Parameters

connectionId   integer     

Bağlantı ID. Example: 17

Bağlantı durumu — token canlı mı, refresh gerekiyor mu.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/entegra/connections/17/status"
const url = new URL(
    "https://dowaba.com/api/entegra/connections/17/status"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/connections/17/status';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/entegra/connections/{connectionId}/status

URL Parameters

connectionId   integer     

Bağlantı ID. Example: 17

Bağlantıyı sil — site'ın Entegra entegrasyonunu kapatır.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/entegra/connections/17"
const url = new URL(
    "https://dowaba.com/api/entegra/connections/17"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/connections/17';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/entegra/connections/{connectionId}

URL Parameters

connectionId   integer     

Bağlantı ID. Example: 17

Bundle Import manifest JSON (PUBLIC — auth yok, token URL'de).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/entegra/manifest/mtk_a1b2c3d4"
const url = new URL(
    "https://dowaba.com/api/entegra/manifest/mtk_a1b2c3d4"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/manifest/mtk_a1b2c3d4';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 60
x-ratelimit-remaining: 33
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Manifest bulunamadı veya bağlantı pasif."
}
 

Request      

GET api/entegra/manifest/{manifestToken}

URL Parameters

manifestToken   string     

EntegraConnection.manifest_token (48-char opaque). Example: mtk_a1b2c3d4

Entegra API proxy — AI fonksiyonlarından gelen çağrıları Entegra'ya yönlendirir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/entegra/proxy/mtk_a1b2c3d4/health"
const url = new URL(
    "https://dowaba.com/api/entegra/proxy/mtk_a1b2c3d4/health"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/entegra/proxy/mtk_a1b2c3d4/health';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (404):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 60
x-ratelimit-remaining: 32
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "error": "Bağlantı bulunamadı veya iptal edilmiş."
}
 

Request      

GET api/entegra/proxy/{manifestToken}/{action}

POST api/entegra/proxy/{manifestToken}/{action}

URL Parameters

manifestToken   string     

EntegraConnection.manifest_token (48-char opaque). Example: mtk_a1b2c3d4

action   string     

İşlem adı (health, get, post, endpoints, ...). Example: health

YouTube (Paylaşım)

YouTube OAuth authorize URL + client_id.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/youtube/oauth/config"
const url = new URL(
    "https://dowaba.com/api/youtube/oauth/config"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube/oauth/config';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/youtube/oauth/config

Cache'deki kanal bilgisini frontend'e döner (kullanıcı onayı öncesi).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/youtube/oauth/pending"
const url = new URL(
    "https://dowaba.com/api/youtube/oauth/pending"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube/oauth/pending';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/youtube/oauth/pending

Cache'deki OAuth bilgilerini DB'ye yaz (yeni kanal veya güncelleme).

Example request:
curl --request POST \
    "https://dowaba.com/api/youtube/oauth/save" \
    --header "Content-Type: application/json" \
    --data "{
    \"cache_key\": \"a1b2c3d4e5f6\"
}"
const url = new URL(
    "https://dowaba.com/api/youtube/oauth/save"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "cache_key": "a1b2c3d4e5f6"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube/oauth/save';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'cache_key' => 'a1b2c3d4e5f6',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/youtube/oauth/save

Headers

Content-Type        

Example: application/json

Body Parameters

cache_key   string     

OAuth callback'in ürettiği geçici oturum anahtarı (token sunucu tarafında bu anahtarla saklanır). Example: a1b2c3d4e5f6

Kullanıcının (cascade) YouTube kanallarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/youtube-profiles"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/youtube-profiles

channels.list ile bağlantıyı test et.

Example request:
curl --request POST \
    "https://dowaba.com/api/youtube-profiles/1562/test"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles/1562/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles/1562/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/youtube-profiles/{id}/test

URL Parameters

id   string     

The ID of the youtube profile. Example: 1562

YouTube OAuth callback (PUBLIC — Google bu URL'e redirect eder). Code → token + kanal bilgisi → 5dk Cache → popup postMessage.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/youtube/callback"
const url = new URL(
    "https://dowaba.com/api/youtube/callback"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube/callback';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: unsafe-none
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html>
<head><title>YouTube Bağlantısı</title></head>
<body>
<p>İşlem tamamlanıyor...</p>
<script>
(function() {
    var oauthData = {"error":"İzin verilmedi"};
    var bcSent = false;
    var openerSent = false;

    try {
        if (typeof BroadcastChannel === 'function') {
            var bc = new BroadcastChannel('youtube_oauth');
            bc.postMessage({ type: 'youtube_oauth', data: oauthData });
            bc.close();
            bcSent = true;
        }
    } catch (e) { /* unsupported */ }

    var opener = null;
    try { opener = window.opener; } catch (e) { /* COOP */ }
    if (opener) {
        try {
            opener.postMessage({ type: 'youtube_oauth', data: oauthData }, '*');
            openerSent = true;
        } catch (e) { /* cross-origin */ }
    }

    if (bcSent || openerSent) {
        document.body.innerHTML = '<div style="font-family:system-ui,-apple-system,sans-serif;text-align:center;padding:60px 20px;color:#0f172a"><div style="font-size:48px;margin-bottom:16px">✓</div><h2 style="margin:0 0 8px;font-size:20px">YouTube bağlandı</h2><p style="color:#64748b;margin:0">Bu pencereyi kapatabilirsiniz.</p></div>';
        setTimeout(function(){ try { window.close(); } catch (e) {} }, 600);
        return;
    }

    window.location.href = "\/admin\/#\/sites?oauth_error=%C4%B0zin+verilmedi";
})();
</script>
</body>
</html>
 

Request      

GET api/youtube/callback

Facebook Sayfa (Paylaşım)

FB Sayfa OAuth authorize URL.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/facebook-page/oauth/config"
const url = new URL(
    "https://dowaba.com/api/facebook-page/oauth/config"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page/oauth/config';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/facebook-page/oauth/config

Cache'deki yönetilen sayfa listesini döner (kullanıcı hangisini bağlayacak seçer).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/facebook-page/oauth/pending"
const url = new URL(
    "https://dowaba.com/api/facebook-page/oauth/pending"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page/oauth/pending';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/facebook-page/oauth/pending

Seçilen sayfa(ları) DB'ye bağla.

Example request:
curl --request POST \
    "https://dowaba.com/api/facebook-page/oauth/save" \
    --header "Content-Type: application/json" \
    --data "{
    \"cache_key\": \"a1b2c3d4e5f6\",
    \"page_id\": \"1234567890\"
}"
const url = new URL(
    "https://dowaba.com/api/facebook-page/oauth/save"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "cache_key": "a1b2c3d4e5f6",
    "page_id": "1234567890"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page/oauth/save';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'cache_key' => 'a1b2c3d4e5f6',
            'page_id' => '1234567890',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/facebook-page/oauth/save

Headers

Content-Type        

Example: application/json

Body Parameters

cache_key   string     

OAuth callback'in ürettiği geçici oturum anahtarı (sayfa listesi sunucu tarafında bu anahtarla saklanır). Example: a1b2c3d4e5f6

page_id   string     

Bağlanacak Facebook Sayfasının ID'si. Example: 1234567890

OAuth sonucundaki TÜM yönetilen sayfaları tek seferde yayına aç (upsert). "Mevcut sayfaları getir" akışı: kullanıcı pick yapmaz, hepsi publish-ready olur.

Example request:
curl --request POST \
    "https://dowaba.com/api/facebook-page/oauth/save-all" \
    --header "Content-Type: application/json" \
    --data "{
    \"cache_key\": \"a1b2c3d4e5f6\"
}"
const url = new URL(
    "https://dowaba.com/api/facebook-page/oauth/save-all"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "cache_key": "a1b2c3d4e5f6"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page/oauth/save-all';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'cache_key' => 'a1b2c3d4e5f6',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/facebook-page/oauth/save-all

Headers

Content-Type        

Example: application/json

Body Parameters

cache_key   string     

OAuth callback'in ürettiği geçici oturum anahtarı (sayfa listesi sunucu tarafında bu anahtarla saklanır). Example: a1b2c3d4e5f6

FB OAuth callback (PUBLIC). Code → user token → sayfa listesi → 5dk Cache → popup.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/facebook-page/callback"
const url = new URL(
    "https://dowaba.com/api/facebook-page/callback"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page/callback';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: unsafe-none
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html><head><title>Facebook Sayfa Bağlantısı</title></head>
<body><p>İşlem tamamlanıyor...</p>
<script>
(function() {
    var oauthData = {"error":"İzin verilmedi"};
    var bcSent = false, openerSent = false;
    try { if (typeof BroadcastChannel === 'function') { var bc = new BroadcastChannel('facebook_page_oauth'); bc.postMessage({ type: 'facebook_page_oauth', data: oauthData }); bc.close(); bcSent = true; } } catch (e) {}
    var opener = null; try { opener = window.opener; } catch (e) {}
    if (opener) { try { opener.postMessage({ type: 'facebook_page_oauth', data: oauthData }, '*'); openerSent = true; } catch (e) {} }
    if (bcSent || openerSent) {
        document.body.innerHTML = '<div style="font-family:system-ui,-apple-system,sans-serif;text-align:center;padding:60px 20px;color:#0f172a"><div style="font-size:48px;margin-bottom:16px">✓</div><h2 style="margin:0 0 8px;font-size:20px">Facebook bağlandı</h2><p style="color:#64748b;margin:0">Bu pencereyi kapatabilirsiniz.</p></div>';
        setTimeout(function(){ try { window.close(); } catch (e) {} }, 600);
        return;
    }
    window.location.href = "\/admin\/#\/sites?oauth_error=%C4%B0zin+verilmedi";
})();
</script></body></html>
 

Request      

GET api/facebook-page/callback

Paylaşım

Bu sayfanın Lead Ads lead'lerini ŞİMDİ senkronla (manuel tetik). Beta kapısı + leads_sync_enabled şart. leads:sync-facebook --profile=id inline çalışır, sonuç satırını döner.

Example request:
curl --request POST \
    "https://dowaba.com/api/facebook-page-profiles/1562/sync-leads"
const url = new URL(
    "https://dowaba.com/api/facebook-page-profiles/1562/sync-leads"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page-profiles/1562/sync-leads';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/facebook-page-profiles/{id}/sync-leads

URL Parameters

id   string     

The ID of the facebook page profile. Example: 1562

Paylaşım (Sosyal Yayın)

Kullanıcının (cascade) sosyal gönderilerini listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/social-posts"
const url = new URL(
    "https://dowaba.com/api/social-posts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-posts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/social-posts

Yeni gönderi oluştur (taslak/zamanlanmış) + kanal hedefleri.

Example request:
curl --request POST \
    "https://dowaba.com/api/social-posts" \
    --header "Content-Type: application/json" \
    --data "{
    \"title\": \"vmqeopfuudtdsufvyvddq\",
    \"body\": \"amniihfqcoynlazghdtqt\",
    \"media_file_ids\": [
        17
    ],
    \"site_id\": 17,
    \"scheduled_at\": \"2107-08-08\",
    \"targets\": [
        {
            \"channel\": \"tiktok\",
            \"profile_id\": 17
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/social-posts"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "vmqeopfuudtdsufvyvddq",
    "body": "amniihfqcoynlazghdtqt",
    "media_file_ids": [
        17
    ],
    "site_id": 17,
    "scheduled_at": "2107-08-08",
    "targets": [
        {
            "channel": "tiktok",
            "profile_id": 17
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-posts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'title' => 'vmqeopfuudtdsufvyvddq',
            'body' => 'amniihfqcoynlazghdtqt',
            'media_file_ids' => [
                17,
            ],
            'site_id' => 17,
            'scheduled_at' => '2107-08-08',
            'targets' => [
                [
                    'channel' => 'tiktok',
                    'profile_id' => 17,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/social-posts

Headers

Content-Type        

Example: application/json

Body Parameters

title   string  optional    

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

body   string  optional    

Must not be greater than 10000 characters. Example: amniihfqcoynlazghdtqt

media_file_ids   integer[]  optional    

The id of an existing record in the media_files table.

site_id   integer  optional    

Example: 17

scheduled_at   string  optional    

Must be a valid date. Must be a date after now. Example: 2107-08-08

targets   object[]     

Must have at least 1 items.

channel   string     

Example: tiktok

Must be one of:
  • youtube
  • tiktok
  • instagram
  • facebook_page
profile_id   integer     

Example: 17

options   object  optional    

AI ile başlık + açıklamayı (caption) güzelleştir. Gemini key cascade + kredi (kendi→owner→bayi→parent→platform+kredi EN SON) SocialCaptionService üzerinden.

Example request:
curl --request POST \
    "https://dowaba.com/api/social-posts/ai-enhance" \
    --header "Content-Type: application/json" \
    --data "{
    \"title\": \"vmqeopfuudtdsufvyvddq\",
    \"body\": \"amniihfqcoynlazghdtqt\",
    \"platforms\": [
        \"qxbajwbpilpmufinllwlo\"
    ],
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/social-posts/ai-enhance"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "vmqeopfuudtdsufvyvddq",
    "body": "amniihfqcoynlazghdtqt",
    "platforms": [
        "qxbajwbpilpmufinllwlo"
    ],
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-posts/ai-enhance';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'title' => 'vmqeopfuudtdsufvyvddq',
            'body' => 'amniihfqcoynlazghdtqt',
            'platforms' => [
                'qxbajwbpilpmufinllwlo',
            ],
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/social-posts/ai-enhance

Headers

Content-Type        

Example: application/json

Body Parameters

title   string  optional    

Must not be greater than 300 characters. Example: vmqeopfuudtdsufvyvddq

body   string  optional    

Must not be greater than 5000 characters. Example: amniihfqcoynlazghdtqt

platforms   string[]  optional    

Must not be greater than 40 characters.

site_id   integer  optional    

Example: 17

Gönderiyi yayınla — queue job (zamanlanmışsa cron bekler).

Example request:
curl --request POST \
    "https://dowaba.com/api/social-posts/1562/publish"
const url = new URL(
    "https://dowaba.com/api/social-posts/1562/publish"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-posts/1562/publish';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/social-posts/{id}/publish

URL Parameters

id   string     

The ID of the social post. Example: 1562

Birleşik yorum listesi (tüm kanallar). ?channel= + ?status= filtre.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/social-comments"
const url = new URL(
    "https://dowaba.com/api/social-comments"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-comments';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/social-comments

Yoruma cevap yaz (kanal API'sine gönderir).

Example request:
curl --request POST \
    "https://dowaba.com/api/social-comments/1562/reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"text\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/social-comments/1562/reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-comments/1562/reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'text' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/social-comments/{id}/reply

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the social comment. Example: 1562

Body Parameters

text   string     

Must not be greater than 9000 characters. Example: vmqeopfuudtdsufvyvddq

Yorum moderasyonu: hide | hold | show | delete.

Example request:
curl --request POST \
    "https://dowaba.com/api/social-comments/1562/moderate" \
    --header "Content-Type: application/json" \
    --data "{
    \"action\": \"show\",
    \"ban_author\": true
}"
const url = new URL(
    "https://dowaba.com/api/social-comments/1562/moderate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "action": "show",
    "ban_author": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-comments/1562/moderate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'action' => 'show',
            'ban_author' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/social-comments/{id}/moderate

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the social comment. Example: 1562

Body Parameters

action   string     

Example: show

Must be one of:
  • hide
  • hold
  • show
  • delete
ban_author   boolean  optional    

Example: true

Kullanıcının yorum oto-cevap kurallarını listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/social-rules"
const url = new URL(
    "https://dowaba.com/api/social-rules"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-rules';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/social-rules

Reklam Yönetimi

Reklam hesabı OAuth authorize URL (site bazlı).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/oauth/config" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ads/oauth/config"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/oauth/config';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/oauth/config

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

Cache'deki reklam hesabı + sayfa/IG listesini döner (kullanıcı seçer).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/oauth/pending"
const url = new URL(
    "https://dowaba.com/api/ads/oauth/pending"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/oauth/pending';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/oauth/pending

Kullanıcının erişebildiği reklam hesapları (cascade — bayi müşteri sitelerini de görür).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/accounts"
const url = new URL(
    "https://dowaba.com/api/ads/accounts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/accounts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/accounts

Bağlı hesabı düzenlemek için mevcut token ile reklam hesabı + Sayfa/IG listesini YENİDEN getirir (yeni Facebook OAuth GEREKMEDEN). Seçim, mevcut `save()` reconnect kontratıyla kaydedilir (withTrashed updateOrCreate). Token expired / izin çekilmişse `needs_reauth=true` döner → panel OAuth popup akışına düşer (seçili değerler korunur).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/accounts/3/edit-options"
const url = new URL(
    "https://dowaba.com/api/ads/accounts/3/edit-options"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/accounts/3/edit-options';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/accounts/{id}/edit-options

URL Parameters

id   integer     

Bağlı reklam hesabı kaydı. Example: 3

Seçilen reklam hesabını (+ Sayfa/IG) siteye bağla. Reconnect: withTrashed updateOrCreate.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/accounts" \
    --header "Content-Type: application/json" \
    --data "{
    \"cache_key\": \"a1b2c3\",
    \"site_id\": 5,
    \"ad_account_id\": \"act_123\",
    \"page_id\": \"consequatur\",
    \"instagram_account_id\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/accounts"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "cache_key": "a1b2c3",
    "site_id": 5,
    "ad_account_id": "act_123",
    "page_id": "consequatur",
    "instagram_account_id": "consequatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/accounts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'cache_key' => 'a1b2c3',
            'site_id' => 5,
            'ad_account_id' => 'act_123',
            'page_id' => 'consequatur',
            'instagram_account_id' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/accounts

Headers

Content-Type        

Example: application/json

Body Parameters

cache_key   string     

OAuth oturum anahtarı. Example: a1b2c3

site_id   integer     

Bağlanacak site. Example: 5

ad_account_id   string     

Seçilen reklam hesabı (act_...). Example: act_123

page_id   string  optional    

Example: consequatur

instagram_account_id   string  optional    

Example: consequatur

Reklam hesabı bağlantısını kaldır (soft delete — kampanya geçmişi korunur).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/ads/accounts/1562"
const url = new URL(
    "https://dowaba.com/api/ads/accounts/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/accounts/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/ads/accounts/{id}

URL Parameters

id   string     

The ID of the account. Example: 1562

Sitenin reklam hesabındaki Meta Pixel'lerini listele (kurulum kodu + son ateşleme).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/pixels" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ads/pixels"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/pixels';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/pixels

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

Yeni Meta Pixel oluştur (reklam hesabı altında). Kurulum kodu kopyalanabilir.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/pixels" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"name\": \"Dowaba Sitem Pixel\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/pixels"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "name": "Dowaba Sitem Pixel"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/pixels';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'name' => 'Dowaba Sitem Pixel',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/pixels

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

name   string     

Pixel adı. Example: Dowaba Sitem Pixel

Katalog ekranı durumu: bağlı mı + (varsa) işletme adı + Meta Commerce Manager deep-link. Katalog LİSTELEMEZ/oluşturmaz (catalog_management yok) — yönetim Meta'da yapılır.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/catalogs" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5
}"
const url = new URL(
    "https://dowaba.com/api/ads/catalogs"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/catalogs';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/catalogs

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

Seçilebilen görsel modelleri (Nano Banana 2 / Pro / klasik).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/studio/models"
const url = new URL(
    "https://dowaba.com/api/ads/studio/models"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/studio/models';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/studio/models

Sohbet tabanlı prompt geliştirme (gemini-pro-latest). Müşterinin dilinde yanıt; hazır olunca İngilizce prompt + özet (onaya). Referans görsel pro'ya GÖNDERİLMEZ (yalnız üretimde nano banana'ya).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/studio/chat" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"messages\": [
        {
            \"role\": \"user\",
            \"text\": \"yaz indirimi afişi\"
        }
    ],
    \"has_reference\": true
}"
const url = new URL(
    "https://dowaba.com/api/ads/studio/chat"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "messages": [
        {
            "role": "user",
            "text": "yaz indirimi afişi"
        }
    ],
    "has_reference": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/studio/chat';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => \Symfony\Component\VarExporter\Internal\Hydrator::hydrate(
            $o = [
                clone (\Symfony\Component\VarExporter\Internal\Registry::$prototypes['stdClass'] ?? \Symfony\Component\VarExporter\Internal\Registry::p('stdClass')),
            ],
            null,
            [
                'stdClass' => [
                    'role' => [
                        'user',
                    ],
                    'text' => [
                        'yaz indirimi afişi',
                    ],
                ],
            ],
            [
                'site_id' => 5,
                'messages' => [
                    $o[0],
                ],
                'has_reference' => true,
            ],
            []
        ),
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/studio/chat

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

messages   object[]     

Sohbet geçmişi [{role:'user'|'assistant', text}].

role   string     

Example: assistant

Must be one of:
  • user
  • assistant
text   string     

Must not be greater than 4000 characters. Example: vmqeopfuudtdsufvyvddq

has_reference   boolean  optional    

Müşteri referans görsel iliştirdi mi. Example: true

Brief'ten reklam görseli üret (nano banana). Kredi cüzdanından düşülür.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/studio/generate" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"prompt\": \"Yaz indirimi, turuncu, modern afiş\",
    \"model\": \"gemini-3.1-flash-image\",
    \"aspect_ratio\": \"1:1\",
    \"image_size\": \"1K\",
    \"title\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/studio/generate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "prompt": "Yaz indirimi, turuncu, modern afiş",
    "model": "gemini-3.1-flash-image",
    "aspect_ratio": "1:1",
    "image_size": "1K",
    "title": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/studio/generate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'prompt' => 'Yaz indirimi, turuncu, modern afiş',
            'model' => 'gemini-3.1-flash-image',
            'aspect_ratio' => '1:1',
            'image_size' => '1K',
            'title' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/studio/generate

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Site. Example: 5

prompt   string     

Görsel tarifi. Example: Yaz indirimi, turuncu, modern afiş

model   string  optional    

Görsel modeli. Example: gemini-3.1-flash-image

aspect_ratio   string  optional    

En-boy. Example: 1:1

image_size   string  optional    

Çözünürlük (1K/2K/4K). Example: 1K

title   string  optional    

Must not be greater than 200 characters. Example: mqeopfuudtdsufvyvddqa

Onaylanan İngilizce prompt + seçili reklam türleri → her tekil oran için görsel (nano banana). Referans görsel (varsa) nano banana'ya geçer (marka rengi/fontu; yeni kompozisyon).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/studio/generate-set" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"prompt\": \"A modern summer-sale poster...\",
    \"ad_types\": [
        \"feed_square\",
        \"story_reels\"
    ],
    \"model\": \"gemini-3.1-flash-image\",
    \"reference\": \"data:image\\/png;base64,iVBOR...\",
    \"title\": \"mniihfqcoynlazghdtqtq\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/studio/generate-set"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "prompt": "A modern summer-sale poster...",
    "ad_types": [
        "feed_square",
        "story_reels"
    ],
    "model": "gemini-3.1-flash-image",
    "reference": "data:image\/png;base64,iVBOR...",
    "title": "mniihfqcoynlazghdtqtq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/studio/generate-set';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'prompt' => 'A modern summer-sale poster...',
            'ad_types' => [
                'feed_square',
                'story_reels',
            ],
            'model' => 'gemini-3.1-flash-image',
            'reference' => 'data:image/png;base64,iVBOR...',
            'title' => 'mniihfqcoynlazghdtqtq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/studio/generate-set

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

prompt   string     

Onaylanan İngilizce prompt. Example: A modern summer-sale poster...

ad_types   string[]     

feed_square|feed_vertical|story_reels|landscape.

model   string  optional    

Görsel modeli. Example: gemini-3.1-flash-image

reference   string  optional    

Referans görsel (data URL ya da base64). Example: data:image/png;base64,iVBOR...

title   string  optional    

~8MB görselin base64+dataURL karşılığı (decode öncesi eler). Must not be greater than 200 characters. Example: mniihfqcoynlazghdtqtq

Site'in üretilmiş görsel kütüphanesi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/studio/creatives" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ads/studio/creatives"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/studio/creatives';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/studio/creatives

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

Üretilen görseli sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/ads/studio/creatives/1562"
const url = new URL(
    "https://dowaba.com/api/ads/studio/creatives/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/studio/creatives/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/ads/studio/creatives/{id}

URL Parameters

id   string     

The ID of the creative. Example: 1562

Site'in kampanyaları (lokal mirror).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/campaigns" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ads/campaigns"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/campaigns';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/campaigns

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

Meta'daki MEVCUT kampanya/adset/reklamları içe aktar (lokal mirror'a senkronla).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/campaigns/sync" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ads/campaigns/sync"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/campaigns/sync';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/campaigns/sync

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

Hibrit "Yeni Kampanya": Meta'da kampanya kabuğu (objective + PAUSED) açar; frontend onu Meta Ads Manager'da açıp kreatif/bütçe/hedefleme/yayını orada tamamlatır (deep-link).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/campaigns/shell" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"objective\": \"consequatur\",
    \"name\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/campaigns/shell"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "objective": "consequatur",
    "name": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/campaigns/shell';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'objective' => 'consequatur',
            'name' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/campaigns/shell

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

objective   string     

Example: consequatur

name   string  optional    

Must not be greater than 200 characters. Example: mqeopfuudtdsufvyvddqa

Sihirbazdan kampanya yayınla (PAUSED oluşturulur, kullanıcı sonra başlatır).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/campaigns" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"name\": \"Yaz İndirimi\",
    \"objective\": \"OUTCOME_TRAFFIC\",
    \"daily_budget\": 50,
    \"creative\": {
        \"creative_id\": 17
    },
    \"targeting\": [],
    \"optimization_goal\": \"consequatur\",
    \"billing_event\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/campaigns"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "name": "Yaz İndirimi",
    "objective": "OUTCOME_TRAFFIC",
    "daily_budget": 50,
    "creative": {
        "creative_id": 17
    },
    "targeting": [],
    "optimization_goal": "consequatur",
    "billing_event": "consequatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/campaigns';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'name' => 'Yaz İndirimi',
            'objective' => 'OUTCOME_TRAFFIC',
            'daily_budget' => 50.0,
            'creative' => [
                'creative_id' => 17,
            ],
            'targeting' => [],
            'optimization_goal' => 'consequatur',
            'billing_event' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/campaigns

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

name   string     

Example: Yaz İndirimi

objective   string     

OUTCOME_TRAFFIC vb. Example: OUTCOME_TRAFFIC

daily_budget   number     

Günlük bütçe (hesap para birimi). Example: 50

creative   object     

{creative_id, headline, body, link, call_to_action}

creative_id   integer     

Example: 17

targeting   object     

Hedefleme.

optimization_goal   string  optional    

Example: consequatur

billing_event   string  optional    

Example: consequatur

Kampanyayı başlat/durdur (ACTIVE/PAUSED).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/campaigns/1562/status" \
    --header "Content-Type: application/json" \
    --data "{
    \"status\": \"ACTIVE\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/campaigns/1562/status"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "status": "ACTIVE"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/campaigns/1562/status';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'status' => 'ACTIVE',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/campaigns/{id}/status

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the campaign. Example: 1562

Body Parameters

status   string     

ACTIVE|PAUSED. Example: ACTIVE

Mevcut kampanyanın GÜNLÜK bütçesini değiştir. CBO/kampanya-bütçeli ise kampanya node'una, değilse (tek) reklam setine yazar. Birden çok set-bütçeli kampanya panelden düzenlenemez.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/campaigns/1562/budget" \
    --header "Content-Type: application/json" \
    --data "{
    \"daily_budget\": 75
}"
const url = new URL(
    "https://dowaba.com/api/ads/campaigns/1562/budget"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "daily_budget": 75
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/campaigns/1562/budget';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'daily_budget' => 75.0,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/campaigns/{id}/budget

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the campaign. Example: 1562

Body Parameters

daily_budget   number     

Yeni günlük bütçe (hesap para birimi). Example: 75

Site'in oluşturulmuş hedef kitleleri.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/audiences" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ads/audiences"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/audiences';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/audiences

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

Hedef kitle oluştur — "kendi takipçilerim" (IG/Sayfa engagement) veya lookalike.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/audiences" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"type\": \"ig_engagement\",
    \"name\": \"mqeopfuudtdsufvyvddqa\",
    \"origin_audience_id\": \"consequatur\",
    \"ratio\": 11613.31890586,
    \"country\": \"op\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/audiences"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "type": "ig_engagement",
    "name": "mqeopfuudtdsufvyvddqa",
    "origin_audience_id": "consequatur",
    "ratio": 11613.31890586,
    "country": "op"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/audiences';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'type' => 'ig_engagement',
            'name' => 'mqeopfuudtdsufvyvddqa',
            'origin_audience_id' => 'consequatur',
            'ratio' => 11613.31890586,
            'country' => 'op',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/audiences

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

type   string     

ig_engagement|page_engagement|lookalike. Example: ig_engagement

name   string  optional    

Must not be greater than 200 characters. Example: mqeopfuudtdsufvyvddqa

origin_audience_id   string  optional    

Example: consequatur

ratio   number  optional    

Example: 11613.31890586

country   string  optional    

Must be 2 characters. Example: op

İlgi alanı arama (targeting interests).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/interests" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"q\": \"mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjury\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/interests"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "q": "mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjury"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/interests';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'q' => 'mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjury',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/interests

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

q   string     

Must be at least 2 characters. Example: mqeopfuudtdsufvyvddqamniihfqcoynlazghdtqtqxbajwbpilpmufinllwloauydlsmsjury

Site performans özeti: 7g toplam + günlük seri + placement/region breakdown.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/insights" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"days\": 13,
    \"status\": \"active\",
    \"ad_ids\": [
        \"qeopfuudtdsufvyvddqam\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/ads/insights"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "days": 13,
    "status": "active",
    "ad_ids": [
        "qeopfuudtdsufvyvddqam"
    ]
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/insights';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'days' => 13,
            'status' => 'active',
            'ad_ids' => [
                'qeopfuudtdsufvyvddqam',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/insights

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

days   integer  optional    

Must be at least 1. Must not be greater than 90. Example: 13

status   string  optional    

Example: active

Must be one of:
  • active
  • paused
  • all
ad_ids   string[]  optional    

belirli reklam(lar) seçimi (kampanya gruplu çoklu). Must not be greater than 64 characters.

Site'ın reklamları (kampanyaya göre gruplanabilir) — performans reklam seçici için. Yalnız aynadaki (mevcut) reklamlar; remote_ad_id + çalışma durumu + kampanya bilgisi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/insights/ads" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5
}"
const url = new URL(
    "https://dowaba.com/api/ads/insights/ads"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/insights/ads';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/insights/ads

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

Bir bölgeyi (il) hedeflemeden ÇIKAR — ülke (TR) hedefi korunur, il excluded_geo_locations'a eklenir (81 ili tek tek listelemeye gerek yok; sonuç aynı: o ile reklam gösterilmez). Hesabın tüm ad set'lerine uygulanır (read-modify-write). Aksiyon loglanır.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/insights/exclude-region" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"region\": \"Istanbul Province\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/insights/exclude-region"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "region": "Istanbul Province"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/insights/exclude-region';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'region' => 'Istanbul Province',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/insights/exclude-region

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

region   string     

İl adı (breakdown'daki). Example: Istanbul Province

BİRDEN ÇOK bölgeyi tek seferde hedeflemeden ÇIKAR (toplu seçim). Tek geçişte tüm ad set'lere uygulanır → N×(get+update) yerine az API çağrısı. Eşleşmeyen iller `unmatched`'te döner.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/insights/exclude-regions" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"regions\": [
        \"Karaman Province\",
        \"Hatay Province\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/ads/insights/exclude-regions"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "regions": [
        "Karaman Province",
        "Hatay Province"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/insights/exclude-regions';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'regions' => [
                'Karaman Province',
                'Hatay Province',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/insights/exclude-regions

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

regions   string[]     

İl adları listesi.

Son üretilmiş AI analiz raporu (cache; yoksa null).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/advisor" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"status\": \"all\",
    \"ad_ids\": [
        \"mqeopfuudtdsufvyvddqa\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/ads/advisor"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "status": "all",
    "ad_ids": [
        "mqeopfuudtdsufvyvddqa"
    ]
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/advisor';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'status' => 'all',
            'ad_ids' => [
                'mqeopfuudtdsufvyvddqa',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/advisor

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

status   string  optional    

Example: all

Must be one of:
  • active
  • paused
  • all
ad_ids   string[]  optional    

Must not be greater than 64 characters.

Yeni AI analizi üret (Pro model — kredi düşer). KULLANICI TETİKLER.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/advisor" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"status\": \"active\",
    \"ad_ids\": [
        \"mqeopfuudtdsufvyvddqa\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/ads/advisor"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "status": "active",
    "ad_ids": [
        "mqeopfuudtdsufvyvddqa"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/advisor';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'status' => 'active',
            'ad_ids' => [
                'mqeopfuudtdsufvyvddqa',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/advisor

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

status   string  optional    

Reklam çalışma durumu filtresi: active|paused|all (varsayılan all). Example: active

ad_ids   string[]  optional    

Must not be greater than 64 characters.

AI önerisindeki GÜVENLİ aksiyonu (bölge/yerleşim dışla) tek-tıkla uygula. Sadece geri-alınabilir dışlama aksiyonları; bütçe/kreatif/kitle önerileri panel'de uygulanamaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/advisor/apply" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"type\": \"exclude_region\",
    \"region\": \"Istanbul Province\",
    \"publisher_platform\": \"instagram\",
    \"position\": \"reels\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/advisor/apply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "type": "exclude_region",
    "region": "Istanbul Province",
    "publisher_platform": "instagram",
    "position": "reels"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/advisor/apply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'type' => 'exclude_region',
            'region' => 'Istanbul Province',
            'publisher_platform' => 'instagram',
            'position' => 'reels',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/advisor/apply

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

type   string     

exclude_region veya exclude_placement. Example: exclude_region

region   string  optional    

İl/bölge adı (exclude_region için). Example: Istanbul Province

publisher_platform   string  optional    

facebook|instagram|messenger|audience_network (exclude_placement için). Example: instagram

position   string  optional    

Ops. pozisyon (exclude_placement için). Example: reels

Site'in sızıntı koruması kuralı (yoksa config default'larıyla virtual).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/guard" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/ads/guard"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/guard';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/guard

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

Sızıntı koruması kuralını oluştur/güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/ads/guard" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"is_enabled\": true,
    \"mode\": \"hybrid\",
    \"auto_pause_min_spend_usd\": 45,
    \"recommend_cpr_multiplier\": 56,
    \"learning_grace_days\": 5,
    \"pause_placements\": true,
    \"pause_regions\": true,
    \"pause_interests\": true
}"
const url = new URL(
    "https://dowaba.com/api/ads/guard"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "is_enabled": true,
    "mode": "hybrid",
    "auto_pause_min_spend_usd": 45,
    "recommend_cpr_multiplier": 56,
    "learning_grace_days": 5,
    "pause_placements": true,
    "pause_regions": true,
    "pause_interests": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/guard';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'is_enabled' => true,
            'mode' => 'hybrid',
            'auto_pause_min_spend_usd' => 45,
            'recommend_cpr_multiplier' => 56,
            'learning_grace_days' => 5,
            'pause_placements' => true,
            'pause_regions' => true,
            'pause_interests' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/ads/guard

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 5

is_enabled   boolean  optional    

Example: true

mode   string  optional    

hybrid|autonomous|recommend. Example: hybrid

auto_pause_min_spend_usd   number  optional    

Must be at least 0. Example: 45

recommend_cpr_multiplier   number  optional    

Must be at least 1. Example: 56

learning_grace_days   integer  optional    

Must be at least 0. Must not be greater than 30. Example: 5

pause_placements   boolean  optional    

Example: true

pause_regions   boolean  optional    

Example: true

pause_interests   boolean  optional    

Example: true

Sızıntı koruması aksiyonları (öneri + uygulanan + tasarruf logu).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/guard/actions" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"status\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/ads/guard/actions"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "status": "consequatur"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/guard/actions';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'status' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ads/guard/actions

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

status   string  optional    

Example: consequatur

Bekleyen bir öneriyi uygula (placement de-target / ad pause).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/guard/actions/1562/apply"
const url = new URL(
    "https://dowaba.com/api/ads/guard/actions/1562/apply"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/guard/actions/1562/apply';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/guard/actions/{id}/apply

URL Parameters

id   string     

The ID of the action. Example: 1562

Öneriyi reddet (uygulama).

Example request:
curl --request POST \
    "https://dowaba.com/api/ads/guard/actions/1562/dismiss"
const url = new URL(
    "https://dowaba.com/api/ads/guard/actions/1562/dismiss"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/guard/actions/1562/dismiss';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ads/guard/actions/{id}/dismiss

URL Parameters

id   string     

The ID of the action. Example: 1562

OAuth callback (PUBLIC). code → long token → reklam hesabı + sayfa/IG listesi → cache → popup.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/oauth/callback"
const url = new URL(
    "https://dowaba.com/api/ads/oauth/callback"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/oauth/callback';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: unsafe-none
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html><head><title>Reklam Hesabı Bağlantısı</title></head>
<body><p>İşlem tamamlanıyor...</p>
<script>
(function() {
    var d = {"error":"İzin verilmedi"};
    var sent = false;
    try { if (typeof BroadcastChannel === 'function') { var bc = new BroadcastChannel('meta_ads_oauth'); bc.postMessage({ type: 'meta_ads_oauth', data: d }); bc.close(); sent = true; } } catch (e) {}
    var opener = null; try { opener = window.opener; } catch (e) {}
    if (opener) { try { opener.postMessage({ type: 'meta_ads_oauth', data: d }, '*'); sent = true; } catch (e) {} }
    if (sent) {
        document.body.innerHTML = '<div style="font-family:system-ui,sans-serif;text-align:center;padding:60px 20px;color:#0f172a"><div style="font-size:48px;margin-bottom:16px">✓</div><h2 style="margin:0 0 8px;font-size:20px">Bağlandı</h2><p style="color:#64748b;margin:0">Bu pencereyi kapatabilirsiniz.</p></div>';
        setTimeout(function(){ try { window.close(); } catch (e) {} }, 600);
        return;
    }
    window.location.href = "\/admin\/#\/ads\/accounts?ads_oauth_error=%C4%B0zin+verilmedi";
})();
</script></body></html>
 

Request      

GET api/ads/oauth/callback

Üretilen görseli servis et (imzalı URL — auth signature ile).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ads/creatives/1562/image"
const url = new URL(
    "https://dowaba.com/api/ads/creatives/1562/image"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ads/creatives/1562/image';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (403):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Forbidden</title>

        <style>
            /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}code{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-xl{max-width:36rem}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.uppercase{text-transform:uppercase}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tracking-wider{letter-spacing:.05em}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@-webkit-keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@-webkit-keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-300 { --text-opacity: 1; color: #e2e8f0; color: rgba(226,232,240,var(--text-opacity)) }}
        </style>

        <style>
            body {
                font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
            }
        </style>
    </head>
    <body class="antialiased">
        <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center sm:pt-0" role="main">
            <div class="max-w-xl mx-auto sm:px-6 lg:px-8">
                <div class="flex items-center pt-8 sm:justify-start sm:pt-0">
                    <h1 class="px-4 text-lg dark:text-gray-300 text-gray-700 border-r border-gray-400 tracking-wider">
                        403                    </h1>

                    <div class="ml-4 text-lg dark:text-gray-300 text-gray-700 uppercase tracking-wider">
                        Invalid signature.                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

 

Request      

GET api/ads/creatives/{id}/image

URL Parameters

id   string     

The ID of the creative. Example: 1562

Müşteri Talepleri (Callback)

Tüm callback taleplerini listele (tüm kanallar birleşik). ID prefix kanala göre: WhatsApp 'w-', Voice 'v-', Widget 'cs-'.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/callback-requests"
const url = new URL(
    "https://dowaba.com/api/callback-requests"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/callback-requests

Bir site için atama seçenekleri: atanabilir takım üyeleri (açık talep yükleriyle) + otomatik dağıtım ayarının mevcut durumu.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/callback-requests/assignment-options?site_id=5" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 73
}"
const url = new URL(
    "https://dowaba.com/api/callback-requests/assignment-options"
);

const params = {
    "site_id": "5",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 73
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests/assignment-options';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'query' => [
            'site_id' => '5',
        ],
        'json' => [
            'site_id' => 73,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "auto_assign": false,
    "users": [
        {
            "id": 17,
            "name": "Ali Veli",
            "email": "a**@example.com",
            "role": "agent",
            "open_count": 3
        }
    ]
}
 

Request      

GET api/callback-requests/assignment-options

Headers

Content-Type        

Example: application/json

Query Parameters

site_id   integer     

Site ID. Example: 5

Body Parameters

site_id   integer     

Must be at least 1. Example: 73

Otomatik dağıtımı aç/kapat. Açıkken yeni müşteri talepleri, sitenin takım üyeleri (agent) arasında en az açık talebi olana otomatik atanır.

Example request:
curl --request PUT \
    "https://dowaba.com/api/callback-requests/auto-assign" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"enabled\": true
}"
const url = new URL(
    "https://dowaba.com/api/callback-requests/auto-assign"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "enabled": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests/auto-assign';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'enabled' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "auto_assign": true
}
 

Request      

PUT api/callback-requests/auto-assign

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Site ID. Example: 5

enabled   boolean     

Otomatik dağıtım açık mı. Example: true

AI özet dilini ayarla (kullanıcıya özel). Müşteri Talepleri başlığındaki seçiciden çağrılır. Özet, site sahibinin bu ayarındaki dilde üretilir (default: TR).

Example request:
curl --request PUT \
    "https://dowaba.com/api/callback-requests/summary-locale" \
    --header "Content-Type: application/json" \
    --data "{
    \"locale\": \"tr\"
}"
const url = new URL(
    "https://dowaba.com/api/callback-requests/summary-locale"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "locale": "tr"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests/summary-locale';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'locale' => 'tr',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "summary_locale": "tr"
}
 

Request      

PUT api/callback-requests/summary-locale

Headers

Content-Type        

Example: application/json

Body Parameters

locale   string     

Dil kodu (config/callback_summary.php listesinden). Example: tr

Bir müşteri talebinin TAM konuşma geçmişini döndür (panel "Tüm konuşmayı gör" akordeonu için on-demand). Liste hafif kalsın diye index'te değil ayrı endpoint.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/callback-requests/w-42/conversation"
const url = new URL(
    "https://dowaba.com/api/callback-requests/w-42/conversation"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests/w-42/conversation';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "data": [
        {
            "direction": "in",
            "message": "Merhaba",
            "created_at": "2026-06-21T10:00:00Z"
        }
    ]
}
 

Request      

GET api/callback-requests/{id}/conversation

URL Parameters

id   string     

Kanal prefix'li callback talep ID'si (WhatsApp 'w-', Voice 'v-', Widget 'cs-'). Example: w-42

Callback talebinin durumunu güncelle (pending/contacted/no_answer/postponed/resolved).

Example request:
curl --request PUT \
    "https://dowaba.com/api/callback-requests/w-42/status" \
    --header "Content-Type: application/json" \
    --data "{
    \"status\": \"postponed\"
}"
const url = new URL(
    "https://dowaba.com/api/callback-requests/w-42/status"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "status": "postponed"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests/w-42/status';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'status' => 'postponed',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/callback-requests/{id}/status

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

Kanal prefix'li callback talep ID'si (WhatsApp 'w-', Voice 'v-', Widget 'cs-'). Example: w-42

Body Parameters

status   string     

Example: postponed

Must be one of:
  • pending
  • contacted
  • no_answer
  • resolved
  • postponed

Callback talebine not ekle/güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/callback-requests/w-42/note" \
    --header "Content-Type: application/json" \
    --data "{
    \"note\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/callback-requests/w-42/note"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "note": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests/w-42/note';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'note' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/callback-requests/{id}/note

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

Kanal prefix'li callback talep ID'si (WhatsApp 'w-', Voice 'v-', Widget 'cs-'). Example: w-42

Body Parameters

note   string     

Must not be greater than 5000 characters. Example: vmqeopfuudtdsufvyvddq

Talebi bir takım üyesine ata (veya atamayı kaldır). Atanabilir kullanıcılar: site sahibi + site takım üyeleri (assignment-options endpoint'inden listelenir). Atanan kullanıcıya panel/mobil bildirimi gider.

Example request:
curl --request POST \
    "https://dowaba.com/api/callback-requests/w-42/assign" \
    --header "Content-Type: application/json" \
    --data "{
    \"user_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/callback-requests/w-42/assign"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "user_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/callback-requests/w-42/assign';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'user_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "message": "Talep atandı",
    "assigned_user_id": 17
}
 

Request      

POST api/callback-requests/{id}/assign

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

Kanal prefix'li callback talep ID'si (WhatsApp 'w-', Voice 'v-', Widget 'cs-'). Example: w-42

Body Parameters

user_id   integer  optional    

Atanacak kullanıcı ID'si; null gönderilirse atama kaldırılır. Example: 17

Potansiyel Müşteriler (Leads)

Potansiyel Müşteriler (CRM) — Lead yönetimi. module:leads.

Scope: messagingSiteIds() — bayiye bağlı MÜŞTERİ sitelerinin lead'leri kapalı (mesaj+rehber gizlilik kilidiyle tutarlı; bayi yalnız KENDİ sitelerinin lead'lerini görür/düzenler/siler). store hem manuel hem kaynaktan (öneri/talep/lead ads) ekleme — source/source_type/source_id ile. Tek otorite plan: ~/.claude/plans/biz-buraya-ba-lad-k-ya-cheeky-mist.md.

GET api/leads

Example request:
curl --request GET \
    --get "https://dowaba.com/api/leads"
const url = new URL(
    "https://dowaba.com/api/leads"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/leads

Manuel VEYA kaynaktan (öneri/talep/lead ads) lead ekle.

Example request:
curl --request POST \
    "https://dowaba.com/api/leads" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"name\": \"mqeopfuudtdsufvyvddqa\",
    \"phone\": \"mniihfqcoynlazghdtqtq\",
    \"email\": \"ablanda@example.org\",
    \"stage\": \"consequatur\",
    \"source\": \"consequatur\",
    \"source_type\": \"mqeopfuudtdsufvyvddqa\",
    \"source_id\": 17,
    \"channel\": \"mqeopfuudtdsufvyv\",
    \"value\": 11613.31890586,
    \"notes\": \"opfuudtdsufvyvddqamni\"
}"
const url = new URL(
    "https://dowaba.com/api/leads"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "name": "mqeopfuudtdsufvyvddqa",
    "phone": "mniihfqcoynlazghdtqtq",
    "email": "ablanda@example.org",
    "stage": "consequatur",
    "source": "consequatur",
    "source_type": "mqeopfuudtdsufvyvddqa",
    "source_id": 17,
    "channel": "mqeopfuudtdsufvyv",
    "value": 11613.31890586,
    "notes": "opfuudtdsufvyvddqamni"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'name' => 'mqeopfuudtdsufvyvddqa',
            'phone' => 'mniihfqcoynlazghdtqtq',
            'email' => 'ablanda@example.org',
            'stage' => 'consequatur',
            'source' => 'consequatur',
            'source_type' => 'mqeopfuudtdsufvyvddqa',
            'source_id' => 17,
            'channel' => 'mqeopfuudtdsufvyv',
            'value' => 11613.31890586,
            'notes' => 'opfuudtdsufvyvddqamni',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/leads

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

name   string  optional    

Must not be greater than 200 characters. Example: mqeopfuudtdsufvyvddqa

phone   string  optional    

Must not be greater than 32 characters. Example: mniihfqcoynlazghdtqtq

email   string  optional    

Must be a valid email address. Must not be greater than 191 characters. Example: ablanda@example.org

stage   string  optional    

Example: consequatur

source   string  optional    

Example: consequatur

source_type   string  optional    

Must not be greater than 40 characters. Example: mqeopfuudtdsufvyvddqa

source_id   integer  optional    

Example: 17

channel   string  optional    

Must not be greater than 20 characters. Example: mqeopfuudtdsufvyv

value   number  optional    

Example: 11613.31890586

notes   string  optional    

Must not be greater than 5000 characters. Example: opfuudtdsufvyvddqamni

AI Tarama — site konuşmalarını tara, eklenmemiş potansiyel müşterileri ÖNER (DB'ye yazmaz).

Mesaj İÇERİĞİ okur → messagingSiteIds gate (gizlilik kilidi). Maliyet AiCreditMeter (servis içinde).

Example request:
curl --request POST \
    "https://dowaba.com/api/leads/scan" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"days\": 13
}"
const url = new URL(
    "https://dowaba.com/api/leads/scan"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "days": 13
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads/scan';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'days' => 13,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/leads/scan

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Example: 17

days   integer  optional    

Must be at least 1. Must not be greater than 365. Example: 13

channels   object  optional    

Tek lead AI analizi + aşama önerisi. Mesaj İÇERİĞİ okur → messagingSiteIds gate.

Example request:
curl --request POST \
    "https://dowaba.com/api/leads/5/analyze"
const url = new URL(
    "https://dowaba.com/api/leads/5/analyze"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads/5/analyze';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/leads/{id}/analyze

URL Parameters

id   integer     

The ID of the lead. Example: 5

Sütun içi manuel sıralama: verilen sıradaki lead'lere 1.

.n position atar (scope: erişilebilir site). Yalnız aynı stage'in kartları gönderilir (frontend). Cross-tenant guard: site scope filtresi.

Example request:
curl --request POST \
    "https://dowaba.com/api/leads/reorder" \
    --header "Content-Type: application/json" \
    --data "{
    \"stage\": \"consequatur\",
    \"ordered_ids\": [
        17
    ]
}"
const url = new URL(
    "https://dowaba.com/api/leads/reorder"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "stage": "consequatur",
    "ordered_ids": [
        17
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads/reorder';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'stage' => 'consequatur',
            'ordered_ids' => [
                17,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/leads/reorder

Headers

Content-Type        

Example: application/json

Body Parameters

stage   string     

Example: consequatur

ordered_ids   integer[]  optional    

PATCH api/leads/{id}/stage

Example request:
curl --request PATCH \
    "https://dowaba.com/api/leads/5/stage" \
    --header "Content-Type: application/json" \
    --data "{
    \"stage\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/leads/5/stage"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "stage": "consequatur"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads/5/stage';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'stage' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/leads/{id}/stage

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the lead. Example: 5

Body Parameters

stage   string     

Example: consequatur

POST api/leads/{id}/assign

Example request:
curl --request POST \
    "https://dowaba.com/api/leads/5/assign" \
    --header "Content-Type: application/json" \
    --data "{
    \"assigned_user_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/leads/5/assign"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "assigned_user_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads/5/assign';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'assigned_user_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/leads/{id}/assign

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the lead. Example: 5

Body Parameters

assigned_user_id   integer  optional    

Example: 17

PATCH api/leads/{id}

Example request:
curl --request PATCH \
    "https://dowaba.com/api/leads/5" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"value\": 11613.31890586,
    \"notes\": \"opfuudtdsufvyvddqamni\",
    \"email\": \"damien.murazik@example.com\",
    \"phone\": \"oynlazghdtqtqxbajwbpi\",
    \"color\": \"lpmufinllwloauydl\"
}"
const url = new URL(
    "https://dowaba.com/api/leads/5"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "value": 11613.31890586,
    "notes": "opfuudtdsufvyvddqamni",
    "email": "damien.murazik@example.com",
    "phone": "oynlazghdtqtqxbajwbpi",
    "color": "lpmufinllwloauydl"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads/5';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'value' => 11613.31890586,
            'notes' => 'opfuudtdsufvyvddqamni',
            'email' => 'damien.murazik@example.com',
            'phone' => 'oynlazghdtqtqxbajwbpi',
            'color' => 'lpmufinllwloauydl',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/leads/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the lead. Example: 5

Body Parameters

name   string  optional    

Must not be greater than 200 characters. Example: vmqeopfuudtdsufvyvddq

value   number  optional    

Example: 11613.31890586

notes   string  optional    

Must not be greater than 5000 characters. Example: opfuudtdsufvyvddqamni

email   string  optional    

Must be a valid email address. Must not be greater than 191 characters. Example: damien.murazik@example.com

phone   string  optional    

Must not be greater than 32 characters. Example: oynlazghdtqtqxbajwbpi

color   string  optional    

Must not be greater than 20 characters. Example: lpmufinllwloauydl

DELETE api/leads/{id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/leads/5"
const url = new URL(
    "https://dowaba.com/api/leads/5"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/leads/5';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/leads/{id}

URL Parameters

id   integer     

The ID of the lead. Example: 5

GET api/lead-submissions

Example request:
curl --request GET \
    --get "https://dowaba.com/api/lead-submissions"
const url = new URL(
    "https://dowaba.com/api/lead-submissions"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/lead-submissions';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/lead-submissions

Bir site için lead atama seçenekleri: atanabilir takım üyeleri (atanmış lead yükleriyle) + otomatik dağıtım ayarının mevcut durumu.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/lead-submissions/assignment-options?site_id=5" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 73
}"
const url = new URL(
    "https://dowaba.com/api/lead-submissions/assignment-options"
);

const params = {
    "site_id": "5",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 73
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/lead-submissions/assignment-options';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'query' => [
            'site_id' => '5',
        ],
        'json' => [
            'site_id' => 73,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "auto_assign": false,
    "users": [
        {
            "id": 17,
            "name": "Ali Veli",
            "email": "a**@example.com",
            "role": "agent",
            "open_count": 3
        }
    ]
}
 

Request      

GET api/lead-submissions/assignment-options

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Query Parameters

site_id   integer     

Site ID. Example: 5

Body Parameters

site_id   integer     

Must be at least 1. Example: 73

Otomatik dağıtımı aç/kapat. Açıkken yeni gelen lead'ler sitenin takım üyeleri (agent) arasında en az lead atanmış olana otomatik atanır.

requires authentication

Example request:
curl --request PUT \
    "https://dowaba.com/api/lead-submissions/auto-assign" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 5,
    \"enabled\": true
}"
const url = new URL(
    "https://dowaba.com/api/lead-submissions/auto-assign"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 5,
    "enabled": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/lead-submissions/auto-assign';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 5,
            'enabled' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "auto_assign": true
}
 

Request      

PUT api/lead-submissions/auto-assign

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Site ID. Example: 5

enabled   boolean     

Otomatik dağıtım açık mı. Example: true

Bir lead form gönderimini takım üyesine ata (null = atamayı kaldır).

requires authentication

Atama sonrası atanana ÖNCELİKLİ bildirim gider (SMS varsa SMS, yoksa mail — NotificationDispatcher::dispatchLeadAssignment). Site'a bağlı olmayan (null-site) gönderimde takım olmadığından atama yapılamaz (422).

Example request:
curl --request POST \
    "https://dowaba.com/api/lead-submissions/12/assign" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"user_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/lead-submissions/12/assign"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "user_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/lead-submissions/12/assign';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'user_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "message": "Lead atandı",
    "assigned_user_id": 17,
    "assigned_user_name": "Ali Veli"
}
 

Request      

POST api/lead-submissions/{id}/assign

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

id   integer     

Lead form gönderim id'si. Example: 12

Body Parameters

user_id   integer  optional    

Atanacak takım üyesi (boş/null → atamayı kaldır). Example: 17

Bir lead form gönderimini SİL — Facebook'tan da kalıcı (DELETE /{leadgen_id}) + panelde tombstone.

requires authentication

Scope: index ile aynı (messagingSiteIds VEYA null-site+kendi sayfası) → cross-tenant silme engellenir. Facebook tarafı: sayfa sahibinin (sub.user_id) aktif FB sayfa profili token'ıyla denenir (best-effort). Meta silinmezse (sayfa kopuk) yine yerelde soft-delete → re-sync GERİ EKLEMEZ (tombstone). Bağlı CRM lead kartı da kaldırılır; Kişi + Rıza KORUNUR (Rehber'den ayrı + KVKK yasal kaydı).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/lead-submissions/12" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/lead-submissions/12"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/lead-submissions/12';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "meta_deleted": true,
    "message": "Lead panelden ve Facebook'tan silindi."
}
 

Request      

DELETE api/lead-submissions/{id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

id   integer     

Lead form gönderim id'si. Example: 12

Fonksiyon Gateway

Site için kullanılabilir fonksiyonları listele (her kayıt scope: global|override|site).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/functions"
const url = new URL(
    "https://dowaba.com/api/sites/1/functions"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/functions';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/functions

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Yeni site-specific fonksiyon yarat (type=http/sql/static).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/functions"
const url = new URL(
    "https://dowaba.com/api/sites/1/functions"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/functions';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/functions

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Global fonksiyonu site bazında özelleştir (override kopyası yarat).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/functions/1/override"
const url = new URL(
    "https://dowaba.com/api/sites/1/functions/1/override"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/functions/1/override';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/functions/{function_id}/override

URL Parameters

site_id   integer     

The ID of the site. Example: 1

function_id   integer     

The ID of the function. Example: 1

Site-specific fonksiyonu güncelle (global'ler için "override" kullan).

Example request:
curl --request PUT \
    "https://dowaba.com/api/functions/1"
const url = new URL(
    "https://dowaba.com/api/functions/1"
);



fetch(url, {
    method: "PUT",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/functions/1';
$response = $client->put($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/functions/{function_id}

URL Parameters

function_id   integer     

The ID of the function. Example: 1

Site-specific fonksiyonu güncelle (global'ler için "override" kullan).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/functions/1"
const url = new URL(
    "https://dowaba.com/api/functions/1"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/functions/1';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/functions/{function_id}

URL Parameters

function_id   integer     

The ID of the function. Example: 1

Fonksiyonu mock argümanlarla test et (panel "Test" butonu).

Example request:
curl --request POST \
    "https://dowaba.com/api/functions/1/test" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/functions/1/test"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/functions/1/test';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/functions/{function_id}/test

Headers

Content-Type        

Example: application/json

URL Parameters

function_id   integer     

The ID of the function. Example: 1

Body Parameters

site_id   integer     

The id of an existing record in the sites table. Example: 17

args   object  optional    

Fonksiyonu aktif/pasif yap (site-specific için).

Example request:
curl --request POST \
    "https://dowaba.com/api/functions/1/toggle"
const url = new URL(
    "https://dowaba.com/api/functions/1/toggle"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/functions/1/toggle';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/functions/{function_id}/toggle

URL Parameters

function_id   integer     

The ID of the function. Example: 1

Site-specific fonksiyonu sil (global'ler silinemez).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/functions/1"
const url = new URL(
    "https://dowaba.com/api/functions/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/functions/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/functions/{function_id}

URL Parameters

function_id   integer     

The ID of the function. Example: 1

Site bağlantılarını listele (HTTP API + DB).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/connections"
const url = new URL(
    "https://dowaba.com/api/sites/1/connections"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/connections';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/connections

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Yeni site bağlantısı oluştur (HTTP veya DB).

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/connections"
const url = new URL(
    "https://dowaba.com/api/sites/1/connections"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/connections';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/connections

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Site bağlantısını güncelle (maskelenmiş "***" alanlar korunur).

Example request:
curl --request PUT \
    "https://dowaba.com/api/connections/8"
const url = new URL(
    "https://dowaba.com/api/connections/8"
);



fetch(url, {
    method: "PUT",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8';
$response = $client->put($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/connections/{connection_id}

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

Site bağlantısını güncelle (maskelenmiş "***" alanlar korunur).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/connections/8"
const url = new URL(
    "https://dowaba.com/api/connections/8"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/connections/{connection_id}

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

Site bağlantısını sil (aktif fonksiyon kullanıyorsa engellenir).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/connections/8"
const url = new URL(
    "https://dowaba.com/api/connections/8"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/connections/{connection_id}

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

Bağlantıyı test et (HTTP için base_url, DB için SELECT 1).

Example request:
curl --request POST \
    "https://dowaba.com/api/connections/8/test"
const url = new URL(
    "https://dowaba.com/api/connections/8/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/connections/{connection_id}/test

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

DB bağlantısının tablolarını listele (AI Function Generator için).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/connections/8/tables"
const url = new URL(
    "https://dowaba.com/api/connections/8/tables"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8/tables';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/connections/{connection_id}/tables

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

DB tablosunun kolon detayını getir (AI schema context için).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/connections/8/tables/products/columns"
const url = new URL(
    "https://dowaba.com/api/connections/8/tables/products/columns"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8/tables/products/columns';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/connections/{connection_id}/tables/{table}/columns

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

table   string     

Kolonları listelenecek tablonun adı. Example: products

Seçilen DB tabloları için AI ile 2'şer fonksiyon (ara + detay) öner (preview only).

Example request:
curl --request POST \
    "https://dowaba.com/api/connections/8/generate-functions" \
    --header "Content-Type: application/json" \
    --data "{
    \"tables\": [
        \"vmqeopfuudtdsufvyvddq\"
    ],
    \"intent\": \"amniihfqcoynlazghdtqt\"
}"
const url = new URL(
    "https://dowaba.com/api/connections/8/generate-functions"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "tables": [
        "vmqeopfuudtdsufvyvddq"
    ],
    "intent": "amniihfqcoynlazghdtqt"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8/generate-functions';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'tables' => [
                'vmqeopfuudtdsufvyvddq',
            ],
            'intent' => 'amniihfqcoynlazghdtqt',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/connections/{connection_id}/generate-functions

Headers

Content-Type        

Example: application/json

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

Body Parameters

tables   string[]  optional    

Must not be greater than 128 characters.

intent   string  optional    

Must not be greater than 500 characters. Example: amniihfqcoynlazghdtqt

HTTP API için AI agentic loop ile fonksiyon üret (canlı endpoint testi + submit).

Example request:
curl --request POST \
    "https://dowaba.com/api/connections/8/generate-http-functions" \
    --header "Content-Type: application/json" \
    --data "{
    \"ai_prompt\": \"vmqeopfuudtdsufvyvddq\",
    \"provider\": \"claude\"
}"
const url = new URL(
    "https://dowaba.com/api/connections/8/generate-http-functions"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ai_prompt": "vmqeopfuudtdsufvyvddq",
    "provider": "claude"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/connections/8/generate-http-functions';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ai_prompt' => 'vmqeopfuudtdsufvyvddq',
            'provider' => 'claude',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/connections/{connection_id}/generate-http-functions

Headers

Content-Type        

Example: application/json

URL Parameters

connection_id   integer     

The ID of the connection. Example: 8

Body Parameters

ai_prompt   string     

Must be at least 10 characters. Must not be greater than 5000 characters. Example: vmqeopfuudtdsufvyvddq

provider   string  optional    

Example: claude

Must be one of:
  • claude
  • gemini

Reseller

Müşteri detayı + bu bayinin sattığı subscription/sites.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/customers/1"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/customers/{user_id}

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Bayi havuzu + müşteri allocate dağıtım bilgisi (modal'ın "kalan dağıtım" göstergesi için). 2026-05-22 tek havuz UI'sına özel endpoint.

Dönen pool: message: {limit, otherAllocated, currentAllocated, remaining} voice: {limit, otherAllocated, currentAllocated, remaining}

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/customers/1/pool-info"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/pool-info"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/pool-info';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/customers/{user_id}/pool-info

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Bayi müşterisinin profilini ve kullanım limitlerini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/reseller/customers/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Test Müşteri\",
    \"phone\": \"+90 555 *** ** **\",
    \"email\": \"customer@example.com\",
    \"is_active\": true,
    \"allowed_modules\": [
        \"wbpilpmufinllwloauydl\"
    ],
    \"allocated_ai_credit\": 18,
    \"allocated_voice_calls\": 12
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Test Müşteri",
    "phone": "+90 555 *** ** **",
    "email": "customer@example.com",
    "is_active": true,
    "allowed_modules": [
        "wbpilpmufinllwloauydl"
    ],
    "allocated_ai_credit": 18,
    "allocated_voice_calls": 12
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Test Müşteri',
            'phone' => '+90 555 *** ** **',
            'email' => 'customer@example.com',
            'is_active' => true,
            'allowed_modules' => [
                'wbpilpmufinllwloauydl',
            ],
            'allocated_ai_credit' => 18,
            'allocated_voice_calls' => 12,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/reseller/customers/{user_id}

Headers

Content-Type        

Example: application/json

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Body Parameters

name   string  optional    

Müşteri adı. Example: Test Müşteri

phone   string  optional    

Müşteri telefonu. Example: +90 555 *** ** **

email   string  optional    

Müşteri e-postası. Example: customer@example.com

is_active   boolean  optional    

Example: true

allowed_modules   string[]  optional    

Must not be greater than 30 characters.

allocated_ai_credit   integer  optional    

2026-05-22 Tek havuz: bayi müşterinin allocate'ini (mesaj+çağrı pay) ayarlayabilir. 0-bayi_havuzu arası. Aşağıda dağıtım toplamı bayinin havuzunu aşamayacak şekilde validate edilir. Must be at least 0. Must not be greater than 10000000. Example: 18

allocated_voice_calls   integer  optional    

Must be at least 0. Must not be greater than 1000000. Example: 12

Müşteri sil — cascade ile tüm siteleri ve subscription'ları silinir. GERİ ALINAMAZ — frontend'de double confirmation gerekli.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/reseller/customers/1"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/reseller/customers/{user_id}

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Bayi-müşteri İLİŞKİSİNİ KOPAR (soft) — müşteri silinmez, bağımsız owner'a dönüşür. `destroy` ile karıştırma: bu endpoint cascade silmez, müşterinin tüm site / lisans / konuşma / FAQ verilerini KORUR. Sadece `users.reseller_id = NULL` set eder + bayi havuzundan müşteri payını çıkarır.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers/1/detach" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/detach"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/detach';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "message": "Müşteri ile ilişkiniz başarıyla koparıldı. Müşteri bağımsız owner'a dönüştü.",
    "sold_subs_count": 2,
    "ai_deducted": 100000,
    "voice_deducted": 200
}
 

Example response (403):


{
    "success": false,
    "error": "Bayi sözleşmesi imzalanmamış."
}
 

Example response (404):


{
    "success": false,
    "error": "Müşteri bulunamadı veya size ait değil."
}
 

Request      

POST api/reseller/customers/{user_id}/detach

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers/1/send-password-link"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/send-password-link"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/send-password-link';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers/1/login-link"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/login-link"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/login-link';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "url": "https://dowaba.com/admin/impersonate?token=...",
    "expires_at": "2026-06-16T12:05:00+00:00",
    "expires_in_seconds": 300,
    "target": {
        "id": 13,
        "name": "...",
        "email": "..."
    }
}
 

Example response (404):


{
    "message": "Müşteri bulunamadı veya size ait değil."
}
 

Example response (422):


{
    "success": false,
    "message": "Pasif (askıdaki) müşteri için giriş linki üretilemez."
}
 

Bayi & Lisans

Bayi, müşterisine site açar — aynı anda 1 yıllık lisans (3.999₺) borç doğar.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers/1/sites" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Test Markası\",
    \"widget_color\": \"#4f46e5\",
    \"widget_position\": \"bottom-right\",
    \"welcome_message\": \"Merhaba, size nasıl yardımcı olabilirim?\",
    \"bot_name\": \"Asistan\",
    \"ai_enabled\": true,
    \"similarity_threshold\": 0.75
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/sites"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Test Markası",
    "widget_color": "#4f46e5",
    "widget_position": "bottom-right",
    "welcome_message": "Merhaba, size nasıl yardımcı olabilirim?",
    "bot_name": "Asistan",
    "ai_enabled": true,
    "similarity_threshold": 0.75
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/sites';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Test Markası',
            'widget_color' => '#4f46e5',
            'widget_position' => 'bottom-right',
            'welcome_message' => 'Merhaba, size nasıl yardımcı olabilirim?',
            'bot_name' => 'Asistan',
            'ai_enabled' => true,
            'similarity_threshold' => 0.75,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/customers/{user_id}/sites

Headers

Content-Type        

Example: application/json

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Body Parameters

name   string     

Site adı. Example: Test Markası

widget_color   string  optional    

Widget rengi (hex). Example: #4f46e5

widget_position   string  optional    

Widget konumu (bottom-right/bottom-left). Example: bottom-right

welcome_message   string  optional    

Karşılama mesajı. Example: Merhaba, size nasıl yardımcı olabilirim?

bot_name   string  optional    

Bot adı. Example: Asistan

ai_enabled   boolean  optional    

AI cevap aktif/pasif. Example: true

similarity_threshold   number  optional    

RAG benzerlik eşiği (0-1). Example: 0.75

Müşteriden siteyi GERİ AL — site bayinin elinde kalır, başka müşteriye atayabilir veya tamamen silebilir. Subscription bayiye swap edilir (sold_by_reseller_id null → gift havuzunda).

requires authentication

Example request:
curl --request DELETE \
    "https://dowaba.com/api/reseller/customers/1/sites/1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/sites/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/sites/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/reseller/customers/{user_id}/sites/{site_id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

user_id   integer     

The ID of the user. Example: 1

site_id   integer     

The ID of the site. Example: 1

Bayi - Telefon

Bir SIP trunk'a yönlendirilmiş DID route'larını listele.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/phone-routes?sip_trunk_id=17" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"sip_trunk_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/reseller/phone-routes"
);

const params = {
    "sip_trunk_id": "17",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sip_trunk_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/phone-routes';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'query' => [
            'sip_trunk_id' => '17',
        ],
        'json' => [
            'sip_trunk_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/phone-routes

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Query Parameters

sip_trunk_id   integer     

Hangi trunk'ın route'larını döndür. Example: 17

Body Parameters

sip_trunk_id   integer     

The id of an existing record in the sip_trunks table. Example: 17

Yeni DID route ekle (trunk'a yönlendirilmiş ekstra numara).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/phone-routes" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"sip_trunk_id\": 5,
    \"phone_number\": \"5000000001\",
    \"site_id\": 70,
    \"label\": \"PiSchool ana hat\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/reseller/phone-routes"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sip_trunk_id": 5,
    "phone_number": "5000000001",
    "site_id": 70,
    "label": "PiSchool ana hat",
    "is_active": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/phone-routes';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sip_trunk_id' => 5,
            'phone_number' => '5000000001',
            'site_id' => 70,
            'label' => 'PiSchool ana hat',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/phone-routes

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

sip_trunk_id   integer     

Parent SIP trunk ID. Example: 5

phone_number   string     

10 haneli DID numarası. Example: 5000000001

site_id   integer     

Müşteri sitesi ID. Example: 70

label   string  optional    

Açıklama etiketi. Example: PiSchool ana hat

is_active   boolean  optional    

Aktif mi. Example: false

DID route güncelle (site değiştirme, aktif/pasif toggle, label). phone_number ve sip_trunk_id değişikliğine izin yok — yeni route ekle.

requires authentication

Example request:
curl --request PUT \
    "https://dowaba.com/api/reseller/phone-routes/1" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"label\": \"mqeopfuudtdsufvyvddqa\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/reseller/phone-routes/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "label": "mqeopfuudtdsufvyvddqa",
    "is_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/phone-routes/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'label' => 'mqeopfuudtdsufvyvddqa',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/reseller/phone-routes/{phoneRoute_id}

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

phoneRoute_id   integer     

The ID of the phoneRoute. Example: 1

Body Parameters

site_id   integer  optional    

The id of an existing record in the sites table. Example: 17

label   string  optional    

Must not be greater than 80 characters. Example: mqeopfuudtdsufvyvddqa

is_active   boolean  optional    

Example: false

DID route sil.

requires authentication

Example request:
curl --request DELETE \
    "https://dowaba.com/api/reseller/phone-routes/1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/reseller/phone-routes/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/phone-routes/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/reseller/phone-routes/{phoneRoute_id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

phoneRoute_id   integer     

The ID of the phoneRoute. Example: 1

Bayinin müşteri sitelerini dropdown için döner (DID → site seçimi). `User::accessibleSiteIds()` cascade — kendi siteleri + müşterilerinin siteleri.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/customer-sites" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/reseller/customer-sites"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customer-sites';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/customer-sites

Headers

Authorization        

Example: Bearer {TOKEN}

Bayi — Müşteriler

Telefon + e-posta uygunluk ön-kontrolü (form on-blur). Kayıt YARATMAZ; her alan için {valid, available, severity, message} döner. store ile aynı tekillik mantığı.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers/check" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"+905551234567\",
    \"email\": \"qkunze@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/check"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "+905551234567",
    "email": "qkunze@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/check';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => '+905551234567',
            'email' => 'qkunze@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/customers/check

Headers

Content-Type        

Example: application/json

Body Parameters

phone   string  optional    

Kontrol edilecek telefon. Example: +905551234567

email   string  optional    

Kontrol edilecek e-posta. Example: qkunze@example.com

Bayi — Cari Hesap

Müşterinin cari hesabını getir: özet (currency başına) + borçlar (taksitlerle) + ödemeler.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/customers/1/billing"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/billing"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/billing';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/customers/{user_id}/billing

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Yeni borç oluştur + otomatik taksit üret.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers/1/billing/invoices" \
    --header "Content-Type: application/json" \
    --data "{
    \"title\": \"WhatsApp Lisansı 2026\",
    \"total_amount\": 12000,
    \"currency\": \"TRY\",
    \"installment_count\": 6,
    \"issued_at\": \"2026-05-28\",
    \"first_due_at\": \"2026-06-28\",
    \"interval_days\": 30,
    \"description\": \"Yıllık lisans yenileme bedeli\"
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/billing/invoices"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "WhatsApp Lisansı 2026",
    "total_amount": 12000,
    "currency": "TRY",
    "installment_count": 6,
    "issued_at": "2026-05-28",
    "first_due_at": "2026-06-28",
    "interval_days": 30,
    "description": "Yıllık lisans yenileme bedeli"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/billing/invoices';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'title' => 'WhatsApp Lisansı 2026',
            'total_amount' => 12000.0,
            'currency' => 'TRY',
            'installment_count' => 6,
            'issued_at' => '2026-05-28',
            'first_due_at' => '2026-06-28',
            'interval_days' => 30,
            'description' => 'Yıllık lisans yenileme bedeli',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/customers/{user_id}/billing/invoices

Headers

Content-Type        

Example: application/json

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Body Parameters

title   string     

Borç başlığı. Example: WhatsApp Lisansı 2026

total_amount   number     

Toplam tutar (pozitif). Example: 12000

currency   string  optional    

İSO kodu (TRY/USD/EUR/GBP). Example: TRY

installment_count   integer  optional    

1-60. Example: 6

issued_at   date  optional    

Borç tarihi. Example: 2026-05-28

first_due_at   date  optional    

İlk taksit vadesi. Example: 2026-06-28

interval_days   integer  optional    

Taksitler arası gün (default 30). Example: 30

description   string  optional    

Açıklama. Example: Yıllık lisans yenileme bedeli

meta   object  optional    

Manuel ödeme ekle. FIFO otomatik veya manual_allocations ile spesifik taksitlere yaz.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers/1/billing/payments" \
    --header "Content-Type: application/json" \
    --data "{
    \"amount\": 2000,
    \"currency\": \"TRY\",
    \"method\": \"wire\",
    \"paid_at\": \"2026-06-15\",
    \"reference\": \"DKT-2026-0042\",
    \"note\": \"Havale ile tahsil edildi\",
    \"manual_allocations\": []
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers/1/billing/payments"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "amount": 2000,
    "currency": "TRY",
    "method": "wire",
    "paid_at": "2026-06-15",
    "reference": "DKT-2026-0042",
    "note": "Havale ile tahsil edildi",
    "manual_allocations": []
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers/1/billing/payments';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'amount' => 2000.0,
            'currency' => 'TRY',
            'method' => 'wire',
            'paid_at' => '2026-06-15',
            'reference' => 'DKT-2026-0042',
            'note' => 'Havale ile tahsil edildi',
            'manual_allocations' => [],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/customers/{user_id}/billing/payments

Headers

Content-Type        

Example: application/json

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Body Parameters

amount   number     

Pozitif: tahsilat, negatif: iade. Example: 2000

currency   string     

TRY/USD/EUR/GBP. Example: TRY

method   string  optional    

Ödeme yöntemi. Example: wire

paid_at   datetime  optional    

Ödeme tarihi. Example: 2026-06-15

reference   string  optional    

Dekont no. Example: DKT-2026-0042

note   string  optional    

Bayi notu. Example: Havale ile tahsil edildi

manual_allocations   object  optional    

[installment_id => applied_amount] manuel dağıtım.

Borç başlığı/açıklama/issued_at/total_amount/meta güncelle. total_amount değişikliği sadece tüm taksitler 0 paid_amount ise serbest; ödeme alındıysa "yeniden hesapla" akışı (regenerate endpoint) kullanılmalı.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/customer-invoices/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"title\": \"vmqeopfuudtdsufvyvddq\",
    \"description\": \"Yıllık lisans yenileme bedeli\",
    \"issued_at\": \"2026-07-09T20:55:57\",
    \"total_amount\": 11613.31890586
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customer-invoices/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "title": "vmqeopfuudtdsufvyvddq",
    "description": "Yıllık lisans yenileme bedeli",
    "issued_at": "2026-07-09T20:55:57",
    "total_amount": 11613.31890586
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customer-invoices/1';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'title' => 'vmqeopfuudtdsufvyvddq',
            'description' => 'Yıllık lisans yenileme bedeli',
            'issued_at' => '2026-07-09T20:55:57',
            'total_amount' => 11613.31890586,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/customer-invoices/{invoice_id}

Headers

Content-Type        

Example: application/json

URL Parameters

invoice_id   integer     

The ID of the invoice. Example: 1

Body Parameters

title   string  optional    

Must not be greater than 200 characters. Example: vmqeopfuudtdsufvyvddq

description   string  optional    

Borç açıklaması. Example: Yıllık lisans yenileme bedeli

issued_at   string  optional    

Must be a valid date. Example: 2026-07-09T20:55:57

total_amount   number  optional    

Example: 11613.31890586

meta   object  optional    

Borç iptal et — status=cancelled, taksitler de cancelled. Ödemeler korunur (audit).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/reseller/customer-invoices/1"
const url = new URL(
    "https://dowaba.com/api/reseller/customer-invoices/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customer-invoices/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/reseller/customer-invoices/{invoice_id}

URL Parameters

invoice_id   integer     

The ID of the invoice. Example: 1

Kalan tutarı yeni N taksite eşit böl. Ödenmiş taksitler korunur. Bayi UI'da "Yeniden Hesapla" butonu.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customer-invoices/1/regenerate" \
    --header "Content-Type: application/json" \
    --data "{
    \"installment_count\": 21,
    \"first_due_at\": \"2026-07-09T20:55:57\",
    \"interval_days\": 13
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customer-invoices/1/regenerate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "installment_count": 21,
    "first_due_at": "2026-07-09T20:55:57",
    "interval_days": 13
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customer-invoices/1/regenerate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'installment_count' => 21,
            'first_due_at' => '2026-07-09T20:55:57',
            'interval_days' => 13,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/customer-invoices/{invoice_id}/regenerate

Headers

Content-Type        

Example: application/json

URL Parameters

invoice_id   integer     

The ID of the invoice. Example: 1

Body Parameters

installment_count   integer     

Must be at least 1. Must not be greater than 60. Example: 21

first_due_at   string     

Must be a valid date. Example: 2026-07-09T20:55:57

interval_days   integer  optional    

Must be at least 1. Must not be greater than 365. Example: 13

Tek taksit alanlarını güncelle (vade/tutar/not). amount değişimi paid_amount altına düşemez.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/customer-installments/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"due_date\": \"2026-07-09T20:55:57\",
    \"amount\": 11613.31890586,
    \"note\": \"opfuudtdsufvyvddqamni\",
    \"reset_reminder\": false
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customer-installments/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "due_date": "2026-07-09T20:55:57",
    "amount": 11613.31890586,
    "note": "opfuudtdsufvyvddqamni",
    "reset_reminder": false
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customer-installments/1';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'due_date' => '2026-07-09T20:55:57',
            'amount' => 11613.31890586,
            'note' => 'opfuudtdsufvyvddqamni',
            'reset_reminder' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/customer-installments/{installment_id}

Headers

Content-Type        

Example: application/json

URL Parameters

installment_id   integer     

The ID of the installment. Example: 1

Body Parameters

due_date   string  optional    

Must be a valid date. Example: 2026-07-09T20:55:57

amount   number  optional    

Example: 11613.31890586

note   string  optional    

Must not be greater than 1000 characters. Example: opfuudtdsufvyvddqamni

reset_reminder   boolean  optional    

Example: false

Bu taksit elden ödendi → kalan tutar için sentetik CustomerPayment + allocation.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customer-installments/1/mark-paid" \
    --header "Content-Type: application/json" \
    --data "{
    \"method\": \"cash\",
    \"note\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customer-installments/1/mark-paid"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "method": "cash",
    "note": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customer-installments/1/mark-paid';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'method' => 'cash',
            'note' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/customer-installments/{installment_id}/mark-paid

Headers

Content-Type        

Example: application/json

URL Parameters

installment_id   integer     

The ID of the installment. Example: 1

Body Parameters

method   string  optional    

Ödeme yöntemi (cash/wire/card/crypto/other, default cash). Example: cash

note   string  optional    

Must not be greater than 500 characters. Example: mqeopfuudtdsufvyvddqa

Ödeme kaydını sil — applied'i taksitlerden geri çek, invoice status'ünü güncelle.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/reseller/customer-payments/2"
const url = new URL(
    "https://dowaba.com/api/reseller/customer-payments/2"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customer-payments/2';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/reseller/customer-payments/{payment_id}

URL Parameters

payment_id   integer     

The ID of the payment. Example: 2

Bayi hatırlatma config'ini güncelle (kaç gün önce, hangi kanal).

Example request:
curl --request PUT \
    "https://dowaba.com/api/reseller/billing/reminder-settings" \
    --header "Content-Type: application/json" \
    --data "{
    \"days_before\": 21,
    \"channel\": \"mail\"
}"
const url = new URL(
    "https://dowaba.com/api/reseller/billing/reminder-settings"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "days_before": 21,
    "channel": "mail"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/billing/reminder-settings';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'days_before' => 21,
            'channel' => 'mail',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/reseller/billing/reminder-settings

Headers

Content-Type        

Example: application/json

Body Parameters

days_before   integer  optional    

Must be at least 0. Must not be greater than 30. Example: 21

channel   string     

Hatırlatma kanalı (none/sms/mail/both). Example: mail

Bayi — Faturalandırma

Paraşüt faturasının PDF'ini indir. PDF cron tarafından JuiceFS'e çekilmiş olmalı. Hazır değilse 404 + "İşleniyor" mesajı. Auth: subscription.sold_by_reseller_id = bayi.id zorunlu (ownership).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/invoices/1/parasut-pdf"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices/1/parasut-pdf"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices/1/parasut-pdf';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/invoices/{subscription_id}/parasut-pdf

URL Parameters

subscription_id   integer     

The ID of the subscription. Example: 1

Bayi Duyuruları

Bayi (role=reseller) kendi duyurularını okur + okundu işaretler. Yayınlama superadmin'de (Api\Admin\ResellerAnnouncementController). İç alanlar (created_by, draft) DIŞA SIZMAZ — sadece yayınlanmış duyurular + bu bayinin okuma durumu döner.

Yayınlanmış duyurular + bu bayinin okuma durumu (is_read) + unread_count.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/announcements"
const url = new URL(
    "https://dowaba.com/api/reseller/announcements"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/announcements';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/announcements

Dashboard rozeti + header banner'ı için hafif okunmamış özeti.

latest_unread: en yeni okunmamış duyuru (pinned öncelikli) — panel header'ındaki duyuru şeridi bunu gösterir, tıklayınca duyurular sayfasına gider (2026-06-11). Body dönmez (hafif kalsın).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/announcements/unread-count"
const url = new URL(
    "https://dowaba.com/api/reseller/announcements/unread-count"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/announcements/unread-count';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "unread_count": 2,
    "latest_unread": {
        "id": 7,
        "title": "Yeni özellik",
        "type": "feature",
        "published_at": "2026-06-11T10:00:00+03:00"
    }
}
 

Request      

GET api/reseller/announcements/unread-count

Tümünü okundu işaretle.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/announcements/read-all"
const url = new URL(
    "https://dowaba.com/api/reseller/announcements/read-all"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/announcements/read-all';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/announcements/read-all

Tek duyuruyu okundu işaretle (sadece yayınlanmış).

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/announcements/1562/read"
const url = new URL(
    "https://dowaba.com/api/reseller/announcements/1562/read"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/announcements/1562/read';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/announcements/{id}/read

URL Parameters

id   string     

The ID of the announcement. Example: 1562

Bayi Referans Ayarları

Bayi (role=reseller) kendi landing "Çözüm Ortaklarımız" referans tercihini yönetir. KVKK: enabled için açık rıza (consent) ZORUNLU; kapatınca rıza geri çekilir (consent_at=null). Logo/marka adı bayinin branding'inden (Reseller/BrandingController) gelir — burada saklanmaz.

Bayinin mevcut referans tercihi + branding önizleme (logo/ad/renk).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/reference"
const url = new URL(
    "https://dowaba.com/api/reseller/reference"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/reference';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/reference

Tercihi güncelle. enabled=true → açık rıza (consent) şart.

Example request:
curl --request PUT \
    "https://dowaba.com/api/reseller/reference" \
    --header "Content-Type: application/json" \
    --data "{
    \"enabled\": true,
    \"show_logo\": false,
    \"show_website\": false,
    \"website\": \"vmqeopfuudtdsufvyvddq\",
    \"show_contact\": true,
    \"contact_email\": \"kunde.eloisa@example.com\",
    \"contact_phone\": \"hfqcoynlazghdtqtqxbaj\",
    \"show_tagline\": true,
    \"tagline\": \"wbpilpmufinllwloauydl\",
    \"sector\": \"smsjuryvojcybzvrbyick\",
    \"consent\": false
}"
const url = new URL(
    "https://dowaba.com/api/reseller/reference"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "enabled": true,
    "show_logo": false,
    "show_website": false,
    "website": "vmqeopfuudtdsufvyvddq",
    "show_contact": true,
    "contact_email": "kunde.eloisa@example.com",
    "contact_phone": "hfqcoynlazghdtqtqxbaj",
    "show_tagline": true,
    "tagline": "wbpilpmufinllwloauydl",
    "sector": "smsjuryvojcybzvrbyick",
    "consent": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/reference';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'enabled' => true,
            'show_logo' => false,
            'show_website' => false,
            'website' => 'vmqeopfuudtdsufvyvddq',
            'show_contact' => true,
            'contact_email' => 'kunde.eloisa@example.com',
            'contact_phone' => 'hfqcoynlazghdtqtqxbaj',
            'show_tagline' => true,
            'tagline' => 'wbpilpmufinllwloauydl',
            'sector' => 'smsjuryvojcybzvrbyick',
            'consent' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/reseller/reference

Headers

Content-Type        

Example: application/json

Body Parameters

enabled   boolean     

Example: true

show_logo   boolean  optional    

Example: false

show_website   boolean  optional    

Example: false

website   string  optional    

Must be a valid URL. Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

show_contact   boolean  optional    

Example: true

contact_email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: kunde.eloisa@example.com

contact_phone   string  optional    

Must not be greater than 40 characters. Example: hfqcoynlazghdtqtqxbaj

show_tagline   boolean  optional    

Example: true

tagline   string  optional    

Must not be greater than 160 characters. Example: wbpilpmufinllwloauydl

sector   string  optional    

Must not be greater than 80 characters. Example: smsjuryvojcybzvrbyick

consent   boolean  optional    

Example: false

Yasal & Onay

Example request:
curl --request GET \
    --get "https://dowaba.com/api/legal-documents"
const url = new URL(
    "https://dowaba.com/api/legal-documents"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/legal-documents';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Example request:
curl --request GET \
    --get "https://dowaba.com/api/legal-documents/euwi22"
const url = new URL(
    "https://dowaba.com/api/legal-documents/euwi22"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/legal-documents/euwi22';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Example request:
curl --request POST \
    "https://dowaba.com/api/legal-documents/euwi22/accept" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/legal-documents/euwi22/accept"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/legal-documents/euwi22/accept';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

İYS (İleti Yönetim Sistemi)

İYS hizmet sağlayıcı API hesabı (credential) yönetimi (iys-entegrasyon.md § 5).

Model: HS = MÜŞTERİ (tüzel kişi). Kullanıcı kendi İYS hesabını kendi açar (MERSİS + marka tescili), "API Test Hesabı"ndan ürettiği iysCode + brandCode + kullanıcı adı + şifreyi buraya girer. Şifre/kullanıcı adı Laravel 'encrypted' cast ile şifreli saklanır ve JSON'a ASLA dönmez ($hidden) — sadece has_credentials özeti döner.

Yetki: kullanıcı yalnızca yönetebildiği kullanıcıların (managedUserIds — self + bayi müşterileri) İYS hesaplarını görür/yönetir.

İYS hesaplarını listele

Yönetebildiğin kullanıcıların İYS API hesaplarını döndürür. Credential'lar maskelidir (kullanıcı adı maskeli, şifre asla dönmez).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/iys/accounts"
const url = new URL(
    "https://dowaba.com/api/iys/accounts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/accounts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "iys_code": "123456",
            "brand_code": "7890",
            "label": "Ana marka",
            "environment": "production",
            "is_active": true,
            "has_credentials": true,
            "masked_username": "ab••••yz"
        }
    ]
}
 

Request      

GET api/iys/accounts

İYS hesabı ekle

İYS "API Test/Üretim Hesabı"ndan alınan credential'ı kaydeder. Kullanıcı adı + şifre şifreli saklanır, yanıtta asla açık dönmez. (iys_code + brand_code) tekildir.

Example request:
curl --request POST \
    "https://dowaba.com/api/iys/accounts" \
    --header "Content-Type: application/json" \
    --data "{
    \"iys_code\": \"123456\",
    \"brand_code\": \"7890\",
    \"label\": \"Ana marka\",
    \"iys_username\": \"api_user\",
    \"iys_password\": null,
    \"environment\": \"production\"
}"
const url = new URL(
    "https://dowaba.com/api/iys/accounts"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "iys_code": "123456",
    "brand_code": "7890",
    "label": "Ana marka",
    "iys_username": "api_user",
    "iys_password": null,
    "environment": "production"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/accounts';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'iys_code' => '123456',
            'brand_code' => '7890',
            'label' => 'Ana marka',
            'iys_username' => 'api_user',
            'iys_password' => null,
            'environment' => 'production',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "success": true,
    "data": {
        "id": 1,
        "iys_code": "123456",
        "brand_code": "7890",
        "has_credentials": true
    }
}
 

Example response (422):


{
    "error": "Bu İYS kodu + marka kodu zaten ekli."
}
 

Request      

POST api/iys/accounts

Headers

Content-Type        

Example: application/json

Body Parameters

iys_code   string     

İYS kodu (path 1. segment). Example: 123456

brand_code   string     

Marka kodu (path 2. segment). Example: 7890

label   string  optional    

Etiket (opsiyonel). Example: Ana marka

iys_username   string     

İYS API kullanıcı adı. Example: api_user

iys_password   string     

İYS API şifresi.

environment   string  optional    

Ortam: sandbox veya production (varsayılan production). Example: production

İYS hesabını güncelle

Etiket/kod/credential/durum günceller. Boş gelen credential alanları korunur (write-only). Credential değişirse token cache temizlenir.

Example request:
curl --request PUT \
    "https://dowaba.com/api/iys/accounts/1" \
    --header "Content-Type: application/json" \
    --data "{
    \"label\": \"Ana marka\",
    \"iys_code\": \"123456\",
    \"brand_code\": \"7890\",
    \"iys_username\": \"api_user\",
    \"environment\": \"production\",
    \"is_active\": true
}"
const url = new URL(
    "https://dowaba.com/api/iys/accounts/1"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "label": "Ana marka",
    "iys_code": "123456",
    "brand_code": "7890",
    "iys_username": "api_user",
    "environment": "production",
    "is_active": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/accounts/1';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'label' => 'Ana marka',
            'iys_code' => '123456',
            'brand_code' => '7890',
            'iys_username' => 'api_user',
            'environment' => 'production',
            'is_active' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "data": {
        "id": 1,
        "is_active": true
    }
}
 

Example response (404):


{
    "error": "Hesap bulunamadı."
}
 

Request      

PUT api/iys/accounts/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

İYS hesabı id. Example: 1

Body Parameters

label   string  optional    

Etiket. Example: Ana marka

iys_code   string  optional    

İYS kodu. Example: 123456

brand_code   string  optional    

Marka kodu. Example: 7890

iys_username   string  optional    

Yeni kullanıcı adı (boşsa korunur). Example: api_user

iys_password   string  optional    

Yeni şifre (boşsa korunur).

environment   string  optional    

sandbox | production. Example: production

is_active   boolean  optional    

Aktif/pasif. Example: true

İYS hesabını sil

Bağlı siteler otomatik çözülür (sites.iys_account_id null'a çekilir).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/iys/accounts/1"
const url = new URL(
    "https://dowaba.com/api/iys/accounts/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/accounts/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true
}
 

Example response (404):


{
    "error": "Hesap bulunamadı."
}
 

Request      

DELETE api/iys/accounts/{id}

URL Parameters

id   integer     

İYS hesabı id. Example: 1

Pazarlama onaylarını listele

Erişebildiğin site'ların son-alıcı onay kayıtlarını + İYS yükleme durumlarını sayfalı döndürür.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/iys/consents?site_id=12&type=MESAJ&status=ONAY&sync_status=pending&search=90555&per_page=50"
const url = new URL(
    "https://dowaba.com/api/iys/consents"
);

const params = {
    "site_id": "12",
    "type": "MESAJ",
    "status": "ONAY",
    "sync_status": "pending",
    "search": "90555",
    "per_page": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/consents';
$response = $client->get(
    $url,
    [
        'query' => [
            'site_id' => '12',
            'type' => 'MESAJ',
            'status' => 'ONAY',
            'sync_status' => 'pending',
            'search' => '90555',
            'per_page' => '50',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "site_id": 12,
            "recipient": "+905551112233",
            "type": "MESAJ",
            "status": "ONAY",
            "iys_sync_status": "pending"
        }
    ],
    "total": 1,
    "current_page": 1,
    "last_page": 1
}
 

Request      

GET api/iys/consents

Query Parameters

site_id   integer  optional    

Belirli siteye filtrele. Example: 12

type   string  optional    

İYS tipi: MESAJ, EPOSTA veya ARAMA. Example: MESAJ

status   string  optional    

ONAY veya RET. Example: ONAY

sync_status   string  optional    

İYS senkron durumu (pending|queued|synced|failed|not_required). Example: pending

search   string  optional    

Alıcı (telefon/e-posta) içinde ara. Example: 90555

per_page   integer  optional    

Sayfa boyutu (max 100). Example: 50

Onay senkron durumu özeti

Site bazlı İYS sync durumu sayaçları (UI rozet/sayaç için).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/iys/consents/summary?site_id=12"
const url = new URL(
    "https://dowaba.com/api/iys/consents/summary"
);

const params = {
    "site_id": "12",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/consents/summary';
$response = $client->get(
    $url,
    [
        'query' => [
            'site_id' => '12',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "stub_mode": true,
    "counts": {
        "pending": 5,
        "synced": 12
    }
}
 

Request      

GET api/iys/consents/summary

Query Parameters

site_id   integer  optional    

Belirli siteye filtrele. Example: 12

Onay meta verileri (enum listeleri)

Onay kaynağı kodları + İYS tipleri + alıcı tipleri — UI dropdown'larını ve geçerli source/type/recipient_type değerlerini beslemek için.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/iys/consents/meta"
const url = new URL(
    "https://dowaba.com/api/iys/consents/meta"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/consents/meta';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "sources": [
        "HS_WEB",
        "HS_FIZIKSEL_ORTAM",
        "HS_MESAJ"
    ],
    "types": [
        "MESAJ",
        "EPOSTA",
        "ARAMA"
    ],
    "recipient_types": [
        "BIREYSEL",
        "TACIR"
    ],
    "stub_mode": true
}
 

Request      

GET api/iys/consents/meta

Tekil onay kaydı ekle

Bir alıcının pazarlama onayını (veya reddini) kaydeder. consent_confirmed ile "elimde bu onay var" beyanı zorunludur (delil zinciri). cron (iys:upload-pending) 'pending' kayıtları İYS'ye yükler (3 iş günü kuralı).

Example request:
curl --request POST \
    "https://dowaba.com/api/iys/consents" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 12,
    \"recipient\": \"+905551112233\",
    \"type\": \"MESAJ\",
    \"status\": \"ONAY\",
    \"source\": \"HS_WEB\",
    \"recipient_type\": \"BIREYSEL\",
    \"consent_date\": \"2026-06-01 10:00:00\",
    \"consent_confirmed\": true
}"
const url = new URL(
    "https://dowaba.com/api/iys/consents"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 12,
    "recipient": "+905551112233",
    "type": "MESAJ",
    "status": "ONAY",
    "source": "HS_WEB",
    "recipient_type": "BIREYSEL",
    "consent_date": "2026-06-01 10:00:00",
    "consent_confirmed": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/consents';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 12,
            'recipient' => '+905551112233',
            'type' => 'MESAJ',
            'status' => 'ONAY',
            'source' => 'HS_WEB',
            'recipient_type' => 'BIREYSEL',
            'consent_date' => '2026-06-01 10:00:00',
            'consent_confirmed' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "success": true,
    "data": {
        "id": 1,
        "recipient": "+905551112233",
        "type": "MESAJ",
        "status": "ONAY",
        "iys_sync_status": "pending"
    }
}
 

Example response (403):


{
    "error": "Bu siteye erişiminiz yok."
}
 

Example response (422):


{
    "error": "Geçersiz alıcı (telefon/e-posta formatı)."
}
 

Request      

POST api/iys/consents

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Erişebildiğin site. Example: 12

recipient   string     

Telefon (MESAJ/ARAMA, E.164) veya e-posta (EPOSTA). Example: +905551112233

type   string     

İYS tipi: MESAJ, EPOSTA veya ARAMA. Example: MESAJ

status   string  optional    

Onay durumu: ONAY veya RET (varsayılan ONAY). Example: ONAY

source   string     

İzin kaynağı kodu (geçerli değerler /iys/consents/meta'da). Example: HS_WEB

recipient_type   string  optional    

Alıcı tipi: BIREYSEL veya TACIR. Example: BIREYSEL

consent_date   string  optional    

İznin alındığı gerçek an (gelecek tarih reddedilir). Example: 2026-06-01 10:00:00

consent_confirmed   boolean     

Onayın gerçekliği beyanı (true olmalı). Example: true

Kişi grubuna toplu onay beyanı

Bir contact group için toplu onay beyanı → grup içi her contact'ın telefonu (MESAJ)

Example request:
curl --request POST \
    "https://dowaba.com/api/iys/consents/attest-group" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 12,
    \"contact_group_id\": 5,
    \"source\": \"HS_WEB\",
    \"recipient_type\": \"BIREYSEL\",
    \"consent_date\": \"2026-06-01 10:00:00\",
    \"consent_confirmed\": true
}"
const url = new URL(
    "https://dowaba.com/api/iys/consents/attest-group"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 12,
    "contact_group_id": 5,
    "source": "HS_WEB",
    "recipient_type": "BIREYSEL",
    "consent_date": "2026-06-01 10:00:00",
    "consent_confirmed": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/consents/attest-group';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 12,
            'contact_group_id' => 5,
            'source' => 'HS_WEB',
            'recipient_type' => 'BIREYSEL',
            'consent_date' => '2026-06-01 10:00:00',
            'consent_confirmed' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "success": true,
    "result": {
        "created": 24,
        "skipped": 2
    }
}
 

Example response (403):


{
    "error": "Bu siteye erişiminiz yok."
}
 

Example response (404):


{
    "error": "Kişi grubu bulunamadı."
}
 

Request      

POST api/iys/consents/attest-group

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Erişebildiğin site. Example: 12

contact_group_id   integer     

Onayı beyan edilen kişi grubu. Example: 5

source   string     

İzin kaynağı kodu (geçerli değerler /iys/consents/meta'da). Example: HS_WEB

recipient_type   string  optional    

Alıcı tipi: BIREYSEL veya TACIR. Example: BIREYSEL

consent_date   string     

Onayın alındığı gerçek tarih. Example: 2026-06-01 10:00:00

consent_confirmed   boolean     

Beyan onayı (true olmalı). Example: true

Onay kaydını sil

Bir pazarlama onay kaydını siler. (İYS'ye yüklenmiş onayın geri çekilmesi ayrı bir RET kaydıyla yapılır.)

Example request:
curl --request DELETE \
    "https://dowaba.com/api/iys/consents/1"
const url = new URL(
    "https://dowaba.com/api/iys/consents/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/consents/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true
}
 

Example response (404):


{
    "error": "Kayıt bulunamadı."
}
 

Request      

DELETE api/iys/consents/{id}

URL Parameters

id   integer     

Onay kaydı id. Example: 1

İYS export meta verileri

Kullanıcının erişebildiği siteler + rehber grupları (kişi sayılarıyla, EN SON eklenen üstte)

Example request:
curl --request GET \
    --get "https://dowaba.com/api/iys/export/meta?consent_date=2026-06-30"
const url = new URL(
    "https://dowaba.com/api/iys/export/meta"
);

const params = {
    "consent_date": "2026-06-30",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/export/meta';
$response = $client->get(
    $url,
    [
        'query' => [
            'consent_date' => '2026-06-30',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "sites": [
        {
            "id": 12,
            "name": "Acme",
            "contact_count": 340
        }
    ],
    "groups": [
        {
            "id": 7,
            "name": "VIP",
            "contact_count": 58
        }
    ],
    "total_contacts": 340,
    "sources": [
        "HS_WEB"
    ],
    "types": [
        "MESAJ",
        "EPOSTA",
        "ARAMA"
    ],
    "recipient_types": [
        "BIREYSEL",
        "TACIR"
    ]
}
 

Request      

GET api/iys/export/meta

Query Parameters

consent_date   string  optional    

Verilirse sayımlar yalnız o gün (created_at) eklenen kişileri kapsar (export ile aynı filtre). Example: 2026-06-30

İYS yükleme CSV'si indir

Seçilen kapsamdaki kişilerden İYS resmi şablonunda CSV üretir (Bireysel/Tacir). Her kişi için seçilen tip(ler)e göre satır: e-posta→EPOSTA, telefon→MESAJ/ARAMA.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/iys/export?scope=group&site_id=12&group_id=7&recipient_type=BIREYSEL&types=MESAJ%2CEPOSTA&status=ONAY&source=HS_WEB&consent_date=2026-06-01+10%3A00%3A00&exclude_optout=1&chunk_size=50"
const url = new URL(
    "https://dowaba.com/api/iys/export"
);

const params = {
    "scope": "group",
    "site_id": "12",
    "group_id": "7",
    "recipient_type": "BIREYSEL",
    "types": "MESAJ,EPOSTA",
    "status": "ONAY",
    "source": "HS_WEB",
    "consent_date": "2026-06-01 10:00:00",
    "exclude_optout": "1",
    "chunk_size": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/iys/export';
$response = $client->get(
    $url,
    [
        'query' => [
            'scope' => 'group',
            'site_id' => '12',
            'group_id' => '7',
            'recipient_type' => 'BIREYSEL',
            'types' => 'MESAJ,EPOSTA',
            'status' => 'ONAY',
            'source' => 'HS_WEB',
            'consent_date' => '2026-06-01 10:00:00',
            'exclude_optout' => '1',
            'chunk_size' => '50',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


CSV dosyası (text/csv) ya da bölündüyse ZIP (application/zip) attachment
 

Example response (403):


{
    "error": "Bu kapsama erişiminiz yok."
}
 

Example response (422):


{
    "error": "En az bir izin türü seçin."
}
 

Request      

GET api/iys/export

Query Parameters

scope   string     

Kapsam: all | site | group. Example: group

site_id   integer  optional    

scope=site|all filtresi. Example: 12

group_id   integer  optional    

scope=group için rehber grubu. Example: 7

recipient_type   string     

BIREYSEL veya TACIR. Example: BIREYSEL

types   string     

Virgülle tip listesi (MESAJ,EPOSTA,ARAMA). Example: MESAJ,EPOSTA

status   string  optional    

ONAY veya RET (varsayılan ONAY). Example: ONAY

source   string  optional    

Bireysel için izin kaynağı (meta'dan). Example: HS_WEB

consent_date   string  optional    

Bireysel için izin tarihi. Verilirse AYNI ZAMANDA created_at gün filtresi: yalnız o gün eklenen kişiler dışa aktarılır. Example: 2026-06-01 10:00:00

exclude_optout   boolean  optional    

Kendi ret listemizdeki (opt-out) kişileri hariç tut. Example: true

chunk_size   integer  optional    

Dosya başına en fazla satır. Bu sayıyı aşan liste birden çok CSV'ye bölünüp ZIP olarak iner (İYS tek yüklemede sınırlı satır kabul eder, ör. 50). Varsayılan 999999 = tek dosya. Example: 50

Pazarlama Opt-out (Gönderme Listesi)

Toplu pazarlama "gönderme listesi" yönetimi (ETK 6563 / İYS / KVKK uyum). Otomatik dolar: alıcı WhatsApp'tan "DUR/STOP" yazınca (WhatsappMessageObserver) veya sesli aramada "beni aramayın" deyince (AI aranmak_istemiyorum → channel=call). Bu endpoint'ler bayinin/müşterinin listeyi görmesi + elle ekleme/çıkarma (örn. e-posta/telefonla "beni çıkarın" diyen birini eklemek) içindir.

Yetki: kullanıcı yalnızca erişebildiği site'ların (User::accessibleSiteIds — UNION cascade) opt-out kayıtlarını görür/yönetir.

Opt-out (gönderme) listesini getir

Erişebildiğin site'ların red listesini sayfalı döndürür. Toplu göndermeden önce bu listeyi çekip alıcılardan çıkar.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/message-opt-outs?site_id=12&channel=whatsapp&search=90555&per_page=50"
const url = new URL(
    "https://dowaba.com/api/message-opt-outs"
);

const params = {
    "site_id": "12",
    "channel": "whatsapp",
    "search": "90555",
    "per_page": "50",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/message-opt-outs';
$response = $client->get(
    $url,
    [
        'query' => [
            'site_id' => '12',
            'channel' => 'whatsapp',
            'search' => '90555',
            'per_page' => '50',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "site_id": 12,
            "channel": "whatsapp",
            "identifier": "+905551112233",
            "opted_out_at": "2026-06-06T10:00:00Z"
        }
    ],
    "total": 1,
    "current_page": 1,
    "last_page": 1
}
 

Request      

GET api/message-opt-outs

Query Parameters

site_id   integer  optional    

Belirli siteye filtrele. Example: 12

channel   string  optional    

Kanal: whatsapp, sms, mail veya call (sesli arama kampanyası). Example: whatsapp

search   string  optional    

Telefon/e-posta içinde ara. Example: 90555

per_page   integer  optional    

Sayfa boyutu (max 100, varsayılan 50). Example: 50

Opt-out kaydı ekle (manuel)

Bir alıcıyı gönderme listesine ekler (örn. telefon/e-posta ile "beni çıkarın" diyen). identifier kanal türüne göre normalize edilir (mail → e-posta, diğer → E.164 telefon). channel=call → sesli arama kampanyaları bu numarayı arama anında otomatik atlar.

Example request:
curl --request POST \
    "https://dowaba.com/api/message-opt-outs" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 12,
    \"channel\": \"whatsapp\",
    \"identifier\": \"+905551112233\",
    \"reason\": \"müşteri talebi\"
}"
const url = new URL(
    "https://dowaba.com/api/message-opt-outs"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 12,
    "channel": "whatsapp",
    "identifier": "+905551112233",
    "reason": "müşteri talebi"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/message-opt-outs';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 12,
            'channel' => 'whatsapp',
            'identifier' => '+905551112233',
            'reason' => 'müşteri talebi',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201):


{
    "success": true,
    "data": {
        "id": 1,
        "site_id": 12,
        "channel": "whatsapp",
        "identifier": "+905551112233"
    }
}
 

Example response (403):


{
    "error": "Bu siteye erişiminiz yok."
}
 

Example response (422):


{
    "error": "Geçersiz telefon numarası."
}
 

Request      

POST api/message-opt-outs

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

Erişebildiğin site. Example: 12

channel   string     

Kanal: whatsapp, sms, mail veya call. Example: whatsapp

identifier   string     

Telefon (E.164) veya e-posta. Example: +905551112233

reason   string  optional    

Sebep (opsiyonel). Example: müşteri talebi

Opt-out kaydını sil

Bir kişiyi gönderme listesinden çıkarır (tekrar mesaj alabilir hale gelir).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/message-opt-outs/1"
const url = new URL(
    "https://dowaba.com/api/message-opt-outs/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/message-opt-outs/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true
}
 

Example response (404):


{
    "error": "Kayıt bulunamadı."
}
 

Request      

DELETE api/message-opt-outs/{id}

URL Parameters

id   integer     

Opt-out kaydı id. Example: 1

Kullanım & Krediler

AI kullanım log'larını listele (filtre: site, tarih, action).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/usage"
const url = new URL(
    "https://dowaba.com/api/usage"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/usage';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/usage

Aylık + tüm zaman kullanım istatistikleri (token, maliyet, kanal başı sayılar).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/usage/stats"
const url = new URL(
    "https://dowaba.com/api/usage/stats"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/usage/stats';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/usage/stats

Birleşik usage snapshot — mesaj + voice kotalama, kanal breakdown. UsageMeterService tek noktadan döner (Redis 60sn cache). GET /api/me/usage

Example request:
curl --request GET \
    --get "https://dowaba.com/api/me/usage"
const url = new URL(
    "https://dowaba.com/api/me/usage"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/usage';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/me/usage

Kullanıcı kredi bakiyesini getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/credits"
const url = new URL(
    "https://dowaba.com/api/credits"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/credits';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/credits

Kredi işlem geçmişi (filtre: type, tarih).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/credits/transactions"
const url = new URL(
    "https://dowaba.com/api/credits/transactions"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/credits/transactions';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/credits/transactions

Aktif tüm abonelik planlarını listele. Kullanıcı authenticate olmuşsa ve kendi aktif aboneliği gizli (is_active=false) bir plana bağlıysa (grandfather/legacy planlar — örn. "business-legacy" eski Business 9.990₺ müşterileri için), o planı da listeye ekler. Böylece müşteri panelde kendi planını görebilir ve eskisi gibi yenileyebilir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/plans"
const url = new URL(
    "https://dowaba.com/api/subscriptions/plans"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/plans';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 1,
            "slug": "starter",
            "name": "Starter",
            "monthly_price": 299,
            "yearly_price": 2999,
            "lifetime_price": null,
            "max_sites": 1,
            "max_whatsapp_profiles": 1,
            "monthly_ai_limit": 1000,
            "features": [
                "whatsapp",
                "widget",
                "mail"
            ],
            "is_active": true
        },
        {
            "id": 2,
            "slug": "pro",
            "name": "Pro",
            "monthly_price": 599,
            "yearly_price": 5999,
            "max_sites": 3,
            "max_whatsapp_profiles": 3,
            "monthly_ai_limit": 5000,
            "is_active": true
        },
        {
            "id": 3,
            "slug": "business",
            "name": "Business",
            "monthly_price": 3999,
            "yearly_price": null,
            "max_sites": null,
            "is_dynamic": true,
            "per_site_yearly_price": 3999,
            "is_active": true
        }
    ]
}
 

Request      

GET api/subscriptions/plans

Kullanıcının aktif aboneliğini getir. Paralel sub mimarisi (2026-05-15): primary plan + bayilerin müşterileri için pay_per_site plan'ları dahil.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/current" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/subscriptions/current"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/current';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Aktif Business + 3 pay_per_site):


{
    "data": {
        "subscription": {
            "id": 7,
            "plan_id": 3,
            "plan_name": "Business",
            "period": "yearly",
            "status": "active",
            "sites_count": 5,
            "ends_at": "2027-05-19T00:00:00.000000Z",
            "auto_renew": true
        },
        "subscriptions": [
            {
                "id": 7,
                "plan_name": "Business",
                "sites_count": 5,
                "ends_at": "2027-05-19T00:00:00.000000Z"
            },
            {
                "id": 11,
                "plan_name": "Reseller-Site",
                "site_id": 12,
                "ends_at": "2027-04-30T00:00:00.000000Z"
            },
            {
                "id": 12,
                "plan_name": "Reseller-Site",
                "site_id": 13,
                "ends_at": "2027-05-12T00:00:00.000000Z"
            }
        ]
    }
}
 

Example response (200, Aktif abonelik yok):


{
    "data": {
        "subscription": null,
        "subscriptions": []
    }
}
 

Request      

GET api/subscriptions/current

Headers

Authorization        

Example: Bearer {TOKEN}

Kullanıcının abonelik bazlı kullanım özetini getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/usage"
const url = new URL(
    "https://dowaba.com/api/subscriptions/usage"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/usage';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscriptions/usage

Canlı fiyat preview — dinamik plan için frontend slider/dropdown'unda kullanılır. Query: - plan_id (zorunlu) - sites_count (zorunlu, min 1) - period: monthly | yearly (zorunlu)

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/price-quote" \
    --header "Content-Type: application/json" \
    --data "{
    \"plan_id\": 3,
    \"sites_count\": 13,
    \"period\": \"monthly\"
}"
const url = new URL(
    "https://dowaba.com/api/subscriptions/price-quote"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "plan_id": 3,
    "sites_count": 13,
    "period": "monthly"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/price-quote';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'plan_id' => 3,
            'sites_count' => 13,
            'period' => 'monthly',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscriptions/price-quote

Headers

Content-Type        

Example: application/json

Body Parameters

plan_id   integer     

Fiyat önizlemesi yapılacak plan ID. Example: 3

sites_count   integer     

Must be at least 1. Must not be greater than 1000. Example: 13

period   string     

Example: monthly

Must be one of:
  • monthly
  • yearly

Plan seçimi için PayTR iFrame token üret (ödeme başlatma). Business planında sites_count kademe indirim ile çarpılır (SUBSCRIPTION_ARCHITECTURE.md).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/subscriptions/initiate" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"plan_id\": 3,
    \"period\": \"yearly\",
    \"sites_count\": 5
}"
const url = new URL(
    "https://dowaba.com/api/subscriptions/initiate"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "plan_id": 3,
    "period": "yearly",
    "sites_count": 5
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/initiate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'plan_id' => 3,
            'period' => 'yearly',
            'sites_count' => 5,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "iframe_token": "[REDACTED]",
    "merchant_oid": "DOWABA-42-1730000000",
    "amount_try": 19995,
    "user_subscription_id": 7
}
 

Example response (422):


{
    "message": "The given data was invalid.",
    "errors": {
        "plan_id": [
            "The selected plan id is invalid."
        ]
    }
}
 

Example response (500, PayTR API hata):


{
    "success": false,
    "error": "Ödeme servisi geçici olarak erişilemez. Lütfen tekrar deneyin."
}
 

Request      

POST api/subscriptions/initiate

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

plan_id   integer     

Plan ID. Example: 3

period   string     

monthly/yearly/lifetime. Example: yearly

sites_count   integer  optional    

Business dinamik için site sayısı (1-1000). Example: 5

Mevcut dinamik aboneliğin site sayısını değiştir. Body: - sites_count (zorunlu, min 1) - immediate (default false) — artırma için ödeme tetikler; azaltma için göz ardı edilir Response: - requires_payment: true ise iframe_token + merchant_oid döner (PayTR upgrade) - requires_payment: false (downgrade) pending_sites_count set edildi

Example request:
curl --request POST \
    "https://dowaba.com/api/subscriptions/change-sites" \
    --header "Content-Type: application/json" \
    --data "{
    \"sites_count\": 21,
    \"immediate\": false
}"
const url = new URL(
    "https://dowaba.com/api/subscriptions/change-sites"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "sites_count": 21,
    "immediate": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/change-sites';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'sites_count' => 21,
            'immediate' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/subscriptions/change-sites

Headers

Content-Type        

Example: application/json

Body Parameters

sites_count   integer     

Must be at least 1. Must not be greater than 1000. Example: 21

immediate   boolean  optional    

Example: false

Müşteri — Faturalarım

Müşterinin kendi cari hesabı: bayilerin düzenlediği borçlar, taksitler, ödemeler. Brand bilgisi: müşteri bağlıysa bayinin app_name/app_logo görünür.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/me/billing" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/me/billing"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/billing';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/me/billing

Headers

Authorization        

Example: Bearer {TOKEN}

Müşteri AI Talimat

Müşteri (Contact) bazında bot davranış ek talimatı CRUD'u.

Mimari: Tek prompt × Contact (multi-channel). Bir müşteri WhatsApp'tan, Instagram'dan, e-postadan yazsa bile TEK Contact row'una bağlanır — operatör bir kez talimat yazınca her kanalda aynı geçerli olur.

Frontend modal channel + identifier gönderir (WA için phone, IG için sender_id, vs.). Controller bu çifti Contact'a çevirir (Contact::findByChannelIdentifier), yoksa otomatik upsert eder.

Authz: Site::isAccessibleBy — bayi cascade dahil. Agent için DELETE engelli.

AI inject: UnifiedAIService::buildSystemPrompt ve sip-bridge (voice) bu tek alandan okur. Cache key: contact_ai_instr:{contact_id} — saved/deleted event'inde invalidate.

Endpoint: GET /api/conversation-ai-overrides?site_id=X&channel=Y&identifier=Z PUT /api/conversation-ai-overrides body: {site_id, channel, identifier, instructions, is_active?} DELETE /api/conversation-ai-overrides?site_id=X&channel=Y&identifier=Z

Mevcut talimatı getir. Contact yoksa veya field boşsa → null döner.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/conversation-ai-overrides" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"identifier\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/conversation-ai-overrides"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "identifier": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/conversation-ai-overrides';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'identifier' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/conversation-ai-overrides

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

The id of an existing record in the sites table. Example: 17

channel   string  optional    
identifier   string     

Must not be greater than 191 characters. Example: mqeopfuudtdsufvyvddqa

Upsert — Contact yoksa otomatik oluştur (kanal başına ilgili kolon set edilir), sonra ai_instructions yaz. Bayinin bir müşteriyi rehbere eklemeden de panel'den talimat yazabilmesi için.

Example request:
curl --request PUT \
    "https://dowaba.com/api/conversation-ai-overrides" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"identifier\": \"mqeopfuudtdsufvyvddqa\",
    \"instructions\": \"mniihfqcoynlazghdtqtq\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/conversation-ai-overrides"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "identifier": "mqeopfuudtdsufvyvddqa",
    "instructions": "mniihfqcoynlazghdtqtq",
    "is_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/conversation-ai-overrides';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'identifier' => 'mqeopfuudtdsufvyvddqa',
            'instructions' => 'mniihfqcoynlazghdtqtq',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/conversation-ai-overrides

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

The id of an existing record in the sites table. Example: 17

channel   string  optional    
identifier   string     

Must not be greater than 191 characters. Example: mqeopfuudtdsufvyvddqa

instructions   string     

Must not be greater than 5000 characters. Example: mniihfqcoynlazghdtqtq

is_active   boolean  optional    

Example: false

Talimatı sil (Contact'ı silmez, sadece ai_instructions alanlarını NULL'a çeker). Agent yapamaz.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/conversation-ai-overrides" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17,
    \"identifier\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/conversation-ai-overrides"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17,
    "identifier": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "DELETE",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/conversation-ai-overrides';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
            'identifier' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/conversation-ai-overrides

Headers

Content-Type        

Example: application/json

Body Parameters

site_id   integer     

The id of an existing record in the sites table. Example: 17

channel   string  optional    
identifier   string     

Must not be greater than 191 characters. Example: mqeopfuudtdsufvyvddqa

PayPal (manuel, lang=en için)

Akış (aydinacar.net pattern):

  1. Kullanıcı lang=en panelinden "Pay with PayPal" tıklar → initiate (pending kayıt)
  2. Frontend pending sayfası gösterir: paypal.me link + USD tutar + email
  3. Kullanıcı PayPal'da manuel öder (Friends & Family) + "I sent the payment" tıklar
  4. Admin Telegram bildirimi alır, /admin/paypal-payments'ten onaylar
  5. Abonelik aktive olur (SubscriptionService::activateSubscription)

Kullanıcı PayPal ile abonelik başlatır.

Sadece lang=en kullanıcılar — middleware veya inline check.

Example request:
curl --request POST \
    "https://dowaba.com/api/subscriptions/paypal/initiate" \
    --header "Content-Type: application/json" \
    --data "{
    \"plan_id\": 17,
    \"period\": \"yearly\",
    \"sites_count\": 13,
    \"user_payer_email\": \"justice61@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/subscriptions/paypal/initiate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "plan_id": 17,
    "period": "yearly",
    "sites_count": 13,
    "user_payer_email": "justice61@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/paypal/initiate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'plan_id' => 17,
            'period' => 'yearly',
            'sites_count' => 13,
            'user_payer_email' => 'justice61@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/subscriptions/paypal/initiate

Headers

Content-Type        

Example: application/json

Body Parameters

plan_id   integer     

The id of an existing record in the subscription_plans table. Example: 17

period   string     

Example: yearly

Must be one of:
  • monthly
  • yearly
sites_count   integer  optional    

Must be at least 1. Must not be greater than 1000. Example: 13

user_payer_email   string  optional    

Must be a valid email address. Example: justice61@example.com

Kullanıcının kendi pending/recent PayPal ödemelerini döner.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/paypal/payments"
const url = new URL(
    "https://dowaba.com/api/subscriptions/paypal/payments"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/paypal/payments';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscriptions/paypal/payments

Tek payment detayı (kullanıcı kendi pending'ini görüntüler — pending sayfası).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/paypal/payments/1"
const url = new URL(
    "https://dowaba.com/api/subscriptions/paypal/payments/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/paypal/payments/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscriptions/paypal/payments/{payment_id}

URL Parameters

payment_id   integer     

The ID of the payment. Example: 1

Kullanıcı "I sent the payment" tıkladı.

Example request:
curl --request POST \
    "https://dowaba.com/api/subscriptions/paypal/payments/1/confirm-sent"
const url = new URL(
    "https://dowaba.com/api/subscriptions/paypal/payments/1/confirm-sent"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/paypal/payments/1/confirm-sent';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/subscriptions/paypal/payments/{payment_id}/confirm-sent

URL Parameters

payment_id   integer     

The ID of the payment. Example: 1

Stripe (uluslararası kart ödemesi)

Akış (PayPal'a paralel, ama OTOMATİK):

  1. Kullanıcı (TR dışı / USD locale) "Credit / Debit Card" tıklar → initiate
  2. Backend Stripe Checkout Session oluşturur → frontend url'e yönlendirir
  3. Kullanıcı Stripe sayfasında kartla öder → success_url'e döner
  4. Stripe stripe/webhook (imzalı) aboneliği OTOMATİK aktive eder

Sadece USD (TR dışı) kullanıcılar için — TR kullanıcılar PayTR (TL) kullanır.

Stripe Checkout Session başlat. Frontend dönen `url`'e yönlendirir.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/subscriptions/stripe/checkout" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"plan_id\": 1,
    \"period\": \"yearly\",
    \"sites_count\": 5
}"
const url = new URL(
    "https://dowaba.com/api/subscriptions/stripe/checkout"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "plan_id": 1,
    "period": "yearly",
    "sites_count": 5
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/stripe/checkout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'plan_id' => 1,
            'period' => 'yearly',
            'sites_count' => 5,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "url": "https://checkout.stripe.com/c/pay/cs_...",
    "session_id": "cs_...",
    "payment_id": 12
}
 

Request      

POST api/subscriptions/stripe/checkout

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

plan_id   integer     

Plan ID. Example: 1

period   string     

monthly/yearly/lifetime. Example: yearly

sites_count   integer  optional    

Business dinamik için site sayısı (1-1000). Example: 5

Bir Stripe ödemesinin durumunu döner (success sayfası polling için).

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/stripe/payments/1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/subscriptions/stripe/payments/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/stripe/payments/1';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscriptions/stripe/payments/{payment_id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

payment_id   integer     

The ID of the payment. Example: 1

External API (3rd party)

Server-to-server: Instagram profil bilgisini getir (dsk_ key auth).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/external/instagram/profile"
const url = new URL(
    "https://dowaba.com/api/external/instagram/profile"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/external/instagram/profile';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "success": false,
    "error": "X-Api-Key header required"
}
 

Request      

GET api/external/instagram/profile

Server-to-server: Tüm post kurallarını getir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/external/instagram/rules"
const url = new URL(
    "https://dowaba.com/api/external/instagram/rules"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/external/instagram/rules';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "success": false,
    "error": "X-Api-Key header required"
}
 

Request      

GET api/external/instagram/rules

Server-to-server: Post kuralı ekle/güncelle.

Example request:
curl --request POST \
    "https://dowaba.com/api/external/instagram/rules" \
    --header "Content-Type: application/json" \
    --data "{
    \"id\": \"42\",
    \"post_id\": \"17841400000000000\",
    \"post_caption\": \"Yeni koleksiyon yayında!\",
    \"post_media_url\": \"http:\\/\\/kunze.biz\\/iste-laborum-eius-est-dolor.html\",
    \"keywords\": [],
    \"comment_message\": \"vmqeopfuudtdsufvyvddq\",
    \"dm_message\": \"amniihfqcoynlazghdtqt\",
    \"dm_closed_reply\": \"DM kutunuz kapalı görünüyor, bize DM\'den yazın.\",
    \"use_ai\": true,
    \"custom_prompt\": \"Yorumcuya samimi teşekkür et.\",
    \"enabled\": true
}"
const url = new URL(
    "https://dowaba.com/api/external/instagram/rules"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id": "42",
    "post_id": "17841400000000000",
    "post_caption": "Yeni koleksiyon yayında!",
    "post_media_url": "http:\/\/kunze.biz\/iste-laborum-eius-est-dolor.html",
    "keywords": [],
    "comment_message": "vmqeopfuudtdsufvyvddq",
    "dm_message": "amniihfqcoynlazghdtqt",
    "dm_closed_reply": "DM kutunuz kapalı görünüyor, bize DM'den yazın.",
    "use_ai": true,
    "custom_prompt": "Yorumcuya samimi teşekkür et.",
    "enabled": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/external/instagram/rules';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'id' => '42',
            'post_id' => '17841400000000000',
            'post_caption' => 'Yeni koleksiyon yayında!',
            'post_media_url' => 'http://kunze.biz/iste-laborum-eius-est-dolor.html',
            'keywords' => [],
            'comment_message' => 'vmqeopfuudtdsufvyvddq',
            'dm_message' => 'amniihfqcoynlazghdtqt',
            'dm_closed_reply' => 'DM kutunuz kapalı görünüyor, bize DM\'den yazın.',
            'use_ai' => true,
            'custom_prompt' => 'Yorumcuya samimi teşekkür et.',
            'enabled' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/external/instagram/rules

Headers

Content-Type        

Example: application/json

Body Parameters

id   string     

Kuralın dış sistemdeki benzersiz ID'si. Example: 42

post_id   string     

Instagram gönderi (media) ID'si. Example: 17841400000000000

post_caption   string  optional    

Gönderi açıklaması (caption). Example: Yeni koleksiyon yayında!

post_media_url   string  optional    

Example: http://kunze.biz/iste-laborum-eius-est-dolor.html

keywords   object     

Must have at least 1 items.

comment_message   string  optional    

Must not be greater than 2000 characters. Example: vmqeopfuudtdsufvyvddq

dm_message   string  optional    

Must not be greater than 4000 characters. Example: amniihfqcoynlazghdtqt

dm_closed_reply   string  optional    

DM gönderilemezse yoruma yazılacak fallback yanıt. Example: DM kutunuz kapalı görünüyor, bize DM'den yazın.

use_ai   boolean  optional    

Yorum yanıtı AI ile dinamik üretilsin mi (true → gelen yorum + custom_prompt ile üretilir; comment_message fallback olur). Example: true

custom_prompt   string  optional    

AI yorum yanıtı yönergesi (use_ai=true iken; boşsa profilin genel Instagram prompt'u). Example: Yorumcuya samimi teşekkür et.

enabled   boolean     

Example: true

Server-to-server: Post kuralı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/external/instagram/rules/42"
const url = new URL(
    "https://dowaba.com/api/external/instagram/rules/42"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/external/instagram/rules/42';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/external/instagram/rules/{ruleId}

URL Parameters

ruleId   string     

Silinecek kuralın benzersiz ID'si (saveRule'daki id alanı). Example: 42

Server-to-server: Toplu kural senkronizasyonu (migrasyon için).

Example request:
curl --request POST \
    "https://dowaba.com/api/external/instagram/rules/sync" \
    --header "Content-Type: application/json" \
    --data "{
    \"rules\": [
        {
            \"id\": \"42\",
            \"post_id\": \"17841400000000000\",
            \"keywords\": [],
            \"enabled\": true
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/external/instagram/rules/sync"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "rules": [
        {
            "id": "42",
            "post_id": "17841400000000000",
            "keywords": [],
            "enabled": true
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/external/instagram/rules/sync';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'rules' => [
                [
                    'id' => '42',
                    'post_id' => '17841400000000000',
                    'keywords' => [],
                    'enabled' => true,
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/external/instagram/rules/sync

Headers

Content-Type        

Example: application/json

Body Parameters

rules   object[]     
id   string     

Kuralın dış sistemdeki benzersiz ID'si. Example: 42

post_id   string     

Instagram gönderi (media) ID'si. Example: 17841400000000000

keywords   object     

Must have at least 1 items.

enabled   boolean     

Example: true

Geliştirici — API Anahtarları

Kullanıcının kendi kişisel API anahtarlarını (Sanctum Personal Access Token) yönetir. Geliştirici sayfası > "API Anahtarları" sekmesi.

Güvenlik kontratı:

Kullanıcının kişisel API anahtarlarını listeler (yalnızca dev: prefix'liler, token değeri olmadan).

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/me/tokens" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/me/tokens"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/tokens';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Başarılı):


{
    "tokens": [
        {
            "id": 7,
            "name": "CRM Entegrasyonu",
            "abilities": [
                "*"
            ],
            "last_used_at": "2026-05-31T10:00:00.000000Z",
            "created_at": "2026-05-30T09:00:00.000000Z"
        }
    ]
}
 

Request      

GET api/me/tokens

Headers

Authorization        

Example: Bearer {TOKEN}

Yeni adlandırılmış API anahtarı oluşturur. Plain token cevabı yalnızca bir kez döner.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/me/tokens" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"CRM Entegrasyonu\",
    \"accept_policy\": true
}"
const url = new URL(
    "https://dowaba.com/api/me/tokens"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "CRM Entegrasyonu",
    "accept_policy": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/tokens';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'CRM Entegrasyonu',
            'accept_policy' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (201, Oluşturuldu):


{
    "token": "[REDACTED]",
    "id": 7,
    "name": "CRM Entegrasyonu",
    "created_at": "2026-05-31T10:00:00.000000Z"
}
 

Example response (403, Şartlar kabul edilmemiş):


{
    "error": "Önce Geliştirici Şartları'nı kabul etmelisiniz."
}
 

Example response (422, Limit doldu):


{
    "error": "En fazla 20 API anahtarı oluşturabilirsiniz. Yeni anahtar için önce birini silin."
}
 

Request      

POST api/me/tokens

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

name   string     

Anahtar için tanımlayıcı isim. Example: CRM Entegrasyonu

accept_policy   boolean     

Meta/kanal politika onayı (opt-in + spam yasağı). Example: true

Bir API anahtarını iptal eder (ownership + yalnızca dev: prefix guard).

requires authentication

Example request:
curl --request DELETE \
    "https://dowaba.com/api/me/tokens/7" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/me/tokens/7"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/tokens/7';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, İptal edildi):


{
    "success": true
}
 

Example response (404, Bulunamadı / oturum token'ı / başkasına ait):


{
    "error": "Anahtar bulunamadı."
}
 

Request      

DELETE api/me/tokens/{id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

id   integer     

Token ID. Example: 7

Geliştirici — Webhooks

Outbound webhook endpoint yönetimi. Kendi URL'ini ve abone olduğun event'leri tanımlarsın; ilgili olay gerçekleştiğinde (örn. yeni mesaj) DoWaba o URL'e HMAC imzalı bir POST atar. Yalnızca kendi endpoint'lerini görebilir ve yönetebilirsin; URL'ler https olmak zorundadır. Endpoint secret'ı oluşturma sırasında üretilir ve imza doğrulaması için endpoint listenle birlikte döner.

Teslimat formatı: Gövde {"event", "data", "delivery_id", "timestamp"} alanlı JSON'dır; şu header'lar eklenir: X-Dowaba-Event (event adı), X-Dowaba-Signature (imza), X-Dowaba-Delivery (teslimat ID).

İmza doğrulama: X-Dowaba-Signature, ham istek gövdesinin endpoint secret'ı ile alınmış HMAC-SHA256 hex özetidir:

$expected = hash_hmac('sha256', $rawBody, $secret);
if (! hash_equals($expected, $request->header('X-Dowaba-Signature'))) {
    abort(401);
}

Yeniden deneme: 2xx dışındaki yanıtlar ve zaman aşımı (15 sn) başarısız sayılır; teslimat 1 dk ve 5 dk arayla toplam 3 kez denenir. Aynı X-Dowaba-Delivery ID'si birden fazla kez gelebilir — sisteminiz teslimatları bu ID üzerinden tekilleştirip idempotent işlemelidir.

Kullanıcının endpoint'lerini listeler (kendi secret'larıyla birlikte).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/webhook-endpoints"
const url = new URL(
    "https://dowaba.com/api/webhook-endpoints"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/webhook-endpoints';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/webhook-endpoints

Yeni webhook endpoint'i oluşturur. Secret otomatik üretilir ve döner.

Example request:
curl --request POST \
    "https://dowaba.com/api/webhook-endpoints" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"url\": \"https:\\/\\/example.com\\/webhooks\\/dowaba\",
    \"events\": [
        \"message.received\"
    ],
    \"site_id\": 17,
    \"full_payload\": true,
    \"accept_policy\": true
}"
const url = new URL(
    "https://dowaba.com/api/webhook-endpoints"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "url": "https:\/\/example.com\/webhooks\/dowaba",
    "events": [
        "message.received"
    ],
    "site_id": 17,
    "full_payload": true,
    "accept_policy": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/webhook-endpoints';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'url' => 'https://example.com/webhooks/dowaba',
            'events' => [
                'message.received',
            ],
            'site_id' => 17,
            'full_payload' => true,
            'accept_policy' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/webhook-endpoints

Headers

Content-Type        

Example: application/json

Body Parameters

name   string  optional    

Must not be greater than 60 characters. Example: vmqeopfuudtdsufvyvddq

url   string     

https URL. Example: https://example.com/webhooks/dowaba

events   string[]     

Abone olunacak event'ler.

site_id   integer  optional    

Example: 17

full_payload   boolean  optional    

Example: true

accept_policy   boolean     

Meta/kanal politika onayı. Example: true

Endpoint günceller (url/events/is_active/name).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/webhook-endpoints/1562" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"url\": \"http:\\/\\/www.kunde.com\\/\",
    \"is_active\": false,
    \"full_payload\": false
}"
const url = new URL(
    "https://dowaba.com/api/webhook-endpoints/1562"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "url": "http:\/\/www.kunde.com\/",
    "is_active": false,
    "full_payload": false
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/webhook-endpoints/1562';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'url' => 'http://www.kunde.com/',
            'is_active' => false,
            'full_payload' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/webhook-endpoints/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the webhook endpoint. Example: 1562

Body Parameters

name   string  optional    

Must not be greater than 60 characters. Example: vmqeopfuudtdsufvyvddq

url   string  optional    

Must be a valid URL. Must not be greater than 2048 characters. Example: http://www.kunde.com/

events   string[]  optional    
is_active   boolean  optional    

Example: false

full_payload   boolean  optional    

Example: false

Endpoint siler.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/webhook-endpoints/1562"
const url = new URL(
    "https://dowaba.com/api/webhook-endpoints/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/webhook-endpoints/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/webhook-endpoints/{id}

URL Parameters

id   string     

The ID of the webhook endpoint. Example: 1562

Örnek payload ile test teslimatı kuyruğa atar.

Example request:
curl --request POST \
    "https://dowaba.com/api/webhook-endpoints/1562/test"
const url = new URL(
    "https://dowaba.com/api/webhook-endpoints/1562/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/webhook-endpoints/1562/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/webhook-endpoints/{id}/test

URL Parameters

id   string     

The ID of the webhook endpoint. Example: 1562

Son 20 teslimat (debug).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/webhook-endpoints/1562/deliveries"
const url = new URL(
    "https://dowaba.com/api/webhook-endpoints/1562/deliveries"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/webhook-endpoints/1562/deliveries';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/webhook-endpoints/{id}/deliveries

URL Parameters

id   string     

The ID of the webhook endpoint. Example: 1562

Geliştirici — Yasal Kabul

Geliştirici API Kullanım Şartları kabul durumu + kaydı. Kullanıcı API anahtarı / webhook / OAuth client oluşturmadan ÖNCE bu şartları kabul etmek zorundadır (ilgili store endpoint'leri kabul yoksa 403 döner). Şartların metni frontend'de (DeveloperView) i18n ile gösterilir; burada yalnızca kabul zaman damgası tutulur.

GET api/me/developer-terms

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/me/developer-terms" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/me/developer-terms"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/developer-terms';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "accepted": true,
    "accepted_at": "2026-05-31T22:00:00.000000Z",
    "accepted_version": "1",
    "current_version": "1",
    "needs_reaccept": false
}
 

Request      

GET api/me/developer-terms

Headers

Authorization        

Example: Bearer {TOKEN}

POST api/me/developer-terms/accept

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/me/developer-terms/accept" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"accept\": true
}"
const url = new URL(
    "https://dowaba.com/api/me/developer-terms/accept"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "accept": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/developer-terms/accept';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'accept' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "accepted": true,
    "accepted_at": "2026-05-31T22:00:00.000000Z",
    "version": "1"
}
 

Request      

POST api/me/developer-terms/accept

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

accept   boolean     

Şartların kabulü. Example: true

Geliştirici — OAuth Uygulamaları

Kullanıcının kendi "Login with Dowaba" OAuth client'larını self-service yönetimi. Geliştirici sayfası > "OAuth Uygulamaları" sekmesi. Admin/OauthClientController'ın (superadmin) müşteri-kapsamlı eşdeğeri.

Güvenlik:

GET api/me/oauth/clients

Example request:
curl --request GET \
    --get "https://dowaba.com/api/me/oauth/clients"
const url = new URL(
    "https://dowaba.com/api/me/oauth/clients"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/oauth/clients';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/me/oauth/clients

Yeni OAuth client. owner_user_id = auth, issues_sanctum_token = false (zorunlu).

Example request:
curl --request POST \
    "https://dowaba.com/api/me/oauth/clients" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"Randevu Sitem\",
    \"redirect_uris\": [
        \"https:\\/\\/example.com\\/callback\"
    ],
    \"allowed_scopes\": [
        \"openid\",
        \"profile\",
        \"email\"
    ],
    \"is_confidential\": true,
    \"accept_policy\": true
}"
const url = new URL(
    "https://dowaba.com/api/me/oauth/clients"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "Randevu Sitem",
    "redirect_uris": [
        "https:\/\/example.com\/callback"
    ],
    "allowed_scopes": [
        "openid",
        "profile",
        "email"
    ],
    "is_confidential": true,
    "accept_policy": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/oauth/clients';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'Randevu Sitem',
            'redirect_uris' => [
                'https://example.com/callback',
            ],
            'allowed_scopes' => [
                'openid',
                'profile',
                'email',
            ],
            'is_confidential' => true,
            'accept_policy' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/me/oauth/clients

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

Uygulama adı. Example: Randevu Sitem

redirect_uris   string[]     

https callback URL'leri.

allowed_scopes   string[]     

İzin verilen scope'lar.

is_confidential   boolean  optional    

Backend (secret) mi SPA (PKCE) mi. Example: true

accept_policy   boolean     

Politika onayı. Example: true

OAuth client güncelle (yalnızca sahibi; issues_sanctum_token değiştirilemez).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"redirect_uris\": [
        \"amniihfqcoynlazghdtqt\"
    ],
    \"is_active\": true
}"
const url = new URL(
    "https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "redirect_uris": [
        "amniihfqcoynlazghdtqt"
    ],
    "is_active": true
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'redirect_uris' => [
                'amniihfqcoynlazghdtqt',
            ],
            'is_active' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/me/oauth/clients/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

OAuth client ID'si (dosc_ önekli). Example: dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

Body Parameters

name   string  optional    

Must not be greater than 120 characters. Example: vmqeopfuudtdsufvyvddq

redirect_uris   string[]  optional    

Must not be greater than 500 characters.

allowed_scopes   string[]  optional    
is_active   boolean  optional    

Example: true

Client secret'ı yenile; yeni plain secret yalnızca bu response'ta bir kez döner.

Example request:
curl --request POST \
    "https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4/rotate-secret"
const url = new URL(
    "https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4/rotate-secret"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4/rotate-secret';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/me/oauth/clients/{id}/rotate-secret

URL Parameters

id   string     

OAuth client ID'si (dosc_ önekli). Example: dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

OAuth client'ı devre dışı bırak (is_active=false + revoked_at, kayıt silinmez).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
const url = new URL(
    "https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/oauth/clients/dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/me/oauth/clients/{id}

URL Parameters

id   string     

OAuth client ID'si (dosc_ önekli). Example: dosc_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4

Geliştirici — Sürüm Notları

Yayınlanmış API changelog'u (developer modülü olanlar okur). Yazma/yayınlama superadmin'dedir (App\Http\Controllers\Api\Admin\ChangelogController). Eski statik gelistirici-rehberi.md § 13'ün dinamik yerini alır. İç alanlar (auto_added/ auto_removed/git_commits) DIŞA SIZMAZ — sadece version/summary/entries döner.

Yayınlanmış sürüm notları

requires authentication

Arama + sayfalama opsiyoneldir ve GERİYE UYUMLUDUR: page parametresi GÖNDERİLMEZSE eski davranış aynen korunur (son 100 kayıt, düz dizi). page gönderilirse yanıt meta bloğu içerir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/developer/changelog?q=santral&page=1&per_page=10" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/developer/changelog"
);

const params = {
    "q": "santral",
    "page": "1",
    "per_page": "10",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/developer/changelog';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
        'query' => [
            'q' => 'santral',
            'page' => '1',
            'per_page' => '10',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Sayfalı (page verildi)):


{
    "data": [
        {
            "version": "2026.06.12.3",
            "summary": "Santral / Canlı Çağrı Aktarımı...",
            "entries": [
                {
                    "type": "added",
                    "scope": "Voice",
                    "description": "Aktarım rehberi CRUD eklendi"
                }
            ],
            "released_at": "2026-06-12T17:30:00.000000Z"
        }
    ],
    "meta": {
        "current_page": 1,
        "last_page": 2,
        "per_page": 10,
        "total": 14
    }
}
 

Example response (200, Eski davranış (page yok)):


{
    "data": [
        {
            "version": "2026.06.07.1",
            "summary": "Pazarlama uyum gate'i + İYS API'leri",
            "entries": [
                {
                    "type": "added",
                    "scope": "İYS",
                    "description": "iys/consents + iys/accounts endpoint'leri eklendi"
                }
            ],
            "released_at": "2026-06-07T12:00:00.000000Z"
        }
    ]
}
 

Request      

GET api/developer/changelog

Headers

Authorization        

Example: Bearer {TOKEN}

Query Parameters

q   string  optional    

Arama — sürüm no, özet ve madde metinlerinde geçen ifade. Example: santral

page   integer  optional    

Sayfa numarası (verilirse yanıt sayfalı olur + meta döner). Example: 1

per_page   integer  optional    

Sayfa boyutu (1-50, default 10). Example: 10

OAuth 2.0 / SSO

Token endpoint — 3. taraf backend'in dowaba access+refresh+id_token aldığı yer. RFC 6749 §3.2. Genelde application/x-www-form-urlencoded body bekler; Laravel'in input() kapsayıcısı JSON'u da kabul eder, ikisi de OK.

POST /api/oauth/token

grant_type=authorization_code: client_id, [client_secret], code, redirect_uri, code_verifier

grant_type=refresh_token: client_id, [client_secret], refresh_token

Example request:
curl --request POST \
    "https://dowaba.com/api/oauth/token" \
    --header "Content-Type: application/json" \
    --data "{
    \"grant_type\": \"authorization_code\",
    \"client_id\": \"dosc_abc123xyz\",
    \"client_secret\": \"dosec_secret_value_here\",
    \"code\": \"4c8d9e2f1a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b\",
    \"redirect_uri\": \"https:\\/\\/example.com\\/oauth\\/callback\",
    \"code_verifier\": \"M25iVXpKU3puUjFaYWg3T1NDTDQtcW1ROUY5YXlwalNoc0hhakxiNGZi\",
    \"refresh_token\": \"dort_refresh_token_value_64_chars_here\"
}"
const url = new URL(
    "https://dowaba.com/api/oauth/token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "grant_type": "authorization_code",
    "client_id": "dosc_abc123xyz",
    "client_secret": "dosec_secret_value_here",
    "code": "4c8d9e2f1a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b",
    "redirect_uri": "https:\/\/example.com\/oauth\/callback",
    "code_verifier": "M25iVXpKU3puUjFaYWg3T1NDTDQtcW1ROUY5YXlwalNoc0hhakxiNGZi",
    "refresh_token": "dort_refresh_token_value_64_chars_here"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/oauth/token';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'grant_type' => 'authorization_code',
            'client_id' => 'dosc_abc123xyz',
            'client_secret' => 'dosec_secret_value_here',
            'code' => '4c8d9e2f1a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b',
            'redirect_uri' => 'https://example.com/oauth/callback',
            'code_verifier' => 'M25iVXpKU3puUjFaYWg3T1NDTDQtcW1ROUY5YXlwalNoc0hhakxiNGZi',
            'refresh_token' => 'dort_refresh_token_value_64_chars_here',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Başarılı (authorization_code)):


{
    "access_token": "[REDACTED]",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "[REDACTED]",
    "scope": "openid profile email",
    "id_token": "[REDACTED]"
}
 

Example response (200, Başarılı (refresh_token rotation)):


{
    "access_token": "[REDACTED]",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "[REDACTED]",
    "scope": "openid profile email",
    "id_token": "[REDACTED]"
}
 

Example response (400, Authorization code süresi dolmuş veya kullanılmış):


{
    "error": "invalid_grant",
    "error_description": "authorization_code geçersiz, kullanılmış veya süresi dolmuş"
}
 

Example response (400, PKCE verifier eşleşmiyor):


{
    "error": "invalid_grant",
    "error_description": "PKCE code_verifier eşleşmiyor"
}
 

Example response (400, Client secret hatalı):


{
    "error": "invalid_grant",
    "error_description": "client_secret hatalı"
}
 

Example response (400, grant_type desteklenmiyor):


{
    "error": "unsupported_grant_type",
    "error_description": "Desteklenmeyen grant_type"
}
 

Request      

POST api/oauth/token

Headers

Content-Type        

Example: application/json

Body Parameters

grant_type   string     

"authorization_code" veya "refresh_token". Example: authorization_code

client_id   string     

Client ID (dosc_...). Example: dosc_abc123xyz

client_secret   string  optional    

Client secret — sadece confidential client. Example: dosec_secret_value_here

code   string  optional    

Authorization code (grant_type=authorization_code). Example: 4c8d9e2f1a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b

redirect_uri   string  optional    

Authorize'da kullanılan URI (aynısı). Example: https://example.com/oauth/callback

code_verifier   string  optional    

PKCE verifier (grant_type=authorization_code, 43-128 char URL-safe). Example: M25iVXpKU3puUjFaYWg3T1NDTDQtcW1ROUY5YXlwalNoc0hhakxiNGZi

refresh_token   string  optional    

grant_type=refresh_token için. Example: dort_refresh_token_value_64_chars_here

POST /api/oauth/revoke

Example request:
curl --request POST \
    "https://dowaba.com/api/oauth/revoke" \
    --header "Content-Type: application/json" \
    --data "{
    \"token\": \"doat_access_token_value_48_chars_here\"
}"
const url = new URL(
    "https://dowaba.com/api/oauth/revoke"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "token": "doat_access_token_value_48_chars_here"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/oauth/revoke';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'token' => 'doat_access_token_value_48_chars_here',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Her zaman 200 — RFC 7009 sızıntı önleme):


{
    "revoked": true
}
 

Example response (400, token param eksik):


{
    "error": "invalid_request",
    "error_description": "token zorunlu"
}
 

Request      

POST api/oauth/revoke

Headers

Content-Type        

Example: application/json

Body Parameters

token   string     

Access (doat_...) veya refresh (dort_...) token. Example: doat_access_token_value_48_chars_here

GET /api/oauth/userinfo

Example request:
curl --request GET \
    --get "https://dowaba.com/api/oauth/userinfo" \
    --header "Authorization: Bearer doat_..."
const url = new URL(
    "https://dowaba.com/api/oauth/userinfo"
);

const headers = {
    "Authorization": "Bearer doat_...",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/oauth/userinfo';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer doat_...',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "sub": "42",
    "email": "u***@example.com",
    "email_verified": true,
    "name": "Ali",
    "picture": "https://...",
    "preferred_username": "user@example.com"
}
 

Example response (401):


{
    "error": "invalid_token"
}
 

Request      

GET api/oauth/userinfo

Headers

Authorization        

Example: Bearer doat_...

Continuation token'ı çöz → client + scopes + state + (varsa) auth user.

Vue admin sayfası bunu çağırır. auth:sanctum istenmeden çalışır — token yoksa requires_login=true döner, frontend login'e yönlendirir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/oauth/authorize/state?ct=K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg"
const url = new URL(
    "https://dowaba.com/api/oauth/authorize/state"
);

const params = {
    "ct": "K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/oauth/authorize/state';
$response = $client->get(
    $url,
    [
        'query' => [
            'ct' => 'K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Login değil — frontend /admin/login?continuation=ct'ye yönlenir):


{
    "requires_login": true,
    "client": {
        "id": "dosc_abc123xyz",
        "name": "Test Site",
        "description": "Örnek 3. taraf uygulama",
        "logo_url": null,
        "homepage_url": "https://example.com"
    },
    "scopes": [
        "openid",
        "profile",
        "email"
    ],
    "scope_descriptions": {
        "openid": "OpenID Connect kimlik doğrulama",
        "profile": "Ad, soyad ve profil resminize erişim",
        "email": "E-posta adresinize erişim"
    },
    "redirect_uri": "https://example.com/oauth/callback",
    "user": null
}
 

Example response (200, Login + consent ekranı göster):


{
    "requires_login": false,
    "client": {
        "id": "dosc_abc123xyz",
        "name": "Test Site",
        "description": "Örnek 3. taraf uygulama",
        "logo_url": null,
        "homepage_url": "https://example.com"
    },
    "scopes": [
        "openid",
        "profile",
        "email"
    ],
    "scope_descriptions": {
        "openid": "OpenID Connect kimlik doğrulama",
        "profile": "Ad, soyad ve profil resminize erişim",
        "email": "E-posta adresinize erişim"
    },
    "redirect_uri": "https://example.com/oauth/callback",
    "user": {
        "id": 42,
        "name": "Test Kullanıcı",
        "email": "u***@example.com",
        "avatar_url": null
    }
}
 

Example response (410, Continuation süresi dolmuş veya geçersiz):


{
    "error": "continuation_expired"
}
 

Example response (422, ct param eksik):


{
    "error": "ct param zorunlu"
}
 

Request      

GET api/oauth/authorize/state

Query Parameters

ct   string     

Continuation token. Example: K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg

Kullanıcı [İzin Ver] basar — authorization_code üretip redirect_uri'ye yönlendirilecek URL'i döndür. Frontend bunu alır, window.location = .

requires authentication

..

Example request:
curl --request POST \
    "https://dowaba.com/api/oauth/authorize/approve" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"ct\": \"K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg\"
}"
const url = new URL(
    "https://dowaba.com/api/oauth/authorize/approve"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ct": "K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/oauth/authorize/approve';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ct' => 'K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, İzin verildi):


{
    "redirect_to": "https://example.com/oauth/callback?code=4c8d9e2f1a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b&state=Xq2Pn8mLwTyR6"
}
 

Example response (401, Kullanıcı authenticate değil):


{
    "error": "unauthenticated"
}
 

Example response (410, Continuation süresi dolmuş):


{
    "error": "continuation_expired"
}
 

Example response (410, Client askıya alınmış):


{
    "error": "client_invalid"
}
 

Request      

POST api/oauth/authorize/approve

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

ct   string     

Continuation token (state endpoint'inden gelen). Example: K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg

Kullanıcı [Reddet] basar — redirect_uri'ye `?error=access_denied` (RFC 6749 §4.1.2.1).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/oauth/authorize/deny" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"ct\": \"K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg\"
}"
const url = new URL(
    "https://dowaba.com/api/oauth/authorize/deny"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ct": "K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/oauth/authorize/deny';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'ct' => 'K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200, Reddedildi):


{
    "redirect_to": "https://example.com/oauth/callback?error=access_denied&error_description=Kullan%C4%B1c%C4%B1+izni+reddetti&state=Xq2Pn8mLwTyR6"
}
 

Example response (410, Continuation süresi dolmuş):


{
    "error": "continuation_expired"
}
 

Request      

POST api/oauth/authorize/deny

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

Body Parameters

ct   string     

Continuation token. Example: K3xY9wZ4abC8defG12hIjKLmNopQR3sT_uvW_xYz0aBcD_eFg

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/oauth/login-link" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/oauth/login-link"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/oauth/login-link';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "success": true,
    "url": "https://msg724.com/admin/impersonate?token=...",
    "expires_at": "2026-06-17T12:05:00+00:00",
    "expires_in_seconds": 300
}
 

Example response (403):


{
    "success": false,
    "message": "Bu uç yalnız OAuth Trusted Partner token ile çağrılabilir."
}
 

Bayi Satış Paketleri

Bayi (role=reseller) kendi müşterisine satmak için PAKET tanımlar (ad, açıklama, fiyat, özellikler). SUNUM katmanıdır — subscription_plans'a dokunmaz, kota/site açmayı OTOMATİK TETİKLEMEZ (bayi müşterisini/sitesini mevcut akışla kendi açar). Yayınlanan paketler bayinin custom domain'inde public /paketler vitrininde görünür (PublicPackagesController).

Tüm uçlar 'reseller' middleware'i altında (role=reseller + sözleşme). Sahiplik: paket.reseller_id == auth.id. Bayi sub-user'ları GÖRMEZ (Aydın kararı 2026-07-02) — sadece bayi owner.

Bayinin tüm paketleri (taslak + yayınlı), sıralı.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/packages"
const url = new URL(
    "https://dowaba.com/api/reseller/packages"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/packages';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/packages

POST api/reseller/packages

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/packages"
const url = new URL(
    "https://dowaba.com/api/reseller/packages"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/packages';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/packages

Açıklamayı AI ile güzelleştir (KAYDETMEZ — sonucu döndürür, kullanıcı editörde onaylar).

Anahtar: önce bayi kredisi → yoksa kendi Gemini key (ResellerPackageCopyService).

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/packages/ai-improve" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"features\": [
        \"amniihfqcoynlazghdtqt\"
    ],
    \"description\": \"Necessitatibus architecto aut consequatur debitis et id.\",
    \"instruction\": \"ilpmufinllwloauydlsms\"
}"
const url = new URL(
    "https://dowaba.com/api/reseller/packages/ai-improve"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "features": [
        "amniihfqcoynlazghdtqt"
    ],
    "description": "Necessitatibus architecto aut consequatur debitis et id.",
    "instruction": "ilpmufinllwloauydlsms"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/packages/ai-improve';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'features' => [
                'amniihfqcoynlazghdtqt',
            ],
            'description' => 'Necessitatibus architecto aut consequatur debitis et id.',
            'instruction' => 'ilpmufinllwloauydlsms',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/packages/ai-improve

Headers

Content-Type        

Example: application/json

Body Parameters

name   string  optional    

Must not be greater than 200 characters. Example: vmqeopfuudtdsufvyvddq

type   string  optional    
features   string[]  optional    

Must not be greater than 200 characters.

description   string  optional    

Must not be greater than 20000 characters. Example: Necessitatibus architecto aut consequatur debitis et id.

instruction   string  optional    

Must not be greater than 2000 characters. Example: ilpmufinllwloauydlsms

PUT api/reseller/packages/{package_id}

Example request:
curl --request PUT \
    "https://dowaba.com/api/reseller/packages/1"
const url = new URL(
    "https://dowaba.com/api/reseller/packages/1"
);



fetch(url, {
    method: "PUT",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/packages/1';
$response = $client->put($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/reseller/packages/{package_id}

URL Parameters

package_id   integer     

The ID of the package. Example: 1

Yayın durumunu değiştir (taslak ↔ yayınlı).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/packages/1/publish" \
    --header "Content-Type: application/json" \
    --data "{
    \"is_published\": false
}"
const url = new URL(
    "https://dowaba.com/api/reseller/packages/1/publish"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "is_published": false
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/packages/1/publish';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'is_published' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/packages/{package_id}/publish

Headers

Content-Type        

Example: application/json

URL Parameters

package_id   integer     

The ID of the package. Example: 1

Body Parameters

is_published   boolean     

Example: false

DELETE api/reseller/packages/{package_id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/reseller/packages/1"
const url = new URL(
    "https://dowaba.com/api/reseller/packages/1"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/packages/1';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/reseller/packages/{package_id}

URL Parameters

package_id   integer     

The ID of the package. Example: 1

İki sağlayıcının da mevcut ayarını döndür (secret'sız — sadece "kayıtlı mı" bayrağı).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/payment-gateways"
const url = new URL(
    "https://dowaba.com/api/reseller/payment-gateways"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/payment-gateways';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/payment-gateways

Bir sağlayıcının kimlik bilgilerini kaydet/güncelle (boş secret gönderilirse KORUNUR).

Example request:
curl --request PUT \
    "https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico" \
    --header "Content-Type: application/json" \
    --data "{
    \"merchant_id\": \"vmqeopfuudtdsufvyvddq\",
    \"merchant_key\": \"amniihfqcoynlazghdtqt\",
    \"merchant_salt\": \"qxbajwbpilpmufinllwlo\",
    \"api_key\": \"auydlsmsjuryvojcybzvr\",
    \"secret_key\": \"byickznkygloigmkwxphl\",
    \"test_mode\": true,
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "merchant_id": "vmqeopfuudtdsufvyvddq",
    "merchant_key": "amniihfqcoynlazghdtqt",
    "merchant_salt": "qxbajwbpilpmufinllwlo",
    "api_key": "auydlsmsjuryvojcybzvr",
    "secret_key": "byickznkygloigmkwxphl",
    "test_mode": true,
    "is_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'merchant_id' => 'vmqeopfuudtdsufvyvddq',
            'merchant_key' => 'amniihfqcoynlazghdtqt',
            'merchant_salt' => 'qxbajwbpilpmufinllwlo',
            'api_key' => 'auydlsmsjuryvojcybzvr',
            'secret_key' => 'byickznkygloigmkwxphl',
            'test_mode' => true,
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/reseller/payment-gateways/{provider}

Headers

Content-Type        

Example: application/json

URL Parameters

provider   string     

Example: paytr|iyzico

Body Parameters

merchant_id   string  optional    

Must not be greater than 64 characters. Example: vmqeopfuudtdsufvyvddq

merchant_key   string  optional    

Must not be greater than 255 characters. Example: amniihfqcoynlazghdtqt

merchant_salt   string  optional    

Must not be greater than 255 characters. Example: qxbajwbpilpmufinllwlo

api_key   string  optional    

Must not be greater than 255 characters. Example: auydlsmsjuryvojcybzvr

secret_key   string  optional    

Must not be greater than 255 characters. Example: byickznkygloigmkwxphl

test_mode   boolean  optional    

Example: true

is_active   boolean  optional    

Example: false

Canlı bağlantı testi — geçici (kaydedilmeyen) sipariş ile gateway'e istek atar.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico/test"
const url = new URL(
    "https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico/test"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico/test';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/payment-gateways/{provider}/test

URL Parameters

provider   string     

Example: paytr|iyzico

Bu sağlayıcıyı varsayılan sanal POS yap (aktifleştirir, diğerinin default'unu kapatır).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico/default"
const url = new URL(
    "https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico/default"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/payment-gateways/paytr|iyzico/default';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/payment-gateways/{provider}/default

URL Parameters

provider   string     

Example: paytr|iyzico

GET api/reseller/bank-accounts

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/bank-accounts"
const url = new URL(
    "https://dowaba.com/api/reseller/bank-accounts"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/bank-accounts';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/bank-accounts

POST api/reseller/bank-accounts

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/bank-accounts"
const url = new URL(
    "https://dowaba.com/api/reseller/bank-accounts"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/bank-accounts';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/bank-accounts

PUT api/reseller/bank-accounts/{bankAccount_id}

Example request:
curl --request PUT \
    "https://dowaba.com/api/reseller/bank-accounts/17"
const url = new URL(
    "https://dowaba.com/api/reseller/bank-accounts/17"
);



fetch(url, {
    method: "PUT",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/bank-accounts/17';
$response = $client->put($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/reseller/bank-accounts/{bankAccount_id}

URL Parameters

bankAccount_id   integer     

The ID of the bankAccount. Example: 17

PATCH api/reseller/bank-accounts/{bankAccount_id}/default

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/bank-accounts/17/default"
const url = new URL(
    "https://dowaba.com/api/reseller/bank-accounts/17/default"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/bank-accounts/17/default';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/bank-accounts/{bankAccount_id}/default

URL Parameters

bankAccount_id   integer     

The ID of the bankAccount. Example: 17

DELETE api/reseller/bank-accounts/{bankAccount_id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/reseller/bank-accounts/17"
const url = new URL(
    "https://dowaba.com/api/reseller/bank-accounts/17"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/bank-accounts/17';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/reseller/bank-accounts/{bankAccount_id}

URL Parameters

bankAccount_id   integer     

The ID of the bankAccount. Example: 17

GET api/reseller/orders

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/orders"
const url = new URL(
    "https://dowaba.com/api/reseller/orders"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/orders';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/orders

Havale/EFT siparişinde "Ödemeyi Aldım" — bekleyen havale siparişini paid'e çevirir.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/orders/17/paid"
const url = new URL(
    "https://dowaba.com/api/reseller/orders/17/paid"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/orders/17/paid';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/orders/{order_id}/paid

URL Parameters

order_id   integer     

The ID of the order. Example: 17

Ödemesi gelmiş siparişi "teslim edildi" işaretle (bayi müşteriyi/siteyi elle açtıktan sonra).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/orders/17/fulfill"
const url = new URL(
    "https://dowaba.com/api/reseller/orders/17/fulfill"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/orders/17/fulfill';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/orders/{order_id}/fulfill

URL Parameters

order_id   integer     

The ID of the order. Example: 17

Diğer Endpoint'ler

POST api/partner-applications

Example request:
curl --request POST \
    "https://dowaba.com/api/partner-applications" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"email\": \"kunde.eloisa@example.com\",
    \"phone\": \"hfqcoynlazghdtqtqxbaj\",
    \"company\": \"wbpilpmufinllwloauydl\",
    \"profession\": \"smsjuryvojcybzvrbyick\",
    \"website\": \"znkygloigmkwxphlvazjr\",
    \"experience\": \"cnfbaqywuxhgjjmzuxjub\",
    \"references_past\": \"qouzswiwxtrkimfcatbxs\",
    \"references_offer\": \"pzmrazsroyjpxmqesedyg\",
    \"message\": \"henqcopwvownkbamlnfng\",
    \"consent\": true
}"
const url = new URL(
    "https://dowaba.com/api/partner-applications"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "email": "kunde.eloisa@example.com",
    "phone": "hfqcoynlazghdtqtqxbaj",
    "company": "wbpilpmufinllwloauydl",
    "profession": "smsjuryvojcybzvrbyick",
    "website": "znkygloigmkwxphlvazjr",
    "experience": "cnfbaqywuxhgjjmzuxjub",
    "references_past": "qouzswiwxtrkimfcatbxs",
    "references_offer": "pzmrazsroyjpxmqesedyg",
    "message": "henqcopwvownkbamlnfng",
    "consent": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/partner-applications';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'email' => 'kunde.eloisa@example.com',
            'phone' => 'hfqcoynlazghdtqtqxbaj',
            'company' => 'wbpilpmufinllwloauydl',
            'profession' => 'smsjuryvojcybzvrbyick',
            'website' => 'znkygloigmkwxphlvazjr',
            'experience' => 'cnfbaqywuxhgjjmzuxjub',
            'references_past' => 'qouzswiwxtrkimfcatbxs',
            'references_offer' => 'pzmrazsroyjpxmqesedyg',
            'message' => 'henqcopwvownkbamlnfng',
            'consent' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/partner-applications

Headers

Content-Type        

Example: application/json

Body Parameters

name   string     

value alanı 150 karakterden uzun olmamalıdır. Example: vmqeopfuudtdsufvyvddq

email   string     

value alanı geçerli bir e-posta adresi olmalıdır. value alanı 190 karakterden uzun olmamalıdır. Example: kunde.eloisa@example.com

phone   string     

value alanı 40 karakterden uzun olmamalıdır. Example: hfqcoynlazghdtqtqxbaj

company   string  optional    

value alanı 150 karakterden uzun olmamalıdır. Example: wbpilpmufinllwloauydl

profession   string     

value alanı 120 karakterden uzun olmamalıdır. Example: smsjuryvojcybzvrbyick

website   string  optional    

value alanı 255 karakterden uzun olmamalıdır. Example: znkygloigmkwxphlvazjr

experience   string     

value alanı 5000 karakterden uzun olmamalıdır. Example: cnfbaqywuxhgjjmzuxjub

references_past   string  optional    

value alanı 5000 karakterden uzun olmamalıdır. Example: qouzswiwxtrkimfcatbxs

references_offer   string     

value alanı 5000 karakterden uzun olmamalıdır. Example: pzmrazsroyjpxmqesedyg

message   string  optional    

value alanı 5000 karakterden uzun olmamalıdır. Example: henqcopwvownkbamlnfng

consent   boolean     

Must be accepted. Example: true

GET /sites/{site}/channel-prompt/{channel}

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/1/channel-prompt/whatsapp"
const url = new URL(
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/channel-prompt/whatsapp';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/sites/{site_id}/channel-prompt/{channel}

URL Parameters

site_id   integer     

The ID of the site. Example: 1

channel   string     

Kanal anahtarı (whatsapp, instagram, telegram, messenger, tiktok, widget, x, mail, voice, google_reviews). Example: whatsapp

PUT /sites/{site}/channel-prompt/{channel}

Example request:
curl --request PUT \
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp" \
    --header "Content-Type: application/json" \
    --data "{
    \"channel_prompt\": \"vmqeopfuudtdsufvyvddq\",
    \"system_prompt\": \"amniihfqcoynlazghdtqt\",
    \"save_system\": true
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "channel_prompt": "vmqeopfuudtdsufvyvddq",
    "system_prompt": "amniihfqcoynlazghdtqt",
    "save_system": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/channel-prompt/whatsapp';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'channel_prompt' => 'vmqeopfuudtdsufvyvddq',
            'system_prompt' => 'amniihfqcoynlazghdtqt',
            'save_system' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/sites/{site_id}/channel-prompt/{channel}

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

channel   string     

Kanal anahtarı (whatsapp, instagram, telegram, messenger, tiktok, widget, x, mail, voice, google_reviews). Example: whatsapp

Body Parameters

channel_prompt   string  optional    

Must not be greater than 20000 characters. Example: vmqeopfuudtdsufvyvddq

system_prompt   string  optional    

Must not be greater than 50000 characters. Example: amniihfqcoynlazghdtqt

save_system   boolean  optional    

Example: true

POST /sites/{site}/channel-prompt/{channel}/analyze

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp/analyze"
const url = new URL(
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp/analyze"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/channel-prompt/whatsapp/analyze';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/channel-prompt/{channel}/analyze

URL Parameters

site_id   integer     

The ID of the site. Example: 1

channel   string     

Kanal anahtarı (whatsapp, instagram, telegram, messenger, tiktok, widget, x, mail, voice, google_reviews). Example: whatsapp

POST /sites/{site}/channel-prompt/{channel}/improve

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp/improve"
const url = new URL(
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp/improve"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/channel-prompt/whatsapp/improve';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/channel-prompt/{channel}/improve

URL Parameters

site_id   integer     

The ID of the site. Example: 1

channel   string     

Kanal anahtarı (whatsapp, instagram, telegram, messenger, tiktok, widget, x, mail, voice, google_reviews). Example: whatsapp

POST /sites/{site}/channel-prompt/{channel}/refine

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp/refine" \
    --header "Content-Type: application/json" \
    --data "{
    \"system_prompt\": \"vmqeopfuudtdsufvyvddq\",
    \"channel_prompt\": \"amniihfqcoynlazghdtqt\",
    \"instruction\": \"qxbajwbpilpmufinllwlo\",
    \"target\": \"both\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/channel-prompt/whatsapp/refine"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "system_prompt": "vmqeopfuudtdsufvyvddq",
    "channel_prompt": "amniihfqcoynlazghdtqt",
    "instruction": "qxbajwbpilpmufinllwlo",
    "target": "both"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/channel-prompt/whatsapp/refine';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'system_prompt' => 'vmqeopfuudtdsufvyvddq',
            'channel_prompt' => 'amniihfqcoynlazghdtqt',
            'instruction' => 'qxbajwbpilpmufinllwlo',
            'target' => 'both',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/channel-prompt/{channel}/refine

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

channel   string     

Kanal anahtarı (whatsapp, instagram, telegram, messenger, tiktok, widget, x, mail, voice, google_reviews). Example: whatsapp

Body Parameters

system_prompt   string  optional    

Must not be greater than 50000 characters. Example: vmqeopfuudtdsufvyvddq

channel_prompt   string  optional    

Must not be greater than 20000 characters. Example: amniihfqcoynlazghdtqt

instruction   string     

Must not be greater than 2000 characters. Example: qxbajwbpilpmufinllwlo

target   string  optional    

Example: both

Must be one of:
  • system
  • channel
  • both

POST /sites/{site}/prompt-health HOLİSTİK: sistem promtu × TÜM kanal doğaları. "Şu talimat şu kanalda yanlış, şu kanala taşı" — dashboard "Promt Sağlığı" kartının motoru. Kanal promtuna bağlı DEĞİL → channelSupported gate'i yok, yalnız feature gate.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/prompt-health" \
    --header "Content-Type: application/json" \
    --data "{
    \"system_prompt\": \"vmqeopfuudtdsufvyvddq\",
    \"channels\": [
        \"consequatur\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/prompt-health"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "system_prompt": "vmqeopfuudtdsufvyvddq",
    "channels": [
        "consequatur"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/prompt-health';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'system_prompt' => 'vmqeopfuudtdsufvyvddq',
            'channels' => [
                'consequatur',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/prompt-health

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

system_prompt   string  optional    

Must not be greater than 50000 characters. Example: vmqeopfuudtdsufvyvddq

channels   string[]  optional    

POST /sites/{site}/prompt-health/distribute GENEL/bütünsel düzenleme (ADIM 2): sistem promtunu atomlara bölüp kanal-bağımsız çekirdek + kanal-özel eklemelere DAĞITIR. Önizleme üretir — CANLIYA YAZMAZ.

Sonuç site-seviye _distribution.json workspace'e cache'lenir.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/prompt-health/distribute" \
    --header "Content-Type: application/json" \
    --data "{
    \"system_prompt\": \"vmqeopfuudtdsufvyvddq\",
    \"channels\": [
        \"consequatur\"
    ],
    \"findings\": [
        {
            \"channel\": \"whatsapp\"
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/prompt-health/distribute"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "system_prompt": "vmqeopfuudtdsufvyvddq",
    "channels": [
        "consequatur"
    ],
    "findings": [
        {
            "channel": "whatsapp"
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/prompt-health/distribute';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'system_prompt' => 'vmqeopfuudtdsufvyvddq',
            'channels' => [
                'consequatur',
            ],
            'findings' => [
                [
                    'channel' => 'whatsapp',
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/prompt-health/distribute

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

system_prompt   string  optional    

Must not be greater than 50000 characters. Example: vmqeopfuudtdsufvyvddq

channels   string[]  optional    
findings   object[]  optional    
channel   string  optional    

Bulgunun ait olduğu kanal. Example: whatsapp

violations   object  optional    

POST /sites/{site}/prompt-health/apply GENEL düzenlemeyi UYGULA (ADIM 3): kullanıcının incele/onayladığı NİHAİ metinleri yazar. TEK DB transaction, ALL-OR-NOTHING. core → settings.system_prompt (save_core, default AÇIK — GLOBAL); her kanal nihai metni → site_channel_prompts. Frontend birleştirmeyi (mevcut + additions) yapıp gözden geçirilmiş metni gönderir.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/prompt-health/apply" \
    --header "Content-Type: application/json" \
    --data "{
    \"core_system_prompt\": \"vmqeopfuudtdsufvyvddq\",
    \"save_core\": false,
    \"channels\": [
        {
            \"channel\": \"whatsapp\",
            \"prompt\": \"mqeopfuudtdsufvyvddqa\"
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/prompt-health/apply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "core_system_prompt": "vmqeopfuudtdsufvyvddq",
    "save_core": false,
    "channels": [
        {
            "channel": "whatsapp",
            "prompt": "mqeopfuudtdsufvyvddqa"
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/prompt-health/apply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'core_system_prompt' => 'vmqeopfuudtdsufvyvddq',
            'save_core' => false,
            'channels' => [
                [
                    'channel' => 'whatsapp',
                    'prompt' => 'mqeopfuudtdsufvyvddqa',
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/prompt-health/apply

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

core_system_prompt   string  optional    

Must not be greater than 50000 characters. Example: vmqeopfuudtdsufvyvddq

save_core   boolean  optional    

Example: false

channels   object[]  optional    
channel   string     

Promtu yazılacak kanal. Example: whatsapp

prompt   string  optional    

Must not be greater than 20000 characters. Example: mqeopfuudtdsufvyvddqa

POST /sites/{site}/prompt-chat Sistem promtu oluşturma SOHBET asistanı (sektör-önce, kanal-bağımsız).

Stateless çok-turlu: messages + draft → {reply, updated_prompt, done}.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/prompt-chat" \
    --header "Content-Type: application/json" \
    --data "{
    \"draft\": \"vmqeopfuudtdsufvyvddq\",
    \"locale\": \"af_NA\",
    \"messages\": [
        {
            \"role\": \"user\",
            \"content\": \"mqeopfuudtdsufvyvddqa\"
        }
    ]
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/prompt-chat"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "draft": "vmqeopfuudtdsufvyvddq",
    "locale": "af_NA",
    "messages": [
        {
            "role": "user",
            "content": "mqeopfuudtdsufvyvddqa"
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/prompt-chat';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'draft' => 'vmqeopfuudtdsufvyvddq',
            'locale' => 'af_NA',
            'messages' => [
                [
                    'role' => 'user',
                    'content' => 'mqeopfuudtdsufvyvddqa',
                ],
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/prompt-chat

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

messages   object[]  optional    
role   string  optional    

Mesaj rolü (user veya assistant). Example: user

content   string  optional    

Must not be greater than 8000 characters. Example: mqeopfuudtdsufvyvddqa

draft   string  optional    

Must not be greater than 50000 characters. Example: vmqeopfuudtdsufvyvddq

locale   string  optional    

Must not be greater than 8 characters. Example: af_NA

Kullanıcının KENDİ abonelik faturaları (Paraşüt e-fatura/e-arşiv) — 2026-06-06.

Sadece kendi adına aldığı paketler (sold_by_reseller_id NULL). Bayinin müşterilerine sattığı reseller-site lisansları HARİÇ — onlar /reseller/invoices ekranında.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/invoices"
const url = new URL(
    "https://dowaba.com/api/subscriptions/invoices"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/invoices';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscriptions/invoices

Kendi faturanın PDF'ini indir. Ownership: subscription.user_id === auth.id.

PDF cron (15dk) tarafından JuiceFS'e çekilmiş olmalı; hazır değilse 404 + "işleniyor".

Example request:
curl --request GET \
    --get "https://dowaba.com/api/subscriptions/invoices/1/parasut-pdf"
const url = new URL(
    "https://dowaba.com/api/subscriptions/invoices/1/parasut-pdf"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/subscriptions/invoices/1/parasut-pdf';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/subscriptions/invoices/{subscription_id}/parasut-pdf

URL Parameters

subscription_id   integer     

The ID of the subscription. Example: 1

App, PushKit/FCM VoIP token'ını kaydeder/yeniler.

Example request:
curl --request POST \
    "https://dowaba.com/api/voip/register-token" \
    --header "Content-Type: application/json" \
    --data "{
    \"token\": \"vmqeopfuudtdsufvyvddq\",
    \"platform\": \"consequatur\",
    \"app_bundle\": \"mqeopfuudtdsufvyvddqa\",
    \"apns_production\": true
}"
const url = new URL(
    "https://dowaba.com/api/voip/register-token"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "token": "vmqeopfuudtdsufvyvddq",
    "platform": "consequatur",
    "app_bundle": "mqeopfuudtdsufvyvddqa",
    "apns_production": true
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voip/register-token';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'token' => 'vmqeopfuudtdsufvyvddq',
            'platform' => 'consequatur',
            'app_bundle' => 'mqeopfuudtdsufvyvddqa',
            'apns_production' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voip/register-token

Headers

Content-Type        

Example: application/json

Body Parameters

token   string     

Must not be greater than 255 characters. Example: vmqeopfuudtdsufvyvddq

platform   string     

Example: consequatur

app_bundle   string     

Must not be greater than 64 characters. Example: mqeopfuudtdsufvyvddqa

apns_production   boolean  optional    

Example: true

App, VoIP push'taki join-token ile aramaya katılım kimlik bilgilerini (ephemeral TURN) çeker.

Example request:
curl --request POST \
    "https://dowaba.com/api/voip/call/credentials" \
    --header "Content-Type: application/json" \
    --data "{
    \"join_token\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/voip/call/credentials"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "join_token": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voip/call/credentials';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'join_token' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voip/call/credentials

Headers

Content-Type        

Example: application/json

Body Parameters

join_token   string     

Must not be greater than 1024 characters. Example: vmqeopfuudtdsufvyvddq

App, WebRTC offer'ını gönderir → backend doğru node'un voip-app-bridge'ine proxy'ler → answer döner.

AUTH: auth:sanctum. Çağrı→kullanıcı bağı voip_route:{bridge_id} cache'inden (push anında bridge yazdı)

Body: {bridge_id, sdp_offer} (app ayrıca join_token gönderir — yok sayılır). Yanıt: {answer_sdp}.

Example request:
curl --request POST \
    "https://dowaba.com/api/voip/call/sdp" \
    --header "Content-Type: application/json" \
    --data "{
    \"bridge_id\": \"vmqeopfuudtdsufvyvddq\",
    \"sdp_offer\": \"amniihfqcoynlazghdtqt\"
}"
const url = new URL(
    "https://dowaba.com/api/voip/call/sdp"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "bridge_id": "vmqeopfuudtdsufvyvddq",
    "sdp_offer": "amniihfqcoynlazghdtqt"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voip/call/sdp';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'bridge_id' => 'vmqeopfuudtdsufvyvddq',
            'sdp_offer' => 'amniihfqcoynlazghdtqt',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voip/call/sdp

Headers

Content-Type        

Example: application/json

Body Parameters

bridge_id   string     

Must not be greater than 64 characters. Example: vmqeopfuudtdsufvyvddq

sdp_offer   string     

Must not be greater than 30000 characters. Example: amniihfqcoynlazghdtqt

"AI'ya geri ver" — app kullanıcısı görüşmeyi tekrar yapay zekaya devreder.

AUTH: auth:sanctum + route-store user binding. Bridge'e proxy → bridge sip-bridge'e resume işareti koyar + caller socket'i kapatır → dialplan arayanı tekrar AI'ya (:3457) bağlar.

Example request:
curl --request POST \
    "https://dowaba.com/api/voip/call/handback" \
    --header "Content-Type: application/json" \
    --data "{
    \"bridge_id\": \"vmqeopfuudtdsufvyvddq\"
}"
const url = new URL(
    "https://dowaba.com/api/voip/call/handback"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "bridge_id": "vmqeopfuudtdsufvyvddq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voip/call/handback';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'bridge_id' => 'vmqeopfuudtdsufvyvddq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voip/call/handback

Headers

Content-Type        

Example: application/json

Body Parameters

bridge_id   string     

Must not be greater than 64 characters. Example: vmqeopfuudtdsufvyvddq

mode   string  optional    

Giriş yapmış kullanıcının kendi başvuru durumu (BecomeResellerView gate).

GET /api/me/partner-application

Example request:
curl --request GET \
    --get "https://dowaba.com/api/me/partner-application"
const url = new URL(
    "https://dowaba.com/api/me/partner-application"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/me/partner-application';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/me/partner-application

GET api/customer-invoices/{invoice_id}/data

Example request:
curl --request GET \
    --get "https://dowaba.com/api/customer-invoices/1/data"
const url = new URL(
    "https://dowaba.com/api/customer-invoices/1/data"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/customer-invoices/1/data';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/customer-invoices/{invoice_id}/data

URL Parameters

invoice_id   integer     

The ID of the invoice. Example: 1

POST api/reseller/customers

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/customers" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"vmqeopfuudtdsufvyvddq\",
    \"name\": \"amniihfqcoynlazghdtqt\",
    \"email\": \"andreanne00@example.org\",
    \"allowed_modules\": [
        \"wbpilpmufinllwloauydl\"
    ]
}"
const url = new URL(
    "https://dowaba.com/api/reseller/customers"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "vmqeopfuudtdsufvyvddq",
    "name": "amniihfqcoynlazghdtqt",
    "email": "andreanne00@example.org",
    "allowed_modules": [
        "wbpilpmufinllwloauydl"
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/customers';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => 'vmqeopfuudtdsufvyvddq',
            'name' => 'amniihfqcoynlazghdtqt',
            'email' => 'andreanne00@example.org',
            'allowed_modules' => [
                'wbpilpmufinllwloauydl',
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/customers

Headers

Content-Type        

Example: application/json

Body Parameters

phone   string     

Must not be greater than 30 characters. Example: vmqeopfuudtdsufvyvddq

name   string  optional    

Must not be greater than 100 characters. Example: amniihfqcoynlazghdtqt

email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: andreanne00@example.org

allowed_modules   string[]  optional    

Must not be greater than 30 characters.

Bayinin tüm sattığı subscription'ları (status filter ile).

Query: ?status=pending|paid|all (default: all)

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/invoices"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/invoices

Seçilen subscription_ids için PayTR iframe token üret.

Body:

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/invoices/paytr-init" \
    --header "Content-Type: application/json" \
    --data "{
    \"subscription_ids\": [
        17
    ],
    \"phone\": \"mqeopfuudtdsufvyvddqa\",
    \"city\": \"mniihfqcoynlazghdtqtq\",
    \"district\": \"xbajwbpilpmufinllwloa\",
    \"address\": \"uydlsmsjuryvojcybzvrb\",
    \"tax_id\": \"yickznkygloigmkwxphlv\"
}"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices/paytr-init"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "subscription_ids": [
        17
    ],
    "phone": "mqeopfuudtdsufvyvddqa",
    "city": "mniihfqcoynlazghdtqtq",
    "district": "xbajwbpilpmufinllwloa",
    "address": "uydlsmsjuryvojcybzvrb",
    "tax_id": "yickznkygloigmkwxphlv"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices/paytr-init';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'subscription_ids' => [
                17,
            ],
            'phone' => 'mqeopfuudtdsufvyvddqa',
            'city' => 'mniihfqcoynlazghdtqtq',
            'district' => 'xbajwbpilpmufinllwloa',
            'address' => 'uydlsmsjuryvojcybzvrb',
            'tax_id' => 'yickznkygloigmkwxphlv',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/invoices/paytr-init

Headers

Content-Type        

Example: application/json

Body Parameters

subscription_ids   integer[]  optional    

The id of an existing record in the user_subscriptions table.

phone   string  optional    

Opsiyonel fatura bilgileri — kullanıcının User satırına kaydedilir. Must not be greater than 30 characters. Example: mqeopfuudtdsufvyvddqa

city   string  optional    

Must not be greater than 100 characters. Example: mniihfqcoynlazghdtqtq

district   string  optional    

Must not be greater than 100 characters. Example: xbajwbpilpmufinllwloa

address   string  optional    

Must not be greater than 500 characters. Example: uydlsmsjuryvojcybzvrb

tax_id   string  optional    

Must not be greater than 50 characters. Example: yickznkygloigmkwxphlv

"Havale yaptım" — bayi banka transferi yaptığını bildirir.

subscription.reseller_payment_status zaten 'pending' kalır; biz sadece bu olayı log'la + admin queue'ya bildirim atan bir işaretleme yaparız.

Body:

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/invoices/wire-claim" \
    --header "Content-Type: application/json" \
    --data "{
    \"subscription_ids\": [
        17
    ],
    \"reference\": \"mqeopfuudtdsufvyvddqa\",
    \"note\": \"mniihfqcoynlazghdtqtq\"
}"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices/wire-claim"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "subscription_ids": [
        17
    ],
    "reference": "mqeopfuudtdsufvyvddqa",
    "note": "mniihfqcoynlazghdtqtq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices/wire-claim';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'subscription_ids' => [
                17,
            ],
            'reference' => 'mqeopfuudtdsufvyvddqa',
            'note' => 'mniihfqcoynlazghdtqtq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/invoices/wire-claim

Headers

Content-Type        

Example: application/json

Body Parameters

subscription_ids   integer[]  optional    

The id of an existing record in the user_subscriptions table.

reference   string  optional    

Must not be greater than 80 characters. Example: mqeopfuudtdsufvyvddqa

note   string  optional    

Must not be greater than 500 characters. Example: mniihfqcoynlazghdtqtq

Bayi lisans faturası — Stripe Checkout (TR dışı / USD). PayTR'a paralel ama OTOMATİK (webhook reseller_license branch → markPaymentPaid). Tutar server-side hesaplanır.

Body: subscription_ids: [int, ...]

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/invoices/stripe-checkout" \
    --header "Content-Type: application/json" \
    --data "{
    \"subscription_ids\": [
        17
    ]
}"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices/stripe-checkout"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "subscription_ids": [
        17
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices/stripe-checkout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'subscription_ids' => [
                17,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/invoices/stripe-checkout

Headers

Content-Type        

Example: application/json

Body Parameters

subscription_ids   integer[]  optional    

The id of an existing record in the user_subscriptions table.

Bayi lisans faturası — PayPal (TR dışı / USD). Manuel: pending kayıt → kullanıcı paypal.me'den öder → "gönderdim" → admin /admin/paypal-payments'ten onaylar (PaypalManualService::approvePayment reseller_license branch → markPaymentPaid).

Body: subscription_ids: [int, ...]

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/invoices/paypal-initiate" \
    --header "Content-Type: application/json" \
    --data "{
    \"subscription_ids\": [
        17
    ]
}"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices/paypal-initiate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "subscription_ids": [
        17
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices/paypal-initiate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'subscription_ids' => [
                17,
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/invoices/paypal-initiate

Headers

Content-Type        

Example: application/json

Body Parameters

subscription_ids   integer[]  optional    

The id of an existing record in the user_subscriptions table.

Bir PayPal ödemesinin durumu (pending modal polling). Ownership guard.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/invoices/paypal-payments/1"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices/paypal-payments/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices/paypal-payments/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/invoices/paypal-payments/{payment_id}

URL Parameters

payment_id   integer     

The ID of the payment. Example: 1

Kullanıcı "PayPal ödememi gönderdim" → admin onayına düşer. Ownership guard.

Example request:
curl --request POST \
    "https://dowaba.com/api/reseller/invoices/paypal-payments/1/confirm-sent"
const url = new URL(
    "https://dowaba.com/api/reseller/invoices/paypal-payments/1/confirm-sent"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/invoices/paypal-payments/1/confirm-sent';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/reseller/invoices/paypal-payments/{payment_id}/confirm-sent

URL Parameters

payment_id   integer     

The ID of the payment. Example: 1

GET api/tiktok-profiles/{id}

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok-profiles/24"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles/24"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles/24';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok-profiles/{id}

URL Parameters

id   integer     

The ID of the tiktok profile. Example: 24

TikTok profilini güncelle.

Example request:
curl --request PUT \
    "https://dowaba.com/api/tiktok-profiles/24" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"is_active\": false,
    \"ai_bot_enabled\": false,
    \"comment_auto_reply_enabled\": true,
    \"tiktok_prompt\": \"Sen bir destek asistanısın\",
    \"use_faq\": true,
    \"notification_phone\": \"mqeopfuudtdsufvyv\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles/24"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "is_active": false,
    "ai_bot_enabled": false,
    "comment_auto_reply_enabled": true,
    "tiktok_prompt": "Sen bir destek asistanısın",
    "use_faq": true,
    "notification_phone": "mqeopfuudtdsufvyv"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles/24';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'is_active' => false,
            'ai_bot_enabled' => false,
            'comment_auto_reply_enabled' => true,
            'tiktok_prompt' => 'Sen bir destek asistanısın',
            'use_faq' => true,
            'notification_phone' => 'mqeopfuudtdsufvyv',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/tiktok-profiles/{id}

PATCH api/tiktok-profiles/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

The ID of the tiktok profile. Example: 24

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

is_active   boolean  optional    

Example: false

ai_bot_enabled   boolean  optional    

Example: false

comment_auto_reply_enabled   boolean  optional    

Example: true

tiktok_prompt   string  optional    

TikTok kanalına özel AI persona prompt'u (boşsa site varsayılanı kullanılır). Example: Sen bir destek asistanısın

use_faq   boolean  optional    

Example: true

notification_phone   string  optional    

Must not be greater than 20 characters. Example: mqeopfuudtdsufvyv

DELETE api/tiktok-profiles/{id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tiktok-profiles/24"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles/24"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles/24';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tiktok-profiles/{id}

URL Parameters

id   integer     

The ID of the tiktok profile. Example: 24

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok-profiles/24/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles/24/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles/24/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok-profiles/24/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles/24/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles/24/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

GET api/tiktok-profiles/{id}/linked-sites

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok-profiles/24/linked-sites"
const url = new URL(
    "https://dowaba.com/api/tiktok-profiles/24/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok-profiles/24/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok-profiles/{id}/linked-sites

URL Parameters

id   integer     

The ID of the tiktok profile. Example: 24

Kanal-bazlı AI bot aç/kapat ("Botu Durdur" / "Botu Başlat" — entegrasyon sayfası).

Konuşma bazlı toggleBot()'tan ayrıdır: profil seviyesinde tüm yorum/DM otomatik yanıtını durdurur. Yalnızca sahibi olduğunuz veya yetkilendirildiğiniz profiller değiştirilebilir. Yanıt anahtarı bot_active'tir (tüm kanal API'lerinde ortak).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/profiles/7/toggle-bot"
const url = new URL(
    "https://dowaba.com/api/tiktok/profiles/7/toggle-bot"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/profiles/7/toggle-bot';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/profiles/{id}/toggle-bot

URL Parameters

id   integer     

TikTok profilinin DB id'si. Example: 7

Yorum thread'i listesini getir.

?profile_id=X tek profile, yoksa user'in tum profilleri. ?search=foo display_name/username/text icinde arar.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/conversations"
const url = new URL(
    "https://dowaba.com/api/tiktok/conversations"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/conversations';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/conversations

Bir thread'in tum mesajlarini getir + okundu isaretle.

Composite key: video_id + commenter_open_id.

Tercih edilen çağrı: GET tiktok/conversation-messages?video_id=..&open_id=.. — open_id base64 olduğundan ("/" içerebilir) path'li form route'u ıskalayabilir (routes/api.php notu).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/conversation-messages?video_id=7345678901234567890&open_id=u-7f3a2b91c4"
const url = new URL(
    "https://dowaba.com/api/tiktok/conversation-messages"
);

const params = {
    "video_id": "7345678901234567890",
    "open_id": "u-7f3a2b91c4",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/conversation-messages';
$response = $client->get(
    $url,
    [
        'query' => [
            'video_id' => '7345678901234567890',
            'open_id' => 'u-7f3a2b91c4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/conversation-messages

URL Parameters

videoId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: 7345678901234567890

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

video_id   string  optional    

Thread'in TikTok video ID'si (query-param formda zorunlu). Example: 7345678901234567890

open_id   string  optional    

Yorumu yazan kullanıcının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

Bir thread'in tum mesajlarini getir + okundu isaretle.

Composite key: video_id + commenter_open_id.

Tercih edilen çağrı: GET tiktok/conversation-messages?video_id=..&open_id=.. — open_id base64 olduğundan ("/" içerebilir) path'li form route'u ıskalayabilir (routes/api.php notu).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/conversations/7345678901234567890/u-7f3a2b91c4/messages?video_id=7345678901234567890&open_id=u-7f3a2b91c4"
const url = new URL(
    "https://dowaba.com/api/tiktok/conversations/7345678901234567890/u-7f3a2b91c4/messages"
);

const params = {
    "video_id": "7345678901234567890",
    "open_id": "u-7f3a2b91c4",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/conversations/7345678901234567890/u-7f3a2b91c4/messages';
$response = $client->get(
    $url,
    [
        'query' => [
            'video_id' => '7345678901234567890',
            'open_id' => 'u-7f3a2b91c4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/conversations/{videoId}/{openId}/messages

URL Parameters

videoId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: 7345678901234567890

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

video_id   string  optional    

Thread'in TikTok video ID'si (query-param formda zorunlu). Example: 7345678901234567890

open_id   string  optional    

Yorumu yazan kullanıcının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

Manuel reply gonder.

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"profile_id\": 17,
    \"video_id\": \"7345678901234567890\",
    \"parent_comment_id\": \"7345678900987654321\",
    \"commenter_open_id\": \"open-abc123def456\",
    \"text\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "profile_id": 17,
    "video_id": "7345678901234567890",
    "parent_comment_id": "7345678900987654321",
    "commenter_open_id": "open-abc123def456",
    "text": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/reply';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'profile_id' => 17,
            'video_id' => '7345678901234567890',
            'parent_comment_id' => '7345678900987654321',
            'commenter_open_id' => 'open-abc123def456',
            'text' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/reply

Headers

Content-Type        

Example: application/json

Body Parameters

profile_id   integer     

Example: 17

video_id   string     

Yorumun ait olduğu TikTok video ID'si. Example: 7345678901234567890

parent_comment_id   string     

Cevaplanacak yorumun TikTok comment ID'si. Example: 7345678900987654321

commenter_open_id   string     

Yorumu yazan kullanıcının TikTok open_id'si. Example: open-abc123def456

text   string     

Must not be greater than 150 characters. Example: mqeopfuudtdsufvyvddqa

Yorum thread'i icin AI bot ac/kapat (konusma bazli).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/toggle-bot" \
    --header "Content-Type: application/json" \
    --data "{
    \"video_id\": \"7345678901234567890\",
    \"commenter_open_id\": \"open-abc123def456\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/toggle-bot"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "video_id": "7345678901234567890",
    "commenter_open_id": "open-abc123def456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/toggle-bot';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'video_id' => '7345678901234567890',
            'commenter_open_id' => 'open-abc123def456',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/toggle-bot

Headers

Content-Type        

Example: application/json

Body Parameters

video_id   string     

Thread'in TikTok video ID'si. Example: 7345678901234567890

commenter_open_id   string     

Yorumu yazan kullanıcının TikTok open_id'si. Example: open-abc123def456

Yorum thread'i icin engelleme ac/kapat (konusma bazli).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/toggle-block" \
    --header "Content-Type: application/json" \
    --data "{
    \"video_id\": \"7345678901234567890\",
    \"commenter_open_id\": \"open-abc123def456\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "video_id": "7345678901234567890",
    "commenter_open_id": "open-abc123def456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/toggle-block';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'video_id' => '7345678901234567890',
            'commenter_open_id' => 'open-abc123def456',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/toggle-block

Headers

Content-Type        

Example: application/json

Body Parameters

video_id   string     

Thread'in TikTok video ID'si. Example: 7345678901234567890

commenter_open_id   string     

Yorumu yazan kullanıcının TikTok open_id'si. Example: open-abc123def456

Tek bir yorum kaydını sil (lokal DB).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tiktok/comments/42"
const url = new URL(
    "https://dowaba.com/api/tiktok/comments/42"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/comments/42';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tiktok/comments/{id}

URL Parameters

id   integer     

Silinecek yorumun DB id'si. Example: 42

Yorum thread'ini (tüm yorumlarıyla birlikte) sil.

Tercih edilen çağrı: DELETE tiktok/conversation?video_id=..&open_id=.. (routes/api.php notu).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tiktok/conversation?video_id=7345678901234567890&open_id=u-7f3a2b91c4"
const url = new URL(
    "https://dowaba.com/api/tiktok/conversation"
);

const params = {
    "video_id": "7345678901234567890",
    "open_id": "u-7f3a2b91c4",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/conversation';
$response = $client->delete(
    $url,
    [
        'query' => [
            'video_id' => '7345678901234567890',
            'open_id' => 'u-7f3a2b91c4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tiktok/conversation

URL Parameters

videoId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: 7345678901234567890

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

video_id   string  optional    

Thread'in TikTok video ID'si (query-param formda zorunlu). Example: 7345678901234567890

open_id   string  optional    

Yorumu yazan kullanıcının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

Yorum thread'ini (tüm yorumlarıyla birlikte) sil.

Tercih edilen çağrı: DELETE tiktok/conversation?video_id=..&open_id=.. (routes/api.php notu).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tiktok/conversations/7345678901234567890/u-7f3a2b91c4?video_id=7345678901234567890&open_id=u-7f3a2b91c4"
const url = new URL(
    "https://dowaba.com/api/tiktok/conversations/7345678901234567890/u-7f3a2b91c4"
);

const params = {
    "video_id": "7345678901234567890",
    "open_id": "u-7f3a2b91c4",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/conversations/7345678901234567890/u-7f3a2b91c4';
$response = $client->delete(
    $url,
    [
        'query' => [
            'video_id' => '7345678901234567890',
            'open_id' => 'u-7f3a2b91c4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tiktok/conversations/{videoId}/{openId}

URL Parameters

videoId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: 7345678901234567890

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

video_id   string  optional    

Thread'in TikTok video ID'si (query-param formda zorunlu). Example: 7345678901234567890

open_id   string  optional    

Yorumu yazan kullanıcının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

Sync edilen TikTok video listesi + her video icin DB'deki yorum sayisi.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/videos"
const url = new URL(
    "https://dowaba.com/api/tiktok/videos"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/videos';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/videos

Per-video auto_reply override gunceller.

value: null (profil fallback) | true (acik) | false (kapali)

Example request:
curl --request PATCH \
    "https://dowaba.com/api/tiktok/videos/12/auto-reply" \
    --header "Content-Type: application/json" \
    --data "{
    \"auto_reply_enabled\": true
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/videos/12/auto-reply"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "auto_reply_enabled": true
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/videos/12/auto-reply';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'auto_reply_enabled' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/tiktok/videos/{id}/auto-reply

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Videonun DB id'si. Example: 12

Body Parameters

auto_reply_enabled   boolean  optional    

Example: true

Content Posting creator info (audit UX ön-adımı). Direct Post formu önce bunu çağırır: hedef hesap nickname/avatar + izinli privacy seçenekleri + comment/duet/stitch disabled.

GET tiktok/videos/creator-info?profile_id=

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/videos/creator-info" \
    --header "Content-Type: application/json" \
    --data "{
    \"profile_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/videos/creator-info"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "profile_id": 17
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/videos/creator-info';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'profile_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/videos/creator-info

Headers

Content-Type        

Example: application/json

Body Parameters

profile_id   integer     

Example: 17

Video yükle (TikTok gelen kutusuna taslak olarak).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/videos/upload" \
    --header "Content-Type: application/json" \
    --data "{
    \"profile_id\": 17,
    \"media_file_id\": 17,
    \"video_url\": \"https:\\/\\/example.com\\/video.mp4\",
    \"caption\": \"sufvyvddqamniihfqcoyn\",
    \"publish_mode\": \"inbox\",
    \"privacy\": \"PUBLIC_TO_EVERYONE\",
    \"disable_comment\": true,
    \"disable_duet\": true,
    \"disable_stitch\": true,
    \"brand_content_toggle\": false,
    \"brand_organic_toggle\": false
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/videos/upload"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "profile_id": 17,
    "media_file_id": 17,
    "video_url": "https:\/\/example.com\/video.mp4",
    "caption": "sufvyvddqamniihfqcoyn",
    "publish_mode": "inbox",
    "privacy": "PUBLIC_TO_EVERYONE",
    "disable_comment": true,
    "disable_duet": true,
    "disable_stitch": true,
    "brand_content_toggle": false,
    "brand_organic_toggle": false
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/videos/upload';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'profile_id' => 17,
            'media_file_id' => 17,
            'video_url' => 'https://example.com/video.mp4',
            'caption' => 'sufvyvddqamniihfqcoyn',
            'publish_mode' => 'inbox',
            'privacy' => 'PUBLIC_TO_EVERYONE',
            'disable_comment' => true,
            'disable_duet' => true,
            'disable_stitch' => true,
            'brand_content_toggle' => false,
            'brand_organic_toggle' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/videos/upload

Headers

Content-Type        

Example: application/json

Body Parameters

profile_id   integer     

Example: 17

media_file_id   integer  optional    

The id of an existing record in the media_files table. Example: 17

video_url   string  optional    

Yüklenecek videonun URL'i (media_file_id verilmezse). Example: https://example.com/video.mp4

caption   string  optional    

Must not be greater than 2200 characters. Example: sufvyvddqamniihfqcoyn

publish_mode   string  optional    

publish_mode: 'inbox' (default, scope: video.upload — drafts'a gönder) 'direct' (scope: video.publish — anlık yayın). Example: inbox

Must be one of:
  • inbox
  • direct
privacy   string  optional    

Example: PUBLIC_TO_EVERYONE

Must be one of:
  • PUBLIC_TO_EVERYONE
  • MUTUAL_FOLLOW_FRIENDS
  • SELF_ONLY
disable_comment   boolean  optional    

Audit-uyumlu interaction + ticari içerik bayrakları (Content Posting UX şartı). Example: true

disable_duet   boolean  optional    

Example: true

disable_stitch   boolean  optional    

Example: true

brand_content_toggle   boolean  optional    

Example: false

brand_organic_toggle   boolean  optional    

Example: false

GET api/tiktok/rules

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/rules"
const url = new URL(
    "https://dowaba.com/api/tiktok/rules"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/rules';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/rules

Video bazli oto-yanit kurali olustur/guncelle.

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/rules" \
    --header "Content-Type: application/json" \
    --data "{
    \"id\": 17,
    \"profile_id\": 17,
    \"video_id\": \"7345678901234567890\",
    \"video_title\": \"Yeni ürün tanıtım videosu\",
    \"video_cover_url\": \"https:\\/\\/www.mueller.com\\/laborum-eius-est-dolor-dolores-minus-voluptatem\",
    \"keywords\": [
        \"fiyat\",
        \"kargo\"
    ],
    \"comment_message\": \"lazghdtqtqxbajwbpilpm\",
    \"use_ai\": false,
    \"custom_prompt\": \"ufinllwloauydlsmsjury\",
    \"reply_via\": \"both\",
    \"dm_message\": \"vojcybzvrbyickznkyglo\",
    \"dm_use_ai\": true,
    \"dm_custom_prompt\": \"igmkwxphlvazjrcnfbaqy\",
    \"enabled\": false,
    \"priority\": 22
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/rules"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "id": 17,
    "profile_id": 17,
    "video_id": "7345678901234567890",
    "video_title": "Yeni ürün tanıtım videosu",
    "video_cover_url": "https:\/\/www.mueller.com\/laborum-eius-est-dolor-dolores-minus-voluptatem",
    "keywords": [
        "fiyat",
        "kargo"
    ],
    "comment_message": "lazghdtqtqxbajwbpilpm",
    "use_ai": false,
    "custom_prompt": "ufinllwloauydlsmsjury",
    "reply_via": "both",
    "dm_message": "vojcybzvrbyickznkyglo",
    "dm_use_ai": true,
    "dm_custom_prompt": "igmkwxphlvazjrcnfbaqy",
    "enabled": false,
    "priority": 22
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/rules';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'id' => 17,
            'profile_id' => 17,
            'video_id' => '7345678901234567890',
            'video_title' => 'Yeni ürün tanıtım videosu',
            'video_cover_url' => 'https://www.mueller.com/laborum-eius-est-dolor-dolores-minus-voluptatem',
            'keywords' => [
                'fiyat',
                'kargo',
            ],
            'comment_message' => 'lazghdtqtqxbajwbpilpm',
            'use_ai' => false,
            'custom_prompt' => 'ufinllwloauydlsmsjury',
            'reply_via' => 'both',
            'dm_message' => 'vojcybzvrbyickznkyglo',
            'dm_use_ai' => true,
            'dm_custom_prompt' => 'igmkwxphlvazjrcnfbaqy',
            'enabled' => false,
            'priority' => 22,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/rules

Headers

Content-Type        

Example: application/json

Body Parameters

id   integer  optional    

Example: 17

profile_id   integer     

Example: 17

video_id   string     

Kuralın bağlanacağı TikTok video ID'si. Example: 7345678901234567890

video_title   string  optional    

Video başlığı (panelde gösterim için). Example: Yeni ürün tanıtım videosu

video_cover_url   string  optional    

Must not be greater than 500 characters. Example: https://www.mueller.com/laborum-eius-est-dolor-dolores-minus-voluptatem

keywords   string[]  optional    

Kuralı tetikleyen anahtar kelimeler.

comment_message   string  optional    

Must not be greater than 150 characters. Example: lazghdtqtqxbajwbpilpm

use_ai   boolean     

Example: false

custom_prompt   string  optional    

Must not be greater than 2000 characters. Example: ufinllwloauydlsmsjury

reply_via   string  optional    

2026-07-02: cevap nereye — 'comment' | 'dm' | 'both'. Example: both

Must be one of:
  • comment
  • dm
  • both
dm_message   string  optional    

2026-05-23: DM aksiyonu — yoruma cevapla beraber DM gönderim (opsiyonel). Must not be greater than 6000 characters. Example: vojcybzvrbyickznkyglo

dm_use_ai   boolean  optional    

Example: true

dm_custom_prompt   string  optional    

Must not be greater than 2000 characters. Example: igmkwxphlvazjrcnfbaqy

enabled   boolean     

Example: false

priority   integer  optional    

Must be at least 0. Must not be greater than 1000. Example: 22

Oto-yanıt kuralını aç/kapat (enabled toggle).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/tiktok/rules/5/toggle"
const url = new URL(
    "https://dowaba.com/api/tiktok/rules/5/toggle"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/rules/5/toggle';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/tiktok/rules/{id}/toggle

URL Parameters

id   integer     

Kuralın DB id'si. Example: 5

Oto-yanıt kuralını sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tiktok/rules/5"
const url = new URL(
    "https://dowaba.com/api/tiktok/rules/5"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/rules/5';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tiktok/rules/{id}

URL Parameters

id   integer     

Silinecek kuralın DB id'si. Example: 5

GET api/tiktok/dm/conversations

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/dm/conversations"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/conversations"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/conversations';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/dm/conversations

DM konuşma bot/engel durumu (READ-ONLY) — unified inbox header için. getDmMessages düz mesaj array'i döndürdüğünden header `botActive` default'ta kalıyordu (2026-05-30 fix).

toggleDmBot ile AYNI profil scope; firstOrFail yerine first() (yoksa default bot açık).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/tiktok/dm/conversation-state" \
    --header "Content-Type: application/json" \
    --data "{
    \"counterparty_open_id\": \"open-abc123def456\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/conversation-state"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "counterparty_open_id": "open-abc123def456"
};

fetch(url, {
    method: "GET",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/conversation-state';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'counterparty_open_id' => 'open-abc123def456',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/tiktok/dm/conversation-state

Headers

Content-Type        

Example: application/json

Body Parameters

counterparty_open_id   string     

DM karşı tarafının TikTok open_id'si. Example: open-abc123def456

DM konusmasi icin AI bot ac/kapat (konusma bazli).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/dm/toggle-bot" \
    --header "Content-Type: application/json" \
    --data "{
    \"counterparty_open_id\": \"open-abc123def456\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/toggle-bot"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "counterparty_open_id": "open-abc123def456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/toggle-bot';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'counterparty_open_id' => 'open-abc123def456',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/dm/toggle-bot

Headers

Content-Type        

Example: application/json

Body Parameters

counterparty_open_id   string     

DM karşı tarafının TikTok open_id'si. Example: open-abc123def456

DM konusmasi icin engelleme ac/kapat (konusma bazli).

Example request:
curl --request POST \
    "https://dowaba.com/api/tiktok/dm/toggle-block" \
    --header "Content-Type: application/json" \
    --data "{
    \"counterparty_open_id\": \"open-abc123def456\"
}"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/toggle-block"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "counterparty_open_id": "open-abc123def456"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/toggle-block';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'counterparty_open_id' => 'open-abc123def456',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/tiktok/dm/toggle-block

Headers

Content-Type        

Example: application/json

Body Parameters

counterparty_open_id   string     

DM karşı tarafının TikTok open_id'si. Example: open-abc123def456

DM konuşmasını (tüm mesajlarıyla birlikte) sil.

Tercih edilen çağrı: DELETE tiktok/dm/conversation?open_id=.. (routes/api.php notu).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tiktok/dm/conversation?open_id=u-7f3a2b91c4"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/conversation"
);

const params = {
    "open_id": "u-7f3a2b91c4",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/conversation';
$response = $client->delete(
    $url,
    [
        'query' => [
            'open_id' => 'u-7f3a2b91c4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tiktok/dm/conversation

URL Parameters

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

open_id   string  optional    

DM karşı tarafının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

DM konuşmasını (tüm mesajlarıyla birlikte) sil.

Tercih edilen çağrı: DELETE tiktok/dm/conversation?open_id=.. (routes/api.php notu).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/tiktok/dm/conversations/u-7f3a2b91c4?open_id=u-7f3a2b91c4"
const url = new URL(
    "https://dowaba.com/api/tiktok/dm/conversations/u-7f3a2b91c4"
);

const params = {
    "open_id": "u-7f3a2b91c4",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/tiktok/dm/conversations/u-7f3a2b91c4';
$response = $client->delete(
    $url,
    [
        'query' => [
            'open_id' => 'u-7f3a2b91c4',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/tiktok/dm/conversations/{openId}

URL Parameters

openId   string  optional    

DEPRECATED path formu — query-param formunu kullanın. Example: u-7f3a2b91c4

Query Parameters

open_id   string  optional    

DM karşı tarafının TikTok open_id'si (query-param formda zorunlu). Example: u-7f3a2b91c4

GET api/youtube-profiles/{id}

Example request:
curl --request GET \
    --get "https://dowaba.com/api/youtube-profiles/1562"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles/1562"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles/1562';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/youtube-profiles/{id}

URL Parameters

id   string     

The ID of the youtube profile. Example: 1562

YouTube kanalını güncelle.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/youtube-profiles/1562" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"is_active\": true,
    \"ai_bot_enabled\": true,
    \"comment_auto_reply_enabled\": true,
    \"youtube_prompt\": \"Sen bir destek asistanısın\",
    \"use_faq\": false,
    \"notification_phone\": \"mqeopfuudtdsufvyv\"
}"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles/1562"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "is_active": true,
    "ai_bot_enabled": true,
    "comment_auto_reply_enabled": true,
    "youtube_prompt": "Sen bir destek asistanısın",
    "use_faq": false,
    "notification_phone": "mqeopfuudtdsufvyv"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles/1562';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'is_active' => true,
            'ai_bot_enabled' => true,
            'comment_auto_reply_enabled' => true,
            'youtube_prompt' => 'Sen bir destek asistanısın',
            'use_faq' => false,
            'notification_phone' => 'mqeopfuudtdsufvyv',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/youtube-profiles/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the youtube profile. Example: 1562

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

is_active   boolean  optional    

Example: true

ai_bot_enabled   boolean  optional    

Example: true

comment_auto_reply_enabled   boolean  optional    

Example: true

youtube_prompt   string  optional    

YouTube kanalına özel AI persona prompt'u (boşsa site varsayılanı kullanılır). Example: Sen bir destek asistanısın

use_faq   boolean  optional    

Example: false

notification_phone   string  optional    

Must not be greater than 20 characters. Example: mqeopfuudtdsufvyv

DELETE api/youtube-profiles/{id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/youtube-profiles/1562"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/youtube-profiles/{id}

URL Parameters

id   string     

The ID of the youtube profile. Example: 1562

Example request:
curl --request POST \
    "https://dowaba.com/api/youtube-profiles/1562/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles/1562/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles/1562/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/youtube-profiles/1562/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles/1562/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles/1562/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

GET api/youtube-profiles/{id}/linked-sites

Example request:
curl --request GET \
    --get "https://dowaba.com/api/youtube-profiles/1562/linked-sites"
const url = new URL(
    "https://dowaba.com/api/youtube-profiles/1562/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/youtube-profiles/1562/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/youtube-profiles/{id}/linked-sites

URL Parameters

id   string     

The ID of the youtube profile. Example: 1562

Birleşik liste: yayın-hazır FB Sayfaları + kullanıcının Messenger'da ZATEN bağlı olduğu ama henüz yayına açılmamış sayfalar (publish_enabled=false). Böylece sayfa ikinci kez sıfırdan bağlanmaz; "Yayın İzni Ver" tek OAuth ile hepsini açar.

(2026-05-30 — kullanıcı kararı: mevcut Messenger sayfalarını getir, ayrı bağlama yok.)

Example request:
curl --request GET \
    --get "https://dowaba.com/api/facebook-page-profiles"
const url = new URL(
    "https://dowaba.com/api/facebook-page-profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page-profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/facebook-page-profiles

Facebook Sayfa profilini güncelle (ad, aktiflik, bot/yorum ayarları).

Example request:
curl --request PATCH \
    "https://dowaba.com/api/facebook-page-profiles/1562" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"is_active\": true,
    \"ai_bot_enabled\": false,
    \"comment_auto_reply_enabled\": false,
    \"leads_sync_enabled\": false,
    \"fb_prompt\": \"Sen bir destek asistanısın\",
    \"use_faq\": true,
    \"notification_phone\": \"mqeopfuudtdsufvyv\"
}"
const url = new URL(
    "https://dowaba.com/api/facebook-page-profiles/1562"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "is_active": true,
    "ai_bot_enabled": false,
    "comment_auto_reply_enabled": false,
    "leads_sync_enabled": false,
    "fb_prompt": "Sen bir destek asistanısın",
    "use_faq": true,
    "notification_phone": "mqeopfuudtdsufvyv"
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page-profiles/1562';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'is_active' => true,
            'ai_bot_enabled' => false,
            'comment_auto_reply_enabled' => false,
            'leads_sync_enabled' => false,
            'fb_prompt' => 'Sen bir destek asistanısın',
            'use_faq' => true,
            'notification_phone' => 'mqeopfuudtdsufvyv',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/facebook-page-profiles/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the facebook page profile. Example: 1562

Body Parameters

name   string  optional    

Must not be greater than 100 characters. Example: vmqeopfuudtdsufvyvddq

is_active   boolean  optional    

Example: true

ai_bot_enabled   boolean  optional    

Example: false

comment_auto_reply_enabled   boolean  optional    

Example: false

leads_sync_enabled   boolean  optional    

Example: false

fb_prompt   string  optional    

Facebook Sayfasına özel AI persona prompt'u (boşsa site varsayılanı kullanılır). Example: Sen bir destek asistanısın

use_faq   boolean  optional    

Example: true

notification_phone   string  optional    

Must not be greater than 20 characters. Example: mqeopfuudtdsufvyv

DELETE api/facebook-page-profiles/{id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/facebook-page-profiles/1562"
const url = new URL(
    "https://dowaba.com/api/facebook-page-profiles/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page-profiles/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/facebook-page-profiles/{id}

URL Parameters

id   string     

The ID of the facebook page profile. Example: 1562

Example request:
curl --request POST \
    "https://dowaba.com/api/facebook-page-profiles/1562/link-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/facebook-page-profiles/1562/link-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page-profiles/1562/link-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example request:
curl --request POST \
    "https://dowaba.com/api/facebook-page-profiles/1562/unlink-site" \
    --header "Content-Type: application/json" \
    --data "{
    \"site_id\": 17
}"
const url = new URL(
    "https://dowaba.com/api/facebook-page-profiles/1562/unlink-site"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "site_id": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page-profiles/1562/unlink-site';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'site_id' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

GET api/facebook-page-profiles/{id}/linked-sites

Example request:
curl --request GET \
    --get "https://dowaba.com/api/facebook-page-profiles/1562/linked-sites"
const url = new URL(
    "https://dowaba.com/api/facebook-page-profiles/1562/linked-sites"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/facebook-page-profiles/1562/linked-sites';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/facebook-page-profiles/{id}/linked-sites

URL Parameters

id   string     

The ID of the facebook page profile. Example: 1562

GET api/social-posts/{id}

Example request:
curl --request GET \
    --get "https://dowaba.com/api/social-posts/1562"
const url = new URL(
    "https://dowaba.com/api/social-posts/1562"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-posts/1562';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/social-posts/{id}

URL Parameters

id   string     

The ID of the social post. Example: 1562

DELETE api/social-posts/{id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/social-posts/1562"
const url = new URL(
    "https://dowaba.com/api/social-posts/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-posts/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/social-posts/{id}

URL Parameters

id   string     

The ID of the social post. Example: 1562

Yeni yorum oto-cevap kuralı oluştur.

Example request:
curl --request POST \
    "https://dowaba.com/api/social-rules" \
    --header "Content-Type: application/json" \
    --data "{
    \"channel\": \"tiktok\",
    \"profile_id\": 17,
    \"post_remote_id\": \"7345678901234567890\",
    \"reply_message\": \"mqeopfuudtdsufvyvddqa\",
    \"use_ai\": false,
    \"custom_prompt\": \"Yorumlara samimi ve kısa bir dille cevap ver\",
    \"reply_via\": \"comment\",
    \"enabled\": true,
    \"priority\": 17
}"
const url = new URL(
    "https://dowaba.com/api/social-rules"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "channel": "tiktok",
    "profile_id": 17,
    "post_remote_id": "7345678901234567890",
    "reply_message": "mqeopfuudtdsufvyvddqa",
    "use_ai": false,
    "custom_prompt": "Yorumlara samimi ve kısa bir dille cevap ver",
    "reply_via": "comment",
    "enabled": true,
    "priority": 17
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-rules';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'channel' => 'tiktok',
            'profile_id' => 17,
            'post_remote_id' => '7345678901234567890',
            'reply_message' => 'mqeopfuudtdsufvyvddqa',
            'use_ai' => false,
            'custom_prompt' => 'Yorumlara samimi ve kısa bir dille cevap ver',
            'reply_via' => 'comment',
            'enabled' => true,
            'priority' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/social-rules

Headers

Content-Type        

Example: application/json

Body Parameters

channel   string     

Example: tiktok

Must be one of:
  • all
  • youtube
  • tiktok
  • instagram
  • facebook_page
profile_id   integer  optional    

Example: 17

post_remote_id   string  optional    

Kuralın uygulanacağı gönderinin kanal tarafındaki ID'si (boş ise tüm gönderiler). Example: 7345678901234567890

keywords   object  optional    
reply_message   string  optional    

Must not be greater than 9000 characters. Example: mqeopfuudtdsufvyvddqa

use_ai   boolean  optional    

Example: false

custom_prompt   string  optional    

AI cevabı için özel yönerge metni. Example: Yorumlara samimi ve kısa bir dille cevap ver

reply_via   string  optional    

Example: comment

Must be one of:
  • comment
  • dm
  • both
enabled   boolean  optional    

Example: true

priority   integer  optional    

Example: 17

Yorum oto-cevap kuralını güncelle.

Example request:
curl --request PATCH \
    "https://dowaba.com/api/social-rules/1562" \
    --header "Content-Type: application/json" \
    --data "{
    \"reply_message\": \"vmqeopfuudtdsufvyvddq\",
    \"use_ai\": true,
    \"custom_prompt\": \"Yorumlara samimi ve kısa bir dille cevap ver\",
    \"reply_via\": \"dm\",
    \"enabled\": true,
    \"priority\": 17
}"
const url = new URL(
    "https://dowaba.com/api/social-rules/1562"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "reply_message": "vmqeopfuudtdsufvyvddq",
    "use_ai": true,
    "custom_prompt": "Yorumlara samimi ve kısa bir dille cevap ver",
    "reply_via": "dm",
    "enabled": true,
    "priority": 17
};

fetch(url, {
    method: "PATCH",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-rules/1562';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'reply_message' => 'vmqeopfuudtdsufvyvddq',
            'use_ai' => true,
            'custom_prompt' => 'Yorumlara samimi ve kısa bir dille cevap ver',
            'reply_via' => 'dm',
            'enabled' => true,
            'priority' => 17,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/social-rules/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   string     

The ID of the social rule. Example: 1562

Body Parameters

keywords   object  optional    
reply_message   string  optional    

Must not be greater than 9000 characters. Example: vmqeopfuudtdsufvyvddq

use_ai   boolean  optional    

Example: true

custom_prompt   string  optional    

AI cevabı için özel yönerge metni. Example: Yorumlara samimi ve kısa bir dille cevap ver

reply_via   string  optional    

Example: dm

Must be one of:
  • comment
  • dm
  • both
enabled   boolean  optional    

Example: true

priority   integer  optional    

Example: 17

PATCH api/social-rules/{id}/toggle

Example request:
curl --request PATCH \
    "https://dowaba.com/api/social-rules/1562/toggle"
const url = new URL(
    "https://dowaba.com/api/social-rules/1562/toggle"
);



fetch(url, {
    method: "PATCH",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-rules/1562/toggle';
$response = $client->patch($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/social-rules/{id}/toggle

URL Parameters

id   string     

The ID of the social rule. Example: 1562

DELETE api/social-rules/{id}

Example request:
curl --request DELETE \
    "https://dowaba.com/api/social-rules/1562"
const url = new URL(
    "https://dowaba.com/api/social-rules/1562"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/social-rules/1562';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/social-rules/{id}

URL Parameters

id   string     

The ID of the social rule. Example: 1562

Kullanıcının saat dilimi tercihini günceller (IANA, örn. 'Europe/Istanbul').

users.locale ile aynı desen. Panel + mobil TÜM saat gösterimleri bu dilime çevrilir (cihaz/tarayıcı TZ'sine güvenilmez). Geçerli IANA tanımı şart; geçersiz/null → 422. NULL semantic = "seçim yok → frontend Europe/Istanbul varsayar".

Example request:
curl --request PUT \
    "https://dowaba.com/api/user/timezone" \
    --header "Content-Type: application/json" \
    --data "{
    \"timezone\": \"Europe\\/Malta\"
}"
const url = new URL(
    "https://dowaba.com/api/user/timezone"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "timezone": "Europe\/Malta"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/user/timezone';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'timezone' => 'Europe/Malta',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/user/timezone

Headers

Content-Type        

Example: application/json

Body Parameters

timezone   string  optional    

Must not be greater than 64 characters. Example: Europe/Malta

Mail template detayı.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail-templates/42"
const url = new URL(
    "https://dowaba.com/api/mail-templates/42"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates/42';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail-templates/{id}

URL Parameters

id   integer     

Mail şablonunun ID'si. Example: 42

Mail template güncelle (name / subject / body / is_active).

Example request:
curl --request PUT \
    "https://dowaba.com/api/mail-templates/7" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"subject_template\": \"amniihfqcoynlazghdtqt\",
    \"body_html\": \"qxbajwbpilpmufinllwlo\",
    \"body_text\": \"auydlsmsjuryvojcybzvr\",
    \"is_active\": false
}"
const url = new URL(
    "https://dowaba.com/api/mail-templates/7"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "subject_template": "amniihfqcoynlazghdtqt",
    "body_html": "qxbajwbpilpmufinllwlo",
    "body_text": "auydlsmsjuryvojcybzvr",
    "is_active": false
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates/7';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'subject_template' => 'amniihfqcoynlazghdtqt',
            'body_html' => 'qxbajwbpilpmufinllwlo',
            'body_text' => 'auydlsmsjuryvojcybzvr',
            'is_active' => false,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/mail-templates/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Güncellenecek mail şablonunun ID'si. Example: 7

Body Parameters

name   string  optional    

Must not be greater than 150 characters. Example: vmqeopfuudtdsufvyvddq

subject_template   string  optional    

Must not be greater than 500 characters. Example: amniihfqcoynlazghdtqt

body_html   string  optional    

Must not be greater than 200000 characters. Example: qxbajwbpilpmufinllwlo

body_text   string  optional    

Must not be greater than 200000 characters. Example: auydlsmsjuryvojcybzvr

is_active   boolean  optional    

Example: false

Mail template sil (aktif/duraklatılmış kampanyada kullanılıyorsa 422).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/mail-templates/12"
const url = new URL(
    "https://dowaba.com/api/mail-templates/12"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-templates/12';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/mail-templates/{id}

URL Parameters

id   integer     

Silinecek mail şablonunun ID'si. Example: 12

Kampanya detayı (son 50 log dahil).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail-campaigns/42"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/42"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/42';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail-campaigns/{id}

URL Parameters

id   integer     

Kampanya ID'si (scheduled_mail_jobs). Example: 42

Kampanya güncelle (draft değilse sadece schedule/limit/is_active/name değişir).

Example request:
curl --request PUT \
    "https://dowaba.com/api/mail-campaigns/42" \
    --header "Content-Type: application/json" \
    --data "{
    \"name\": \"vmqeopfuudtdsufvyvddq\",
    \"schedule_type\": \"hourly\",
    \"schedule_hour\": 0,
    \"batch_size\": 1,
    \"daily_send_limit_override\": 46,
    \"hourly_send_limit_override\": 29,
    \"is_active\": true
}"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/42"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "name": "vmqeopfuudtdsufvyvddq",
    "schedule_type": "hourly",
    "schedule_hour": 0,
    "batch_size": 1,
    "daily_send_limit_override": 46,
    "hourly_send_limit_override": 29,
    "is_active": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/42';
$response = $client->put(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'name' => 'vmqeopfuudtdsufvyvddq',
            'schedule_type' => 'hourly',
            'schedule_hour' => 0,
            'batch_size' => 1,
            'daily_send_limit_override' => 46,
            'hourly_send_limit_override' => 29,
            'is_active' => true,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PUT api/mail-campaigns/{id}

Headers

Content-Type        

Example: application/json

URL Parameters

id   integer     

Kampanya ID'si. Example: 42

Body Parameters

name   string  optional    

Must not be greater than 200 characters. Example: vmqeopfuudtdsufvyvddq

recipient_filter   object  optional    
schedule_type   string  optional    

Example: hourly

Must be one of:
  • once
  • hourly
  • daily
schedule_hour   integer  optional    

Must be between 0 and 23. Example: 0

batch_size   integer  optional    

Must be between 1 and 500. Example: 1

daily_send_limit_override   integer  optional    

Must be at least 1. Example: 46

hourly_send_limit_override   integer  optional    

Must be at least 1. Example: 29

is_active   boolean  optional    

Example: true

Kampanyayı sil.

Example request:
curl --request DELETE \
    "https://dowaba.com/api/mail-campaigns/7"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/7"
);



fetch(url, {
    method: "DELETE",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/7';
$response = $client->delete($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/mail-campaigns/{id}

URL Parameters

id   integer     

Kampanya ID'si. Example: 7

Kampanyayı başlat → status=running, started_at=now, is_active=true

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-campaigns/42/start"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/42/start"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/42/start';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-campaigns/{id}/start

URL Parameters

id   integer     

Kampanya ID'si. Example: 42

Çalışan kampanyayı duraklat.

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-campaigns/12/pause"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/12/pause"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/12/pause';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-campaigns/{id}/pause

URL Parameters

id   integer     

Kampanya ID'si. Example: 12

Duraklatılmış kampanyayı devam ettir (start ile aynı davranış).

Example request:
curl --request POST \
    "https://dowaba.com/api/mail-campaigns/12/resume"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/12/resume"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/12/resume';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/mail-campaigns/{id}/resume

URL Parameters

id   integer     

Kampanya ID'si. Example: 12

Kampanya log listesi (pagination + status filter).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail-campaigns/42/logs"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/42/logs"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/42/logs';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail-campaigns/{id}/logs

URL Parameters

id   integer     

Kampanya ID'si. Example: 42

recipient_filter uygulandığında hedef alınacak contact listesi (preview).

Max 100 kayıt — UI için "kaç kişiye gidecek" göstermesi yeterli.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/mail-campaigns/7/preview-recipients"
const url = new URL(
    "https://dowaba.com/api/mail-campaigns/7/preview-recipients"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/mail-campaigns/7/preview-recipients';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/mail-campaigns/{id}/preview-recipients

URL Parameters

id   integer     

Kampanya ID'si. Example: 7

Authenticate the request for channel access.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/broadcasting/auth"
const url = new URL(
    "https://dowaba.com/api/broadcasting/auth"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/broadcasting/auth';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
set-cookie: dowaba-session=eyJpdiI6IlF0aFYyNlJramFUQ3BhRUtoMlBnWmc9PSIsInZhbHVlIjoiMjd2Vlo4Vk8wZTRLY0R6aGp5SUJadEd6ZjlldzZETTV5M2VaTzM2TWtKMXBmME5TWFE2Nm1PVk00djQ5Wnl5QWUxcW1OOFlVM3RBV0FkMk1zNk1uczZnVUROTlZVNXlLQURGMW1sRjc1eDVNZlA5ZmJod091eitFR2hrLzhJc1kiLCJtYWMiOiJkZGJhYTIzYWE3YzEzOGFhODQ3ZTJkNzJhMGE0YzQxMjU1ZWU1ZmVhOWQzOWI2OTQ2Y2FiYTY2ZGM5MWM0YWYxIiwidGFnIjoiIn0%3D; expires=Fri, 09 Jul 2027 17:55:59 GMT; Max-Age=31536000; path=/; secure; httponly; samesite=lax
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/broadcasting/auth

POST api/broadcasting/auth

GET — onay sayfası (imza doğrulandı; henüz çıkarmaz).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/announcements/unsubscribe/1"
const url = new URL(
    "https://dowaba.com/api/announcements/unsubscribe/1"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/announcements/unsubscribe/1';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (403):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-ratelimit-limit: 240
x-ratelimit-remaining: 239
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Forbidden</title>

        <style>
            /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}code{font-family:monospace,monospace;font-size:1em}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}code{font-family:Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-gray-400{--border-opacity:1;border-color:#cbd5e0;border-color:rgba(203,213,224,var(--border-opacity))}.border-t{border-top-width:1px}.border-r{border-right-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-xl{max-width:36rem}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.uppercase{text-transform:uppercase}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.tracking-wider{letter-spacing:.05em}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@-webkit-keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@-webkit-keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@keyframes ping{0%{transform:scale(1);opacity:1}75%,to{transform:scale(2);opacity:0}}@-webkit-keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:translateY(0);-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-300 { --text-opacity: 1; color: #e2e8f0; color: rgba(226,232,240,var(--text-opacity)) }}
        </style>

        <style>
            body {
                font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
            }
        </style>
    </head>
    <body class="antialiased">
        <div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center sm:pt-0" role="main">
            <div class="max-w-xl mx-auto sm:px-6 lg:px-8">
                <div class="flex items-center pt-8 sm:justify-start sm:pt-0">
                    <h1 class="px-4 text-lg dark:text-gray-300 text-gray-700 border-r border-gray-400 tracking-wider">
                        403                    </h1>

                    <div class="ml-4 text-lg dark:text-gray-300 text-gray-700 uppercase tracking-wider">
                        Invalid signature.                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

 

Request      

GET api/announcements/unsubscribe/{user_id}

URL Parameters

user_id   integer     

The ID of the user. Example: 1

POST — gerçekten çıkar (idempotent) + audit. Gmail tek-tık ve form submit buraya gelir.

Example request:
curl --request POST \
    "https://dowaba.com/api/announcements/unsubscribe/1"
const url = new URL(
    "https://dowaba.com/api/announcements/unsubscribe/1"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/announcements/unsubscribe/1';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/announcements/unsubscribe/{user_id}

URL Parameters

user_id   integer     

The ID of the user. Example: 1

Açılış pixel'i (1x1 GIF) → opened_at (ilk açılışta) damgalar.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/announcements/track/open/c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c"
const url = new URL(
    "https://dowaba.com/api/announcements/track/open/c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/announcements/track/open/c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
content-type: image/gif
cache-control: must-revalidate, no-cache, no-store, private
pragma: no-cache
x-ratelimit-limit: 240
x-ratelimit-remaining: 238
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

GIF89a����!�,D;
 

Request      

GET api/announcements/track/open/{token}

URL Parameters

token   string     

Example: c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c

Tıklama → clicked_at damgalar + hedef URL'e 302. url param base64url (?u=).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/announcements/track/click/c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c"
const url = new URL(
    "https://dowaba.com/api/announcements/track/click/c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/announcements/track/click/c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (400):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-ratelimit-limit: 240
x-ratelimit-remaining: 237
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

Geçersiz hedef link.
 

Request      

GET api/announcements/track/click/{token}

URL Parameters

token   string     

Example: c23d66c5c56d797bb4a12ffed4b2921a9deb64538baf8b3f1316df200703a69c

GET api/public/stats

Example request:
curl --request GET \
    --get "https://dowaba.com/api/public/stats"
const url = new URL(
    "https://dowaba.com/api/public/stats"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/public/stats';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-ratelimit-limit: 60
x-ratelimit-remaining: 56
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "success": true,
    "stats": {
        "active_subscribers": 1,
        "sub_users": 0,
        "total_messages": 0,
        "unique_customers": 0,
        "reseller_customers": 1,
        "active_sites": 2,
        "total_sites": 2,
        "active_domains": 0,
        "active_whatsapp": 0,
        "total_whatsapp": 0,
        "active_instagram": 0,
        "total_instagram": 0,
        "uptime_score": null,
        "uptime_target": 99.5,
        "active_subscribers_short": "1",
        "sub_users_short": "0",
        "total_messages_short": "0",
        "unique_customers_short": "0",
        "reseller_customers_short": "1",
        "active_sites_short": "2",
        "active_whatsapp_short": "0",
        "active_instagram_short": "0"
    }
}
 

Request      

GET api/public/stats

POST api/profile/2fa/totp/enroll

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/2fa/totp/enroll"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/totp/enroll"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/totp/enroll';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/2fa/totp/enroll

POST api/profile/2fa/totp/verify

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/2fa/totp/verify" \
    --header "Content-Type: application/json" \
    --data "{
    \"code\": \"vmqeopf\"
}"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/totp/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "vmqeopf"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/totp/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'code' => 'vmqeopf',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/2fa/totp/verify

Headers

Content-Type        

Example: application/json

Body Parameters

code   string     

Must not be greater than 8 characters. Example: vmqeopf

POST api/profile/2fa/sms/enroll

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/2fa/sms/enroll" \
    --header "Content-Type: application/json" \
    --data "{
    \"phone\": \"vmqeopfuudtdsufvy\"
}"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/sms/enroll"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "phone": "vmqeopfuudtdsufvy"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/sms/enroll';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'phone' => 'vmqeopfuudtdsufvy',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/2fa/sms/enroll

Headers

Content-Type        

Example: application/json

Body Parameters

phone   string     

Must be at least 10 characters. Must not be greater than 20 characters. Example: vmqeopfuudtdsufvy

POST api/profile/2fa/sms/verify

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/2fa/sms/verify" \
    --header "Content-Type: application/json" \
    --data "{
    \"code\": \"vmqeopf\"
}"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/sms/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "vmqeopf"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/sms/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'code' => 'vmqeopf',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/2fa/sms/verify

Headers

Content-Type        

Example: application/json

Body Parameters

code   string     

Must not be greater than 8 characters. Example: vmqeopf

POST api/profile/2fa/email/enroll

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/2fa/email/enroll" \
    --header "Content-Type: application/json" \
    --data "{
    \"email\": \"qkunze@example.com\"
}"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/email/enroll"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "email": "qkunze@example.com"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/email/enroll';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'email' => 'qkunze@example.com',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/2fa/email/enroll

Headers

Content-Type        

Example: application/json

Body Parameters

email   string  optional    

Must be a valid email address. Must not be greater than 255 characters. Example: qkunze@example.com

POST api/profile/2fa/email/verify

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/2fa/email/verify" \
    --header "Content-Type: application/json" \
    --data "{
    \"code\": \"vmqeopf\"
}"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/email/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "code": "vmqeopf"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/email/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'code' => 'vmqeopf',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/2fa/email/verify

Headers

Content-Type        

Example: application/json

Body Parameters

code   string     

Must not be greater than 8 characters. Example: vmqeopf

Method disable — parola onayı + en az 1 method kalsın opsiyonu YOK, kullanıcı tüm method'ları kapatabilir (uyarı UI'da gösterilir).

Example request:
curl --request DELETE \
    "https://dowaba.com/api/profile/2fa/totp|sms|email" \
    --header "Content-Type: application/json" \
    --data "{
    \"current_password\": null
}"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/totp|sms|email"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "current_password": null
};

fetch(url, {
    method: "DELETE",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/totp|sms|email';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'current_password' => null,
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/profile/2fa/{method}

Headers

Content-Type        

Example: application/json

URL Parameters

method   string     

Example: totp|sms|email

Body Parameters

current_password   string     

Mevcut hesap şifresi (onay için).

Recovery codes üret — eski kodları siler. Plain string'leri ilk ve son kez döner.

Example request:
curl --request POST \
    "https://dowaba.com/api/profile/2fa/recovery-codes"
const url = new URL(
    "https://dowaba.com/api/profile/2fa/recovery-codes"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/profile/2fa/recovery-codes';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/profile/2fa/recovery-codes

Bridge ucu (voice.bridge): sip-bridge beginTransfer'da "bu kullanıcı app'e çaldırılabilir mi" diye sorar.

Kayıtlı bir VoIP cihaz token'ı yoksa app çalamaz → sip-bridge telefon/callback'e degrade eder.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/voice/app-ring-eligible"
const url = new URL(
    "https://dowaba.com/api/voice/app-ring-eligible"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice/app-ring-eligible';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "success": false,
    "error": "Invalid bridge secret"
}
 

Request      

GET api/voice/app-ring-eligible

Bridge ucu (voice.bridge): voip-app-bridge arayan bacağı bağlanınca çağırır — eşlenen kullanıcının app'ini çaldır. join-token üret + route'u cache'le (SDP-proxy için) + AppCallPushService.ringUser.

GÜVENLİK: bridge_host exact-match allow-list (SSRF). Cred ASLA bu yanıtta dönmez (yalnız ring_count).

Example request:
curl --request POST \
    "https://dowaba.com/api/voice/app-ring-push" \
    --header "Content-Type: application/json" \
    --data "{
    \"user_id\": 73,
    \"site_id\": 17,
    \"conv_id\": 17,
    \"bridge_id\": \"mqeopfuudtdsufvyvddqa\",
    \"uuid\": \"87582a71-8e82-3d56-919d-d5863651492b\",
    \"bridge_host\": \"iihfqcoynlazghdtqtqxb\",
    \"caller_label\": \"ajwbpilpmufinllwloauy\",
    \"site_name\": \"dlsmsjuryvojcybzvrbyi\"
}"
const url = new URL(
    "https://dowaba.com/api/voice/app-ring-push"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "user_id": 73,
    "site_id": 17,
    "conv_id": 17,
    "bridge_id": "mqeopfuudtdsufvyvddqa",
    "uuid": "87582a71-8e82-3d56-919d-d5863651492b",
    "bridge_host": "iihfqcoynlazghdtqtqxb",
    "caller_label": "ajwbpilpmufinllwloauy",
    "site_name": "dlsmsjuryvojcybzvrbyi"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/voice/app-ring-push';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'user_id' => 73,
            'site_id' => 17,
            'conv_id' => 17,
            'bridge_id' => 'mqeopfuudtdsufvyvddqa',
            'uuid' => '87582a71-8e82-3d56-919d-d5863651492b',
            'bridge_host' => 'iihfqcoynlazghdtqtqxb',
            'caller_label' => 'ajwbpilpmufinllwloauy',
            'site_name' => 'dlsmsjuryvojcybzvrbyi',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/voice/app-ring-push

Headers

Content-Type        

Example: application/json

Body Parameters

user_id   integer     

Must be at least 1. Example: 73

site_id   integer  optional    

Example: 17

conv_id   integer  optional    

Example: 17

bridge_id   string     

Must not be greater than 64 characters. Example: mqeopfuudtdsufvyvddqa

uuid   string     

Must not be greater than 64 characters. Example: 87582a71-8e82-3d56-919d-d5863651492b

bridge_host   string     

Must not be greater than 64 characters. Example: iihfqcoynlazghdtqtqxb

caller_label   string  optional    

Must not be greater than 64 characters. Example: ajwbpilpmufinllwloauy

site_name   string  optional    

Must not be greater than 128 characters. Example: dlsmsjuryvojcybzvrbyi

Eski endpoint — site explicit URL'de.

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/ai-improve-message" \
    --header "Content-Type: application/json" \
    --data "{
    \"draft\": \"vmqeopfuudtdsufvyvddq\",
    \"channel\": \"amniihfqcoynlazghdtqt\",
    \"identifier\": \"qxbajwbpilpmufinllwlo\",
    \"context\": \"auydlsmsjuryvojcybzvr\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/ai-improve-message"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "draft": "vmqeopfuudtdsufvyvddq",
    "channel": "amniihfqcoynlazghdtqt",
    "identifier": "qxbajwbpilpmufinllwlo",
    "context": "auydlsmsjuryvojcybzvr"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/ai-improve-message';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'draft' => 'vmqeopfuudtdsufvyvddq',
            'channel' => 'amniihfqcoynlazghdtqt',
            'identifier' => 'qxbajwbpilpmufinllwlo',
            'context' => 'auydlsmsjuryvojcybzvr',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/ai-improve-message

Headers

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

Body Parameters

draft   string     

Must not be greater than 4000 characters. Example: vmqeopfuudtdsufvyvddq

channel   string     

Must not be greater than 32 characters. Example: amniihfqcoynlazghdtqt

identifier   string  optional    

Must not be greater than 255 characters. Example: qxbajwbpilpmufinllwlo

context   string  optional    

Must not be greater than 4000 characters. Example: auydlsmsjuryvojcybzvr

Yeni endpoint — site auto-resolve (channel + profile_id'den).

WhatsappView/TelegramView/MessengerView gibi panel view'larında kullanılır.

Example request:
curl --request POST \
    "https://dowaba.com/api/ai-improve-message" \
    --header "Content-Type: application/json" \
    --data "{
    \"draft\": \"vmqeopfuudtdsufvyvddq\",
    \"channel\": \"amniihfqcoynlazghdtqt\",
    \"profile_id\": 17,
    \"site_id\": 17,
    \"identifier\": \"mqeopfuudtdsufvyvddqa\",
    \"context\": \"mniihfqcoynlazghdtqtq\"
}"
const url = new URL(
    "https://dowaba.com/api/ai-improve-message"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "draft": "vmqeopfuudtdsufvyvddq",
    "channel": "amniihfqcoynlazghdtqt",
    "profile_id": 17,
    "site_id": 17,
    "identifier": "mqeopfuudtdsufvyvddqa",
    "context": "mniihfqcoynlazghdtqtq"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-improve-message';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'draft' => 'vmqeopfuudtdsufvyvddq',
            'channel' => 'amniihfqcoynlazghdtqt',
            'profile_id' => 17,
            'site_id' => 17,
            'identifier' => 'mqeopfuudtdsufvyvddqa',
            'context' => 'mniihfqcoynlazghdtqtq',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ai-improve-message

Headers

Content-Type        

Example: application/json

Body Parameters

draft   string     

Must not be greater than 4000 characters. Example: vmqeopfuudtdsufvyvddq

channel   string     

Must not be greater than 32 characters. Example: amniihfqcoynlazghdtqt

profile_id   integer  optional    

Example: 17

site_id   integer  optional    

Example: 17

identifier   string  optional    

Must not be greater than 255 characters. Example: mqeopfuudtdsufvyvddqa

context   string  optional    

Must not be greater than 4000 characters. Example: mniihfqcoynlazghdtqtq

POST api/translate-message

Example request:
curl --request POST \
    "https://dowaba.com/api/translate-message" \
    --header "Content-Type: application/json" \
    --data "{
    \"text\": \"vmqeopfuudtdsufvyvddq\",
    \"target_locale\": \"so_ET\",
    \"channel\": \"mqeopfuudtdsufvyvddqa\",
    \"profile_id\": 17,
    \"site_id\": 17,
    \"identifier\": \"mqeopfuudtdsufvyvddqa\"
}"
const url = new URL(
    "https://dowaba.com/api/translate-message"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "text": "vmqeopfuudtdsufvyvddq",
    "target_locale": "so_ET",
    "channel": "mqeopfuudtdsufvyvddqa",
    "profile_id": 17,
    "site_id": 17,
    "identifier": "mqeopfuudtdsufvyvddqa"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/translate-message';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'text' => 'vmqeopfuudtdsufvyvddq',
            'target_locale' => 'so_ET',
            'channel' => 'mqeopfuudtdsufvyvddqa',
            'profile_id' => 17,
            'site_id' => 17,
            'identifier' => 'mqeopfuudtdsufvyvddqa',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/translate-message

Headers

Content-Type        

Example: application/json

Body Parameters

text   string     

Must not be greater than 12000 characters. Example: vmqeopfuudtdsufvyvddq

target_locale   string     

Hedef dil — i18n tek otoritesinden (dil seçici bunu yönetiyor). Example: so_ET

channel   string     

Must not be greater than 32 characters. Example: mqeopfuudtdsufvyvddqa

profile_id   integer  optional    

Example: 17

site_id   integer  optional    

Example: 17

identifier   string  optional    

Must not be greater than 255 characters. Example: mqeopfuudtdsufvyvddqa

GET api/public/brand

Example request:
curl --request GET \
    --get "https://dowaba.com/api/public/brand"
const url = new URL(
    "https://dowaba.com/api/public/brand"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/public/brand';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: application/json
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: same-origin-allow-popups
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

{
    "success": true,
    "brand": {
        "name": "DoWaba",
        "name_display": "DoWaba",
        "tagline": "Yapay Zeka Destekli<br/>Müşteri Hizmetleri Platformu",
        "logo_url": null,
        "logo_letter": "D",
        "primary_color": "#667eea",
        "secondary_color": "#764ba2",
        "show_register": true,
        "show_oauth_buttons": true,
        "show_passkey": true,
        "legal_enabled": true,
        "use_default_bot_svg": true
    }
}
 

Request      

GET api/public/brand

Locale-aware paket kataloğu (TR ₺ / diğer $).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ai-credit/catalog"
const url = new URL(
    "https://dowaba.com/api/ai-credit/catalog"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/catalog';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ai-credit/catalog

Cüzdan özeti: bakiye + tahmini mesaj + son hareketler + own-key var mı.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ai-credit/summary"
const url = new URL(
    "https://dowaba.com/api/ai-credit/summary"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/summary';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ai-credit/summary

Hareket geçmişi (debit/purchase/refund).

Example request:
curl --request GET \
    --get "https://dowaba.com/api/ai-credit/transactions"
const url = new URL(
    "https://dowaba.com/api/ai-credit/transactions"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/transactions';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/ai-credit/transactions

Stripe Checkout (TR-dışı kart, USD, otomatik webhook).

Example request:
curl --request POST \
    "https://dowaba.com/api/ai-credit/stripe/checkout" \
    --header "Content-Type: application/json" \
    --data "{
    \"package_key\": \"standart\"
}"
const url = new URL(
    "https://dowaba.com/api/ai-credit/stripe/checkout"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "package_key": "standart"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/stripe/checkout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'package_key' => 'standart',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ai-credit/stripe/checkout

Headers

Content-Type        

Example: application/json

Body Parameters

package_key   string     

AI kredi paketi anahtarı (mini | standart | pro | kurumsal). Example: standart

PayTR Checkout (TR — kart + taksit). iframe token döner; grant webhook'ta.

Example request:
curl --request POST \
    "https://dowaba.com/api/ai-credit/paytr/checkout" \
    --header "Content-Type: application/json" \
    --data "{
    \"package_key\": \"standart\"
}"
const url = new URL(
    "https://dowaba.com/api/ai-credit/paytr/checkout"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "package_key": "standart"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/paytr/checkout';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'package_key' => 'standart',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ai-credit/paytr/checkout

Headers

Content-Type        

Example: application/json

Body Parameters

package_key   string     

AI kredi paketi anahtarı (mini | standart | pro | kurumsal). Example: standart

PayPal manuel (TR-dışı/USD) — pending kayıt + paypal.me link döner; grant admin onayında.

Example request:
curl --request POST \
    "https://dowaba.com/api/ai-credit/paypal/initiate" \
    --header "Content-Type: application/json" \
    --data "{
    \"package_key\": \"standart\"
}"
const url = new URL(
    "https://dowaba.com/api/ai-credit/paypal/initiate"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "package_key": "standart"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/paypal/initiate';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'package_key' => 'standart',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ai-credit/paypal/initiate

Headers

Content-Type        

Example: application/json

Body Parameters

package_key   string     

AI kredi paketi anahtarı (mini | standart | pro | kurumsal). Example: standart

Apple StoreKit consumable (AI kredi paketi) doğrulama + cüzdana grant.

Abonelik IAP'tan (IAPController) AYRI: kredi consumable'dır, AiCreditMeter::purchase ile USD cüzdana eklenir. Mobil buyConsumable sonrası bu endpoint'i çağırır.

Example request:
curl --request POST \
    "https://dowaba.com/api/ai-credit/apple/verify" \
    --header "Content-Type: application/json" \
    --data "{
    \"receipt_data\": \"consequatur\",
    \"product_id\": \"com.dowaba.app.credit.standart\",
    \"transaction_id\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/ai-credit/apple/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "receipt_data": "consequatur",
    "product_id": "com.dowaba.app.credit.standart",
    "transaction_id": "consequatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/apple/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'receipt_data' => 'consequatur',
            'product_id' => 'com.dowaba.app.credit.standart',
            'transaction_id' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ai-credit/apple/verify

Headers

Content-Type        

Example: application/json

Body Parameters

receipt_data   string     

base64 StoreKit receipt. Example: consequatur

product_id   string     

Kredi product ID (com.dowaba.app.credit.{mini|standart|pro|kurumsal}). Example: com.dowaba.app.credit.standart

transaction_id   string     

Apple transaction ID (idempotency). Example: consequatur

Google Play consumable (AI kredi paketi) doğrulama + cüzdana grant.

Example request:
curl --request POST \
    "https://dowaba.com/api/ai-credit/google/verify" \
    --header "Content-Type: application/json" \
    --data "{
    \"purchase_token\": \"consequatur\",
    \"product_id\": \"com.dowaba.app.credit.standart\",
    \"order_id\": \"consequatur\"
}"
const url = new URL(
    "https://dowaba.com/api/ai-credit/google/verify"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "purchase_token": "consequatur",
    "product_id": "com.dowaba.app.credit.standart",
    "order_id": "consequatur"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/ai-credit/google/verify';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'purchase_token' => 'consequatur',
            'product_id' => 'com.dowaba.app.credit.standart',
            'order_id' => 'consequatur',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/ai-credit/google/verify

Headers

Content-Type        

Example: application/json

Body Parameters

purchase_token   string     

Play Billing purchase token. Example: consequatur

product_id   string     

Kredi product ID (com.dowaba.app.credit.*). Example: com.dowaba.app.credit.standart

order_id   string  optional    

Play order ID (idempotency, opsiyonel). Example: consequatur

GET api/reseller/branding

Example request:
curl --request GET \
    --get "https://dowaba.com/api/reseller/branding"
const url = new URL(
    "https://dowaba.com/api/reseller/branding"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/branding';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/reseller/branding

PATCH api/reseller/branding

Example request:
curl --request PATCH \
    "https://dowaba.com/api/reseller/branding" \
    --header "Content-Type: multipart/form-data" \
    --form "app_name=vmqeopfuudtdsufvyvddq"\
    --form "app_primary_color=#4CD4ab"\
    --form "app_secondary_color=#4CD4ab"\
    --form "remove_logo=1"\
    --form "logo_present=0"\
    --form "app_logo=@/tmp/phpG0wvOl" 
const url = new URL(
    "https://dowaba.com/api/reseller/branding"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('app_name', 'vmqeopfuudtdsufvyvddq');
body.append('app_primary_color', '#4CD4ab');
body.append('app_secondary_color', '#4CD4ab');
body.append('remove_logo', '1');
body.append('logo_present', '0');
body.append('app_logo', document.querySelector('input[name="app_logo"]').files[0]);

fetch(url, {
    method: "PATCH",
    headers,
    body,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/reseller/branding';
$response = $client->patch(
    $url,
    [
        'headers' => [
            'Content-Type' => 'multipart/form-data',
        ],
        'multipart' => [
            [
                'name' => 'app_name',
                'contents' => 'vmqeopfuudtdsufvyvddq'
            ],
            [
                'name' => 'app_primary_color',
                'contents' => '#4CD4ab'
            ],
            [
                'name' => 'app_secondary_color',
                'contents' => '#4CD4ab'
            ],
            [
                'name' => 'remove_logo',
                'contents' => '1'
            ],
            [
                'name' => 'logo_present',
                'contents' => '0'
            ],
            [
                'name' => 'app_logo',
                'contents' => fopen('/tmp/phpG0wvOl', 'r')
            ],
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

PATCH api/reseller/branding

POST api/reseller/branding

Headers

Content-Type        

Example: multipart/form-data

Body Parameters

app_name   string  optional    

Must not be greater than 64 characters. Example: vmqeopfuudtdsufvyvddq

app_primary_color   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

app_secondary_color   string  optional    

Must match the regex /^#[0-9A-Fa-f]{6}$/. Example: #4CD4ab

app_logo   file  optional    

max 5 MB: kırpma aracı çıktısı her zaman çok daha küçük; bu sadece doğrudan API / kırpmasız yükleme için güvenli tavan. Must be a file. Must be an image. Must not be greater than 5120 kilobytes. Example: /tmp/phpG0wvOl

remove_logo   boolean  optional    

Example: true

logo_present   string  optional    

Example: 0

Must be one of:
  • 0
  • 1

POST api/stripe/webhook

Example request:
curl --request POST \
    "https://dowaba.com/api/stripe/webhook"
const url = new URL(
    "https://dowaba.com/api/stripe/webhook"
);



fetch(url, {
    method: "POST",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/stripe/webhook';
$response = $client->post($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/stripe/webhook

X OAuth callback (public route — no auth middleware).

X popup'tan ?code=...&state=... olarak çağrılır. Code → access/refresh token exchange yapılır, sonuçlar Cache'e konup popup parent'a postMessage ile gönderilir.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/x/oauth/callback"
const url = new URL(
    "https://dowaba.com/api/x/oauth/callback"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/x/oauth/callback';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):

Show headers
cache-control: no-cache, private
content-type: text/html; charset=utf-8
x-frame-options: SAMEORIGIN
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: geolocation=(), microphone=(self), camera=(self), payment=(), usb=(), magnetometer=(), gyroscope=()
cross-origin-opener-policy: unsafe-none
content-security-policy-report-only: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://accounts.google.com https://appleid.cdn-apple.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; media-src 'self' blob:; connect-src 'self' wss://dowaba.com wss://*.dowaba.com https://generativelanguage.googleapis.com; frame-src 'self' https://accounts.google.com https://appleid.apple.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; worker-src 'self' blob:
content-language: en
vary: Accept-Language, Cookie, Authorization, Origin
 

<!DOCTYPE html>
<html>
<head><title>X Bağlantısı</title></head>
<body>
<p>İşlem tamamlanıyor...</p>
<script>
(function() {
    var oauthData = {"error":"İzin verilmedi"};
    var bcSent = false;
    var openerSent = false;

    try {
        if (typeof BroadcastChannel === 'function') {
            var bc = new BroadcastChannel('x_oauth');
            bc.postMessage({ type: 'x_oauth', data: oauthData });
            bc.close();
            bcSent = true;
        }
    } catch (e) {}

    var opener = null;
    try { opener = window.opener; } catch (e) {}
    if (opener) {
        try {
            opener.postMessage({ type: 'x_oauth', data: oauthData }, '*');
            openerSent = true;
        } catch (e) {}
    }

    if (bcSent || openerSent) {
        document.body.innerHTML = '<div style="font-family:system-ui,-apple-system,sans-serif;text-align:center;padding:60px 20px;color:#0f172a"><div style="font-size:48px;margin-bottom:16px">✓</div><h2 style="margin:0 0 8px;font-size:20px">X bağlandı</h2><p style="color:#64748b;margin:0">Bu pencereyi kapatabilirsiniz.</p></div>';
        setTimeout(function(){ try { window.close(); } catch (e) {} }, 600);
        return;
    }

    window.location.href = "\/admin\/#\/sites?oauth_error=%C4%B0zin+verilmedi";
})();
</script>
</body>
</html>
 

Request      

GET api/x/oauth/callback

Site Sahipliği Devri

Bir site için yeni sahibe devir teklifi açar (yalnız mevcut sahip).

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/sites/1/transfer/offer" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"to_email\": \"yeni@firma.com\",
    \"message\": \"Siteyi sana devrediyorum.\"
}"
const url = new URL(
    "https://dowaba.com/api/sites/1/transfer/offer"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "to_email": "yeni@firma.com",
    "message": "Siteyi sana devrediyorum."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/1/transfer/offer';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'to_email' => 'yeni@firma.com',
            'message' => 'Siteyi sana devrediyorum.',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/sites/{site_id}/transfer/offer

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

site_id   integer     

The ID of the site. Example: 1

site   integer     

Devredilecek site. Example: 1

Body Parameters

to_email   string     

Yeni sahibin kayıtlı e-postası. Example: yeni@firma.com

message   string  optional    

Opsiyonel not (maks 1000). Example: Siteyi sana devrediyorum.

Kullanıcıya gelen + kullanıcının açtığı devir tekliflerini listeler.

requires authentication

Example request:
curl --request GET \
    --get "https://dowaba.com/api/site-transfers?box=incoming" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/site-transfers"
);

const params = {
    "box": "incoming",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/site-transfers';
$response = $client->get(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
        'query' => [
            'box' => 'incoming',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (401):

Show headers
cache-control: no-cache, private
content-type: application/json
vary: Origin
 

{
    "message": "Unauthenticated."
}
 

Request      

GET api/site-transfers

Headers

Authorization        

Example: Bearer {TOKEN}

Query Parameters

box   string  optional    

incoming|outgoing|all (default all). Example: incoming

Teklifi kabul et — devir gerçekleşir, tüm haklar geçer.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/site-transfers/1/accept" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"note\": \"Teşekkürler.\"
}"
const url = new URL(
    "https://dowaba.com/api/site-transfers/1/accept"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "note": "Teşekkürler."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/site-transfers/1/accept';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'note' => 'Teşekkürler.',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/site-transfers/{transfer_id}/accept

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

transfer_id   integer     

The ID of the transfer. Example: 1

transfer   integer     

Teklif ID. Example: 5

Body Parameters

note   string  optional    

Opsiyonel not. Example: Teşekkürler.

Teklifi reddet.

requires authentication

Example request:
curl --request POST \
    "https://dowaba.com/api/site-transfers/1/reject" \
    --header "Authorization: Bearer {TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"note\": \"Şu an alamıyorum.\"
}"
const url = new URL(
    "https://dowaba.com/api/site-transfers/1/reject"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "note": "Şu an alamıyorum."
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/site-transfers/1/reject';
$response = $client->post(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
            'Content-Type' => 'application/json',
        ],
        'json' => [
            'note' => 'Şu an alamıyorum.',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

POST api/site-transfers/{transfer_id}/reject

Headers

Authorization        

Example: Bearer {TOKEN}

Content-Type        

Example: application/json

URL Parameters

transfer_id   integer     

The ID of the transfer. Example: 1

transfer   integer     

Teklif ID. Example: 5

Body Parameters

note   string  optional    

Opsiyonel red sebebi. Example: Şu an alamıyorum.

Açtığın teklifi iptal et (kabul edilmeden önce).

requires authentication

Example request:
curl --request DELETE \
    "https://dowaba.com/api/site-transfers/1" \
    --header "Authorization: Bearer {TOKEN}"
const url = new URL(
    "https://dowaba.com/api/site-transfers/1"
);

const headers = {
    "Authorization": "Bearer {TOKEN}",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/site-transfers/1';
$response = $client->delete(
    $url,
    [
        'headers' => [
            'Authorization' => 'Bearer {TOKEN}',
        ],
    ]
);
$body = $response->getBody();
print_r(json_decode((string) $body));

Request      

DELETE api/site-transfers/{transfer_id}

Headers

Authorization        

Example: Bearer {TOKEN}

URL Parameters

transfer_id   integer     

The ID of the transfer. Example: 1

transfer   integer     

Teklif ID. Example: 5

WhatsApp — Panel

Siteye bağlı WhatsApp profillerini şablon-uyumluluk bilgisiyle listele.

Example request:
curl --request GET \
    --get "https://dowaba.com/api/sites/5/whatsapp-profiles"
const url = new URL(
    "https://dowaba.com/api/sites/5/whatsapp-profiles"
);



fetch(url, {
    method: "GET",
}).then(response => response.json());
$client = new \GuzzleHttp\Client();
$url = 'https://dowaba.com/api/sites/5/whatsapp-profiles';
$response = $client->get($url);
$body = $response->getBody();
print_r(json_decode((string) $body));

Example response (200):


{
    "data": [
        {
            "id": 12,
            "name": "Klinik WA",
            "connection_type": "meta_business",
            "supports_templates": true
        }
    ]
}
 

Request      

GET api/sites/{site}/whatsapp-profiles

URL Parameters

site   integer     

Site ID. Example: 5