ПРАКТИЧЕСКИЙ РАЗБОР · 6 минут

Почему OpenRouter возвращает ошибку 403 и что проверить

Что означает HTTP 403 в OpenRouter, как проверить ограничения ключа, модели и guardrails и найти причину отказа API

Вы подключили OpenRouter к приложению. API-ключ создан, запросы отправляются с сервера, модель выбрана. Но вместо ответа нейросети появляется 403 Forbidden. Иногда это происходит сразу после настройки, иногда после периода нормальной работы. Код 403 означает, что запрос не был разрешён. При этом причина не обязательно связана с неправильным API-ключом. OpenRouter может ограничить доступ к модели, провайдеру или конкретному запросу.

Разберём порядок проверки, который помогает найти причину без случайной замены всех настроек.

Чем 403 отличается от других ошибок

При обращении к API полезно сначала посмотреть на HTTP-статус. Он подсказывает, в какой части подключения искать проблему.

401 Unauthorized обычно связан с отсутствующей или недействительной авторизацией. Проверьте, передан ли ключ в заголовке Authorization и не был ли он отозван.

402 Payment Required указывает на ограничение, связанное с оплатой доступа. 429 Too Many Requests сообщает о превышении лимита запросов. При временных сбоях серверов встречаются ошибки группы 5xx.

403 Forbidden означает отказ в доступе. Например, запрос может нарушать правила guardrails, ограничения выбранной модели или политику доступа к провайдерам.

Поэтому менять ключ при каждом 403 не нужно. Сначала выясните, что именно запрещено.

Посмотрите сообщение API

Допустим, приложение использует Python и отправляет сообщения в OpenRouter. Чтобы увидеть причину отказа, на время диагностики можно вывести HTTP-статус и текст сообщения об ошибке.

import os
import requests

response = requests.post(
    "https://openrouter.ai/api/v1/chat/completions",
    headers={
        "Authorization": f"Bearer {os.environ['OPENROUTER_API_KEY']}",
    },
    json={
        "model": os.environ["OPENROUTER_MODEL"],
        "messages": [
            {
                "role": "user",
                "content": "Привет! Ответь одним предложением.",
            }
        ],
    },
    timeout=30,
)

print("HTTP:", response.status_code)

if not response.ok:
    try:
        error = response.json().get("error", {})
        print("Причина:", error.get("message", "Не указана"))
    except ValueError:
        print("API вернул ответ не в формате JSON")
else:
    print("Запрос выполнен")

В переменных окружения должны находиться действующий API-ключ и идентификатор модели. Для проверки используйте короткий нейтральный текст, чтобы отделить проблемы доступа от особенностей пользовательского запроса.

Во время локальной диагностики сообщение об ошибке можно изучить в терминале. В production его не следует без проверки отправлять пользователю или записывать в общий журнал. Сообщение API может содержать сведения о запросе.

Проверьте ограничения модели и ключа

Первый сценарий связан с доступом к выбранной модели. В настройках OpenRouter могут действовать списки разрешённых моделей и инфраструктурных провайдеров. Если нужный вариант не входит в разрешённый список, запрос будет отклонён.

Проверьте идентификатор OPENROUTER_MODEL, доступность модели в каталоге и ограничения, назначенные ключу. Если приложение использует организационную учётную запись, ограничения могут применяться на нескольких уровнях.

У OpenRouter есть механизм guardrails. Он позволяет задавать лимиты расходов, списки доступных моделей и провайдеров, а также правила обработки содержимого запросов. Достижение установленного лимита или запрет выбранной модели могут приводить к 403.

Отдельно проверьте настройки приватности и маршрутизации. Если разрешены только определённые провайдеры, а подходящего для выбранной модели среди них нет, запрос может не пройти.

Почему один текст проходит, а другой блокируется

Предположим, приложение успешно отправляет нейтральное сообщение, но получает 403 на другом запросе при тех же ключе и модели. Одна из возможных причин связана с проверкой содержимого. OpenRouter поддерживает правила guardrails, которые могут блокировать запросы с определёнными данными или шаблонами текста. Например, организация может запретить передачу персональных сведений внешним моделям. Если запрос соответствует настроенному правилу блокировки, OpenRouter возвращает 403 до обращения к модели. В такой ситуации смена API-ключа не решает задачу. Нужно изучить действующие правила и понять, какие данные приложение пытается передать. Защитные ограничения не стоит отключать только ради прохождения одного запроса.

Другой случай возникает, когда приложение использует модель, поддерживающую не все форматы данных. Тогда необходимо проверить параметры конкретного API и сообщение об ошибке. Не каждое несоответствие формата приводит именно к 403, поэтому ориентируйтесь на фактический ответ сервиса.

Порядок проверки без лишних изменений

Начните с короткого запроса и сохраните его HTTP-статус. Затем сравните сообщение об ошибке с текущими настройками OpenRouter. Если проблема возникает на всех запросах, проверьте действительность ключа, ограничения расходов, доступ к модели и правила организации. Если отказ зависит от конкретного текста, посмотрите настройки фильтрации содержимого. Если одна модель работает, а другая нет, сравните разрешения и доступность их провайдеров.

После каждого изменения повторяйте один и тот же тест. Так будет видно, какое действие повлияло на результат. Не меняйте одновременно ключ, модель, настройки приватности и текст запроса, иначе причину трудно установить. В документации OpenRouter есть отдельное описание guardrails, включая причины блокировок и структуру ответов 403.

Что должен видеть пользователь приложения

Пользователю AI-чата не требуется знать внутренние правила OpenRouter. Если запрос заблокирован, интерфейс должен сообщить, что ответ сейчас не получен. При этом сервер может сохранить безопасные диагностические сведения, например код ошибки, выбранную модель и время обращения. Автоматически повторять каждый 403 бессмысленно. Пока действует запрещающее правило, повтор того же запроса не изменит результат. Переключение модели допустимо только там, где это разрешено настройками и соответствует задаче приложения.

В моей статье на Habr об агрегаторе LLM подробнее разобрана работа с несколькими моделями и сбоями провайдеров. А получение и хранение ключа показано в статье «Где взять API-ключ OpenRouter».

От диагностики к устойчивому AI-сервису

В демонстрационном AI-Chat можно посмотреть приложение, где интерфейс взаимодействует с языковыми моделями через серверный API.

Курс «AI на Django и Next II» связывает подключение моделей, обработку серверных запросов и разработку приложения на Django и Next.js.

При ошибке 403 начните с ответа API, а затем проверьте ограничения ключа, модели и содержимого запроса. Обычно это быстрее, чем заново настраивать подключение, не зная причины отказа.