> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apiyi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# В журнале указано, что вызов завершился и был тарифицирован, но мой клиент так и не получил ответ — как это отладить?

> Длительность в журнале консоли охватывает только момент, когда шлюз завершает обработку, тогда как ваш клиент ждёт последний байт и сигнал завершения соединения. На этой странице показано, как измерить, где возникает этот разрыв, как выполнить бенчмарк пропускной способности между двумя серверами и какие поля должна записывать ваша инструментация.

## Краткий ответ

<Info>
  **Длительность в журнале консоли и тайм-аут вашего клиента измеряют не один и тот же промежуток.**

  * Длительность в журнале идёт до того момента, когда **шлюз завершает обработку**;
  * Ваш клиент не считается завершившимся, пока **не придёт последний байт body ответа и соединение не сигнализирует о завершении**.

  Так что ситуация «журнал показывает завершение за 280 секунд, но мой тайм-аут в 600 секунд так и не получил никаких данных» вполне возможна — **и этот запрос действительно был успешным, и тарификация за него действительно была выполнена**. Разрыв находится в сегментах, которые журнал вообще не охватывал.

  На этой странице показано, как **измерить** этот разрыв, привязать его к конкретному сегменту и определить правильную причину.
</Info>

Эта страница посвящена **вызовам без потоковой передачи с большими ответами**: эндпоинты изображений, возвращающие base64, — классический случай (body ответа имеют размер от нескольких MB до десятков MB), и долгий текстовый вывод без потоковой передачи ведёт себя так же. Вызовы с потоковой передачей и небольшие ответы обычно не затрагиваются.

## Что на самом деле покрывает длительность в логе

Общая задержка вызова делится на пять этапов:

```
client total = connect + request upload + upstream generation + response download + waiting for finish signal
                                    └─ the console log's duration covers only this ─┘
```

| Этап                          | На что уходит время                                                                                             | Учитывается ли в логе консоли?                   |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
| Подключение (DNS / TCP / TLS) | Ваша сеть достигает нашей точки входа                                                                           | ❌                                                |
| Загрузка запроса              | Ваша пропускная способность **upstream**; при наличии reference images тело запроса также занимает несколько MB | ❌                                                |
| Генерация upstream            | Непосредственно генерация моделью                                                                               | ✅ **это и есть длительность, которую вы видите** |
| Загрузка ответа               | Ваша пропускная способность **downstream**, сильно связанная с concurrency                                      | ❌                                                |
| Ожидание сигнала о завершении | Завершающий chunk HTTP chunked transfer                                                                         | ❌                                                |

<Warning>
  **Этот разрыв не отображается ни в одном поле лога.**

  Мы внутренне провели контролируемое сравнение на уровне raw-socket: для одной и той же партии запросов наш бэкенд зафиксировал длительность 5 секунд со статусом успеха, тогда как клиент фактически ждал 37–40 секунд до полного ответа. Эти 31–35 секунд прошли **после** того, как шлюз завершил обработку, и ни одно поле длительности их не записывает.

  Это означает: **ссылаться на длительность в логе, чтобы опровергнуть «у меня это заняло вечность», — ничего не доказывает**: эти два числа никогда не противоречили друг другу. Чтобы локализовать проблему, требуется покомпонентное измерение времени на стороне клиента.
</Warning>

Поля, доступные в консоли и в [Log Query API](/en/api-capabilities/log-query): `duration_for_view` (длительность вызова в секундах), `is_stream` и `request_id` (указывайте это поле при сообщении о проблеме).

## Шаг 1: определите разрыв для сегмента с помощью одного curl

Это отправная точка для всего ниже. Сначала выполните это, затем решите, какой раздел подходит.

