# AdsPRO API - Zarzadzanie produktami (publiczna dokumentacja)

Ten dokument opisuje endpointy HTTP dostepne w `api.php` do zarzadzania danymi produktow.
Format jest przygotowany pod integracje automatyczne (AI/agent/workflow).

## 1. Informacje bazowe

- Metoda: `GET` lub `POST` (`application/x-www-form-urlencoded` albo query string).
- Endpoint bazowy: `https://TWOJA-DOMENA/api.php`
- Parametr routingu: `action`
- Odpowiedzi: JSON
- Kodowanie: UTF-8

Przyklady zakladaja, ze:
- domena: `https://example.com`
- klucz API: `YOUR_API_KEY`
- klient: `client_id=12`
- produkt: `offer_id=SKU-123`

## 2. Autoryzacja

Kazdy endpoint produktowy wymaga poprawnego parametru:

- `api_key` - klucz porownywany z `settings.setting_key = api_key`

Brak lub zly klucz zwraca:

```json
{
  "result": "error",
  "message": "Invalid api_key"
}
```

HTTP status: `401`

## 3. Wspolne parametry

- `offer_id` (string, wymagany) - zewnetrzny identyfikator produktu.
- `client_id` (int, wymagany) - lokalny identyfikator klienta.

Jesli produkt nie istnieje dla pary `offer_id + client_id`, API zwraca:

```json
{
  "result": "error",
  "message": "Product not found"
}
```

HTTP status: `404`

## 4. Endpointy produktowe

### 4.1 Ustawienie tytulu produktu

- `action=product_title_set`
- Cel: zapisuje `products.title`

Parametry:
- `api_key` (string, wymagany)
- `offer_id` (string, wymagany)
- `client_id` (int, wymagany)
- `title` (string, opcjonalny)

Uwagi:
- `title` jest przycinany (`trim`).
- Pusty `title` ustawia `products.title = NULL` (czyszczenie pola).
- Zmiana zapisuje komentarz techniczny w `products_comments`.

Przyklad:

```bash
curl -X POST "https://example.com/api.php" \
  -d "action=product_title_set" \
  -d "api_key=YOUR_API_KEY" \
  -d "client_id=12" \
  -d "offer_id=SKU-123" \
  -d "title=Buty biegowe meskie Air Run 42"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "title": "Buty biegowe meskie Air Run 42"
}
```

### 4.2 Sprawdzenie, czy tytul byl zmieniony

- `action=product_title_changed_check`
- Cel: sprawdza, czy custom tytul rozni sie od bazowej nazwy produktu

Logika pola `title_changed`:
- `true` gdy `products.title` jest niepuste i inne niz `products.name`
- `false` w pozostalych przypadkach

Parametry:
- `api_key` (string, wymagany)
- `offer_id` (string, wymagany)
- `client_id` (int, wymagany)

Przyklad:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=product_title_changed_check" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "client_id=12" \
  --data-urlencode "offer_id=SKU-123"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "title_changed": true,
  "default_name": "Buty Air Run - wariant bazowy",
  "custom_title": "Buty biegowe meskie Air Run 42"
}
```

### 4.3 Ustawienie Google Product Category

- `action=product_google_category_set`
- Cel: zapisuje `products.google_product_category`

Parametry:
- `api_key` (string, wymagany)
- `offer_id` (string, wymagany)
- `client_id` (int, wymagany)
- `google_product_category` (string, opcjonalny)

Uwagi:
- wartosc jest przycinana (`trim`)
- pusta wartosc ustawia `NULL` (czyszczenie pola)
- zmiana zapisuje komentarz techniczny w `products_comments`

Przyklad:

```bash
curl -X POST "https://example.com/api.php" \
  -d "action=product_google_category_set" \
  -d "api_key=YOUR_API_KEY" \
  -d "client_id=12" \
  -d "offer_id=SKU-123" \
  -d "google_product_category=Apparel & Accessories > Shoes"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "google_product_category": "Apparel & Accessories > Shoes"
}
```

### 4.4 Odczyt Google Product Category

- `action=product_google_category_get`
- Cel: odczytuje `products.google_product_category`

Parametry:
- `api_key` (string, wymagany)
- `offer_id` (string, wymagany)
- `client_id` (int, wymagany)

Przyklad:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=product_google_category_get" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "client_id=12" \
  --data-urlencode "offer_id=SKU-123"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "google_product_category": "Apparel & Accessories > Shoes"
}
```

Jesli kategoria nie jest ustawiona:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "google_product_category": null
}
```

### 4.5 Pobranie produktow do optymalizacji

- `action=products_to_optimize`
- Cel: zwraca liste produktow posortowanych wg klikniec (malejaco), ktore nie maja ustawionego custom tytulu (`title`) lub kategorii Google (`google_product_category`)

Identyfikacja klienta (wymagany dokladnie jeden z trzech):
- `client_id` (int) - lokalny identyfikator klienta w adsPRO
- `google_ads_id` (string) - ID konta Google Ads (z myslnikami lub bez, np. `123-456-7890` lub `1234567890`)
- `merchant_id` (string) - ID konta Google Merchant Center (z myslnikami lub bez)

Parametry dodatkowe:
- `api_key` (string, wymagany)
- `limit` (int, opcjonalny) - liczba produktow do zwrocenia (domyslnie 10, max 100)

Logika:
- Wybiera produkty, ktorych `title` jest pusty/NULL **lub** `google_product_category` jest pusty/NULL
- Pomija produkty z 0 klikniec (all-time)
- Sortuje po `clicks_all_time` malejaco (produkty z najwiekszym ruchem na gorze)
- Agreguje dane z `products_aggregate` (suma klikniec ze wszystkich kampanii/grup reklam)

Przyklad z `client_id`:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=products_to_optimize" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "client_id=12" \
  --data-urlencode "limit=10"
```

Przyklad z `google_ads_id`:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=products_to_optimize" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "google_ads_id=123-456-7890"
```

Przyklad z `merchant_id`:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=products_to_optimize" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "merchant_id=987654321"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "client_id": 12,
  "count": 3,
  "products": [
    {
      "id": 987,
      "offer_id": "SKU-123",
      "original_name": "Buty sportowe Nike Air",
      "custom_title": null,
      "google_product_category": null,
      "product_url": "https://example.com/buty-nike-air",
      "clicks_30": 45,
      "clicks_all_time": 312,
      "impressions_30": 1200,
      "cost_30": "89.500000",
      "conversions_30": "3.000000",
      "conversion_value_30": "450.000000"
    },
    {
      "id": 654,
      "offer_id": "SKU-456",
      "original_name": "Koszulka Adidas",
      "custom_title": "Koszulka sportowa Adidas Originals",
      "google_product_category": null,
      "product_url": "https://example.com/koszulka-adidas",
      "clicks_30": 22,
      "clicks_all_time": 198,
      "impressions_30": 800,
      "cost_30": "45.200000",
      "conversions_30": "1.000000",
      "conversion_value_30": "120.000000"
    }
  ]
}
```

Bledy specyficzne:
- Brak parametru identyfikujacego klienta: `422` z `"Missing required param: client_id, google_ads_id or merchant_id"`
- Klient nie znaleziony: `404` z `"Client not found"`

### 4.6 Ustawienie custom_label_4

- `action=product_custom_label_4_set`
- Cel: zapisuje `products.custom_label_4`

Parametry:
- `api_key` (string, wymagany)
- `offer_id` (string, wymagany)
- `client_id` (int, wymagany)
- `custom_label_4` (string, opcjonalny) - wartosc etykiety; alias: `value`

Uwagi:
- wartosc jest przycinana (`trim`)
- pusta wartosc ustawia pusty string (czyszczenie pola)
- zmiana zapisuje komentarz techniczny w `products_comments`
- jesli zapis sie nie powiedzie, API zwraca blad 500

Przyklad:

```bash
curl -X POST "https://example.com/api.php" \
  -d "action=product_custom_label_4_set" \
  -d "api_key=YOUR_API_KEY" \
  -d "client_id=12" \
  -d "offer_id=SKU-123" \
  -d "custom_label_4=bestseller"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "custom_label_4": "bestseller"
}
```

### 4.6b Odczyt custom_label_4

- `action=product_custom_label_4_get`
- Cel: odczytuje `products.custom_label_4`

Parametry:
- `api_key` (string, wymagany)
- `offer_id` (string, wymagany)
- `client_id` (int, wymagany)

Przyklad:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=product_custom_label_4_get" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "client_id=12" \
  --data-urlencode "offer_id=SKU-123"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "custom_label_4": "bestseller"
}
```

Jesli etykieta nie jest ustawiona:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "client_id": 12,
  "custom_label_4": ""
}
```

### 4.7 Odczyt minimalnego ROAS produktu

- `action=product_min_roas_get`
- Cel: odczytuje `products.min_roas` dla wskazanego produktu