```bash theme={null}
curl -sS -o /dev/null --max-time 900 \
  -w 'connect=%{time_connect} pretransfer=%{time_pretransfer} ttfb=%{time_starttransfer} total=%{time_total} bytes=%{size_download} speed=%{speed_download}\n' \
  -H "Authorization: Bearer $APIYI_API_KEY" \
  -H "Content-Type: application/json" \
  -X POST https://api.apiyi.com/v1/images/generations \
  -d '{"model":"gpt-image-2-vip","prompt":"a watercolor mountain village","size":"2048x2048"}'
```

Три производные метрики превращают эти сырые числа в осмысленные сегменты:

| Метрика                         | Формула                          | Значение                                      |
| ------------------------------- | -------------------------------- | --------------------------------------------- |
| Время загрузки                  | `pretransfer − connect`          | Сколько времени заняла отправка тела запроса  |
| Время генерации                 | `ttfb − pretransfer`             | **≈ длительность, показанная в логе консоли** |
| Время скачивания                | `total − ttfb`                   | Сколько времени заняло получение тела ответа  |
| Эффективная downstream-скорость | `size_download / (total − ttfb)` | Или просто смотрите `speed_download` (байт/с) |

### Чтение результата

Сопоставьте ваши числа с этой таблицей — она определяет, что делать дальше:

| Что вы наблюдаете                                                                        | Где находится разрыв                                           | Следующий шаг                                                                         |
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `ttfb` ≈ длительности лога, а `total` ≈ `ttfb`                                           | Разрыва нет — сама модель просто медленная                     | Увеличьте тайм-аут, см. [Как избежать тайм-аутов API?](/ru/faq/timeout-configuration) |
| `total − ttfb` большое, `speed_download` низкое                                          | **Пропускная способность downstream**                          | Разделы этой страницы о throughput и размере полезной нагрузки                        |
| `total − ttfb` большое, но количество байтов пришло давно и ничего нового не последовало | **Сигнал завершения не пришёл**                                | [Зависание завершения запроса изображения](/ru/api-capabilities/image-tail-stall)     |
| `pretransfer − connect` большое                                                          | **Загрузка медленная** — изображения-источники слишком большие | Сожмите каждое входное изображение до размера менее 1.5MB                             |
| `ECONNRESET` / SSL EOF в середине передачи                                               | **Разрыв downstream-соединения**                               | [Обрывы соединения с Image API](/ru/api-capabilities/image-connection-drops)          |
| curl работает нормально, но истекает тайм-аут только в коде вашего приложения            | **На стороне клиента**                                         | Раздел этой страницы «Три легко упускаемые причины на стороне клиента»                |

<Tip>
  Одного запуска недостаточно. Этот класс проблем **приходит во временных окнах** — внутри окна каждый вызов подряд затрагивается, а вне его десятки вызовов подряд работают совершенно нормально. Выполните это 10 раз, посмотрите на распределение и отметьте время суток вместе с часовым поясом.
</Tip>

## Шаг 2: как измерять «данные пришли, но соединение так и не завершилось»