Identyfikacja produktu (wymagany dokladnie jeden z dwoch):
- `product_id` (int) - wewnetrzny identyfikator produktu w adsPRO (`products.id`)
- `google_ads_product_id` (string) - zewnetrzny identyfikator produktu z Google Ads (mapowany do `products.offer_id`)

Parametry dodatkowe:
- `api_key` (string, wymagany)

Przyklad z `product_id`:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=product_min_roas_get" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "product_id=987"
```

Przyklad z `google_ads_product_id`:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=product_min_roas_get" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "google_ads_product_id=SKU-123"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "min_roas": 450
}
```

Jesli minimalny ROAS nie jest ustawiony:

```json
{
  "result": "ok",
  "product_id": 987,
  "offer_id": "SKU-123",
  "min_roas": null
}
```

Bledy specyficzne:
- Brak identyfikatora produktu: `422` z `"Missing required param: product_id or google_ads_product_id"`
- Podano oba identyfikatory jednoczesnie: `422` z `"Provide only one identifier: product_id or google_ads_product_id"`
- Produkt nie znaleziony: `404` z `"Product not found"`

### 4.8 Odczyt sredniego minimalnego ROAS dla klienta

- `action=client_avg_min_roas_get`
- Cel: zwraca sredni `min_roas` dla produktow danego klienta

Identyfikacja klienta (wymagany dokladnie jeden z dwoch):
- `client_id` (int) - wewnetrzny identyfikator klienta w adsPRO
- `google_ads_id` (string) - ID konta Google Ads (z myslnikami lub bez)

Parametry dodatkowe:
- `api_key` (string, wymagany)

Logika:
- Srednia liczona jest z `products.min_roas`
- Do sredniej wchodza tylko produkty z ustawionym `min_roas` (`IS NOT NULL`)
- Gdy brak produktow z ustawionym `min_roas`, `avg_min_roas` zwracane jest jako `null`

Przyklad z `client_id`:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=client_avg_min_roas_get" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "client_id=12"
```

Przyklad z `google_ads_id`:

```bash
curl -G "https://example.com/api.php" \
  --data-urlencode "action=client_avg_min_roas_get" \
  --data-urlencode "api_key=YOUR_API_KEY" \
  --data-urlencode "google_ads_id=123-456-7890"
```

Przyklad odpowiedzi:

```json
{
  "result": "ok",
  "client_id": 12,
  "google_ads_id": "123-456-7890",
  "products_with_min_roas": 24,
  "avg_min_roas": 436.25
}
```

Jesli klient nie ma ustawionego `min_roas` na zadnym produkcie:

```json
{
  "result": "ok",
  "client_id": 12,
  "google_ads_id": "123-456-7890",
  "products_with_min_roas": 0,
  "avg_min_roas": null
}
```

Bledy specyficzne:
- Brak identyfikatora klienta: `422` z `"Missing required param: client_id or google_ads_id"`
- Podano oba identyfikatory jednoczesnie: `422` z `"Provide only one identifier: client_id or google_ads_id"`
- Klient nie znaleziony: `404` z `"Client not found"`

## 5. Walidacja i bledy

### 5.1 Brak wymaganych parametrow

```json
{
  "result": "error",
  "message": "Missing required params: offer_id, client_id"
}
```

HTTP status: `422`

### 5.2 Nieznana akcja

`api.php` nie zwraca centralnego bledu dla nieznanej `action`.
Przy integracji AI zawsze ustawiaj jawnie `action` i weryfikuj, czy odpowiedz to JSON.

## 6. Zalecany kontrakt dla agentow AI

- Zawsze wysylaj `api_key`, `action`, `client_id`, `offer_id`.
- Po `product_title_set` od razu wywolaj `product_title_changed_check`.
- Po `product_google_category_set` od razu wywolaj `product_google_category_get`.
- Po `product_custom_label_4_set` od razu wywolaj `product_custom_label_4_get`.
- Traktuj `null` jako brak wartosci.
- Przy statusach `401`, `404`, `422` przerywaj workflow i zwracaj czytelny blad operatorowi.

## 7. Minimalny scenariusz end-to-end

1. Pobierz liste produktow do optymalizacji (`products_to_optimize`)
2. Dla kazdego produktu z listy:
   a. Jesli `custom_title` jest `null` - ustaw tytul (`product_title_set`)
   b. Potwierdz zmiane tytulu (`product_title_changed_check`)
   c. Jesli `google_product_category` jest `null` - ustaw kategorie (`product_google_category_set`)
   d. Odczytaj kategorie (`product_google_category_get`)

To daje prosty, deterministyczny przeplyw dla automatyzacji AI.