Если таблица указывает на третью строку, вам нужно более точное наблюдение: читайте ответ чанк за чанком, фиксируя время прихода каждого чанка и интервалы между ними. Вопрос, на который нужно ответить, — **после прихода последнего байта как долго соединение ещё оставалось открытым?**

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    import json, os, time, urllib.request

    body = json.dumps({
        "model": "gpt-image-2-vip",
        "prompt": "a watercolor mountain village",
        "size": "2048x2048",
    }).encode()

    req = urllib.request.Request(
        "https://api.apiyi.com/v1/images/generations",
        data=body,
        headers={
            "Authorization": "Bearer " + os.environ["APIYI_API_KEY"],
            "Content-Type": "application/json",
        },
    )

    t0 = time.monotonic()
    resp = urllib.request.urlopen(req, timeout=900)
    ttfb = time.monotonic() - t0            # headers arrived ≈ generation finished

    chunks, total, last = [], 0, time.monotonic()
    while True:
        buf = resp.read(65536)
        now = time.monotonic()
        if not buf:
            break
        total += len(buf)
        chunks.append((round(now - t0, 3), round(now - last, 3), total))
        last = now
    t_end = time.monotonic() - t0

    transfer = t_end - ttfb
    max_gap = max((gap for _, gap, _ in chunks), default=0)
    p99_at = next((t for t, _, cum in chunks if cum >= total * 0.99), ttfb)

    print(json.dumps({
        "ttfb_s": round(ttfb, 2),                 # ≈ the console log duration
        "transfer_s": round(transfer, 2),         # download
        "total_s": round(t_end, 2),               # what you actually experienced
        "body_bytes": total,
        "down_KBps": round(total / 1024 / transfer, 1) if transfer > 0.001 else None,
        "max_gap_s": max_gap,                     # largest silence between chunks
        "tail_99_s": round(t_end - p99_at, 2),    # how long the last 1% took
    }))
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript theme={null}
    const t0 = Date.now();
    const resp = await fetch("https://api.apiyi.com/v1/images/generations", {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.APIYI_API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        model: "gpt-image-2-vip",
        prompt: "a watercolor mountain village",
        size: "2048x2048",
      }),
    });
    const ttfb = (Date.now() - t0) / 1000;

    const reader = resp.body.getReader();
    const curve = [];
    let total = 0, maxGap = 0, last = Date.now();
    while (true) {
      const { done, value } = await reader.read();
      const now = Date.now();
      if (done) break;
      total += value.length;
      maxGap = Math.max(maxGap, (now - last) / 1000);
      curve.push([(now - t0) / 1000, total]);
      last = now;
    }
    const totalS = (Date.now() - t0) / 1000;
    const p99At = (curve.find(([, cum]) => cum >= total * 0.99) || [ttfb])[0];

    console.log({
      ttfb_s: ttfb,
      transfer_s: totalS - ttfb,
      total_s: totalS,
      body_bytes: total,
      down_KBps: total / 1024 / (totalS - ttfb),
      max_gap_s: maxGap,
      tail_99_s: totalS - p99At,
    });
    ```
  </Tab>
</Tabs>

**Порог обнаружения**: `tail_99` свыше 30 секунд или `max_gap` свыше 30 секунд считается одним случаем «зависания хвоста». Признак — `max_gap`, возникающий в момент, когда счётчик байтов уже достиг 100%: каждый байт уже пришёл, и только после этого началось ожидание.

<Warning>
  **Не охватывайте три фазы одним значением timeout.**

  Это самая простая ловушка: использование одного timeout для «ожидания первого байта» и «ожидания передачи» сводит две проблемы с совершенно разными корневыми причинами к одной неразличимой ошибке.

  | Фаза                                                            | Значение                                                           | Рекомендуемое значение |
  | --------------------------------------------------------------- | ------------------------------------------------------------------ | ---------------------- |
  | Ожидание первого байта                                          | Upstream генерирует — **медленно не значит сломано**               | 120–180 s              |
  | Пауза между чанками                                             | Передача началась, затем застопорилась                             | 20–30 s                |
  | Ожидание сигнала завершения после того, как данные уже переданы | Льготный период; по его истечении завершайте соединение проактивно | 3–5 s                  |

  Разделите их, и ваши журналы прямо покажут, было ли это «медленной генерацией» или «доставлено, но так и не завершено» — без догадок.
</Warning>

## Шаг 3: измерение пропускной способности между двумя серверами

### Между двумя машинами, которыми вы владеете

Используйте `iperf3` для измерения реальной пропускной способности — это самый точный вариант:

```bash theme={null}
# Server side (the machine being measured)
iperf3 -s

# Client side: forward direction, 30 seconds, 4 parallel streams
iperf3 -c <server-ip> -t 30 -P 4

# Add -R for the reverse direction — check both; image bottlenecks are downstream
iperf3 -c <server-ip> -t 30 -P 4 -R
```

### От вашего сервера к нашему API

**`iperf3` нельзя использовать на этом участке** — у нас не запущен iperf-сервер. Вместо этого измеряйте фактическую скорость по реальным вызовам:

```bash theme={null}
# 10 runs; take the median speed_download as your effective downstream bandwidth (bytes/sec)
for i in $(seq 1 10); do
  curl -sS -o /dev/null --max-time 900 \
    -w '%{time_starttransfer} %{time_total} %{size_download} %{speed_download}\n' \
    -H "Authorization: Bearer $APIYI_API_KEY" -H "Content-Type: application/json" \
    -X POST https://api.apiyi.com/v1/images/generations \
    -d '{"model":"gpt-image-2-vip","prompt":"test","size":"1024x1024"}'
done
```

Сочетайте это с проверками качества канала:

```bash theme={null}
mtr -rwzbc 100 api.apiyi.com        # per-hop packet loss and latency
ss -tin state established           # TCP retransmits, RTT, congestion window
```

<Warning>
  **Если таблица результатов указывает на «сигнал завершения так и не пришёл», `mtr` и `ping` здесь бесполезны.** В этом случае не потерян ни один байт, и качество канала в порядке, так что эти инструменты не покажут ничего плохого — и вы пойдёте по ложному следу. Перед тем как исследовать сеть, подтвердите с помощью скрипта выше, к какому классу вы относитесь.
</Warning>

### Проверьте, достаточно ли вашей пропускной способности

Тело ответа с изображением — это один цельный блок base64. Измеренные объёмы:

| Случай                                       | Тело ответа  |
| -------------------------------------------- | ------------ |
| `gpt-image-2` семейство, размер по умолчанию | около 2.6 MB |
| Семейство Gemini, 2K                         | около 13 MB  |
| Семейство Gemini, 4K                         | около 35 MB  |

Само кодирование base64 увеличивает полезную нагрузку примерно на 33%. Время загрузки при канале к самому себе:

| Исходящая пропускная способность | 2.6 MB | 13 MB  | 35 MB |
| -------------------------------- | ------ | ------ | ----- |
| 100 Mbps                         | 0.2 s  | 1.0 s  | 2.8 s |
| 10 Mbps                          | 2.1 s  | 10.4 s | 28 s  |
| 2 Mbps                           | 10.4 s | 52 s   | 140 s |

**Подвох в том, что эта таблица предполагает, что у вас есть канал к самому себе.** На практике:

```
bandwidth per request = egress bandwidth ÷ requests in flight
```

Например: исходящая скорость 10 Mbps, 30 параллельных запросов на изображения, 2.6 MB на ответ — каждому запросу достаётся примерно 0.04 MB/s, так что **только загрузка занимает 62 секунды**, и ни одна из этих секунд не появляется в журнале консоли. Удвойте параллельные запросы — и это число тоже удвоится.

<Tip>
  Вот почему говорят: «днём во время нагрузки всё уходит в тайм-аут, а тот же код ночью работает нормально». Модель не замедлилась; вашу пропускную способность делят между собой больше запросов.
</Tip>

## Шаг 4: какие поля должна записывать ваша инструментация

Чтобы точно описать симптом — для собственного анализа или чтобы отправить его нам — записывайте как минимум такие данные для каждого вызова:

| Поле                                          | Как получить                                                                             | Почему это важно                                                                                         |
| --------------------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| ID запроса                                    | Заголовок ответа; имя зависит от модели (`request-id` или `x-request-id`), проверьте оба | По нему мы ищем запись в backend-логе                                                                    |
| Время начала                                  | Локальное время клиента, **с указанием часового пояса**                                  | Чтобы сопоставить с backend-логами и окнами инцидентов                                                   |
| Время до первого байта                        | `ttfb`                                                                                   | Чтобы сравнить с длительностью на backend                                                                |
| Время последнего байта                        | Когда пришёл финальный chunk                                                             | Его разница с общим временем — это время простоя в ожидании сигнала завершения                           |
| Общее время                                   | Пока вы не получили полный ответ                                                         | То, что вы фактически наблюдали                                                                          |
| Байты тела ответа                             | Сумма прочитанного                                                                       | Чтобы вычислить скорость и подтвердить полноту                                                           |
| Скорость downstream                           | Байты ÷ время загрузки                                                                   | Низкая скорость означает пропускную способность                                                          |
| **Количество запросов в полёте в тот момент** | Ваш собственный счётчик параллельных запросов                                            | **Самый важный столбец** — без него вы не сможете сопоставить медленную работу с параллельными запросами |

Этот последний столбец люди часто пропускают, но именно он нередко и есть ответ: постройте график скорости в зависимости от параллельных запросов, и если скорость падает пропорционально росту параллельных запросов, узкое место — это пропускная способность, и искать больше нечего.

**Как использовать таблицу**: сопоставьте её с `duration_for_view` из лога консоли —

* Если значения близки → проблема в downstream-передаче; проверьте пропускную способность и параллельные запросы;
* Если значения далеко друг от друга → проблема в сигнале завершения или на стороне клиента.

## Четыре меры, которые сразу снижают риск

<Steps>
  <Step title="Переключитесь на вывод URL — изменение с наибольшим эффектом">
    `gpt-image-2-vip` и `gpt-image-2-all` принимают `response_format: "url"`, возвращая ссылку на изображение вместо base64. **Тело ответа уменьшается примерно с 2.6 MB до примерно 0.3 KB** — это одновременно устраняет проблемы со скачиванием и сигналом завершения, поскольку маленький ответ содержит `Content-Length`, и клиент сам понимает, когда всё завершено.

    Если ваш бизнес зависит от вывода URL, переключите группу token'а на `image2_OSS`: детерминированный вывод URL, который не будет деградировать до base64 при нехватке ресурсов, с **коэффициентом тарифа 1x без наценки**.

    <Warning>
      Официальный релей `gpt-image-2` **не** поддерживает этот параметр и возвращает 400 `unknown_parameter`, если вы его отправите. base64 сейчас — его единственный путь вывода.
    </Warning>
  </Step>

  <Step title="Уменьшите тело ответа">
    Когда вам нужно остаться на base64: `output_format=jpeg` с `output_compression` уменьшает размер более чем наполовину по сравнению с PNG; снижайте `size` и `quality` до того уровня, который вам действительно нужен, вместо того чтобы по умолчанию брать 4K. Сжатие входных референсных изображений до менее чем 1.5MB помогает и на этапе загрузки.
  </Step>

  <Step title="Ограничьте параллельные запросы уровнем, который поддерживает ваша пропускная способность">
    Переверните формулу выше: допустимое время скачивания × исходящая пропускная способность ÷ размер одного изображения — это ваш верхний предел параллельных запросов. Выше него большее количество параллельных запросов лишь замедляет каждый запрос, не повышая общую пропускную способность. Лимиты для каждой модели указаны в [Сколько параллельных запросов я могу использовать?](/ru/faq/api-concurrency).
  </Step>

  <Step title="Разделите таймаут на три части и завершайте проактивно, как только данные получены">
    Установите отдельно таймаут первого байта, межчанковый таймаут и таймаут завершения с запасом, как описано выше. Когда данные уже получены, но сигнал завершения так и не приходит, передайте в ваше приложение ответ, который у вас уже есть — полный код совместимости приведён в [Зависание завершения запроса изображения](/ru/api-capabilities/image-tail-stall).
  </Step>
</Steps>

## Часто задаваемые вопросы

<AccordionGroup>
  <Accordion title="Я так и не получил результат — почему с меня всё равно списали?">
    Потому что тарификация происходит **когда шлюз завершает обработку**, и к тому моменту upstream действительно уже сгенерировал и вернул результат. Получит ли его ваш клиент после этого, на уже понесённую стоимость не влияет. Проверенное сравнение: клиент, который отключается через 5 секунд, тарифицируется **абсолютно так же**, как и тот, который работает до завершения.

    Если посмотреть с другой стороны, это самый надёжный диагностический признак: **запись тарификации означает, что запрос действительно дошёл до upstream и успешно выполнился**, значит, проблема должна быть либо после завершения обработки шлюзом, либо ещё до того, как запрос был по-настоящему отправлен — подозревать upstream не нужно.

    У image-эндпоинтов нет async task ID, поэтому при разрыве соединения результат теряется; см. [Есть ли асинхронный image API?](/ru/faq/image-async-api).
  </Accordion>

  <Accordion title="Поможет ли увеличение таймаута с 600 до 1200 секунд?">
    Это зависит — именно поэтому перед любыми изменениями нужно сначала измерить:

    * **Медленная загрузка** (низкая скорость, число байт всё ещё растёт): да, увеличение таймаута поможет вам получить результат.
    * **Сигнал завершения так и не пришёл** (байты полностью переданы уже давно, в конце нет ничего нового): **нет**. Мы измеряли ещё 330 секунд ожидания в этом состоянии без единого нового байта; более длинный таймаут лишь откладывает момент, когда вы это заметите. Здесь вам нужно завершать его на клиенте принудительно.
  </Accordion>

  <Accordion title="Это моя проблема или проблема вашего шлюза?">
    Это может быть и так и так, поэтому сначала нужно измерить. Вот критерии для обеих сторон:

    * **Указывает на вас**: явно низкий `speed_download`, скорость, которая падает по мере роста параллельных запросов, потери пакетов в `mtr`, либо curl работает нормально, а таймаут случается только в коде вашего приложения.
    * **Указывает на нас**: байты были полностью переданы уже давно, а в конце долгое время не приходит ни одного нового байта. У шлюза действительно была проблема с «отложенным сигналом завершения» — её первопричиной было то, что учёт тарификации на image-пути блокировал обработку запросов — исправлено и подтверждено релизом upstream **13 августа 2026 года**. Даже в полностью здоровые периоды примерно 4% запросов всё равно ждут сигнал завершения ещё 10–79 секунд, при этом их данные уже полностью доставлены.

    Когда у вас будут замеры по каждому сегменту, пришлите их нам; это гораздо полезнее, чем «это медленно». Поля, которые нужно включить, приведены в следующем разделе.
  </Accordion>

  <Accordion title="Есть ли async API? Я бы предпочёл не держать соединение открытым">
    Генерация изображений сейчас везде синхронная, без эндпоинта для поиска по task ID. Вариант с асинхронной обработкой есть в дорожной карте и будет анонсирован отдельно, когда появится.

    До тех пор мы рекомендуем оборачивать асинхронную оболочку на своей стороне (возвращать локальный task ID при отправке, а фоновым worker'ам делать синхронный вызов); см. [Построение своей async-очереди](/ru/api-capabilities/image-async-queue).
  </Accordion>

  <Accordion title="Можно ли обойти это, поменяв endpoint или машину?">
    Зависит от того, в какой вы категории. Недостаточная пропускная способность — это свойство вашего egress, поэтому смена нашего адреса входа ничего не даёт — вам нужны большая пропускная способность, меньшие payload'ы или меньшая concurrency. Класс с сигналом завершения проявлялся одновременно на нескольких точках входа внутри одного окна и одновременно же восстанавливался, так что смена доменов тоже не помогает его обойти.

    Единственный адрес, которого следует избегать, — CDN-узел: `api-cf.apiyi.com` проходит через Cloudflare и возвращает `524` примерно через 100 секунд, что непригодно для долгих image-запросов.
  </Accordion>
</AccordionGroup>

## Три легко упускаемых клиентских причины

Если curl показывает, что всё в порядке, а таймаут возникает только в коде вашего приложения, ищите здесь:

1. **Таймаут означает не то, что вы думаете.** Ваши 600 секунд — это общий таймаут или только таймаут чтения? У Node `undici` есть три независимых таймаута — `headersTimeout`, `bodyTimeout` и `connect.timeout` — значения по умолчанию для которых намного ниже того, что вы задали на внешнем уровне, и изменение только внешнего таймаута не даёт эффекта.
2. **Очередь в connection pool.** Когда pool переполнен, отсчёт начинается до фактической отправки request. Это ожидание для нас полностью невидимо — в backend log нет записи о request, пока он действительно не уйдёт. Диагностика: если соответствующей записи в log нет, обычно это именно этот класс причин.
3. **Между ними есть ещё один слой.** У самостоятельно размещённого nginx значение `proxy_read_timeout` по умолчанию — 60 секунд, а load balancers, API gateways и serverless platform задают собственные верхние пределы. Проверьте таймаут на каждом переходе; самый маленький из них — ваш реальный таймаут.

## Что включать в отчёт

Если после самопроверки вам всё ещё нужна наша помощь, отправьте всё это вместе, чтобы сэкономить несколько итераций:

* **Идентификаторы запросов** (нескольких достаточно, не нужен полный набор)
* **Время по сегментам**: время до первого байта / время до последнего байта / общее время / размер body ответа в байтах
* **Когда это произошло**, с указанием часового пояса (например, `2026-08-13 15:57 (UTC+8)`)
* **Параллельные запросы** на тот момент и ваша исходящая пропускная способность
* Какую **модель** и какую **группу token** вы использовали

## Связанные документы

<CardGroup cols={2}>
  <Card title="Как избежать тайм-аутов API?" icon="timer" href="/ru/faq/timeout-configuration">
    Рекомендуемые тайм-ауты для каждого сценария и выбор endpoint
  </Card>

  <Card title="Задержка завершения запроса на генерацию изображений" icon="hourglass" href="/ru/api-capabilities/image-tail-stall">
    Обработка на стороне клиента, когда данные уже получены, но соединение не завершается
  </Card>

  <Card title="Обрывы соединения Image API" icon="unplug" href="/ru/api-capabilities/image-connection-drops">
    Диагностика downstream-обрывов связи в стиле ECONNRESET и SSL EOF
  </Card>

  <Card title="Какую параллельные запросы я могу использовать?" icon="gauge" href="/ru/faq/api-concurrency">
    Лимиты параллельных запросов для каждой модели и запросы на квоту
  </Card>

  <Card title="Лучшие практики для Image API" icon="image" href="/ru/api-capabilities/image-api-best-practices">
    Шпаргалка по тайм-аутам для каждой модели и сравнение форматов вывода
  </Card>

  <Card title="Чтение суммы тарификации в ваших логах" icon="receipt" href="/ru/faq/log-billing-explained">
    Что означает каждый столбец в логах консоли и как записывается тарификация
  </Card>
</CardGroup>

## Свяжитесь с нами

<CardGroup cols={2}>
  <Card title="Поддержка WeCom" icon="message-circle" href="https://work.weixin.qq.com/kfid/kfc9adfd5810ece25ec">
    <img src="https://mintcdn.com/apiyillc/fpi567ydpk7adDt0/images/wecom-qrcode.png?fit=max&auto=format&n=fpi567ydpk7adDt0&q=85&s=7286b96e94110e3a48798b649df1b45b" alt="QR-код поддержки WeCom" style={{maxWidth: "180px"}} width="400" height="400" data-path="images/wecom-qrcode.png" />

    Сканируйте QR-код или [свяжитесь со службой поддержки](https://work.weixin.qq.com/kfid/kfc9adfd5810ece25ec)

    Диагностика тайм-аутов изображений и медленной загрузки
  </Card>

  <Card title="Электронная почта" icon="mail">
    **Поддержка**: [support@apiyi.com](mailto:support@apiyi.com)

    **Бизнес**: [business@apiyi.com](mailto:business@apiyi.com)
  </Card>
</CardGroup>
