ИИ в вашем приложении за счёт пользователя

Добавьте кнопку «Войти через Polza». Пользователь подтверждает доступ, приложение получает его API-ключ и отправляет запросы к 400+ моделям. Polza.ai списывает деньги с баланса пользователя, и ваш счёт за API не растёт вместе с аудиторией.

  • Лимит расходов ставит пользователь
  • Один ключ на 400+ моделей
  • OpenAI-совместимый API
  • Callback на localhost для разработки
Polza.aipolza.ai/oauth/consent

Запрос доступа

Мой ботhttps://mybot.ruНе верифицировано

Организация

Личная · 1 240,00 ₽

Доступ к данным

  • User IDВсегда передаётся
  • ИмяПередать ваше имя приложению
  • EmailПередать ваш email приложению

Установить лимит расходов

Сумма (₽)

100

Период

День

Приложение получит API-ключ для организации Личная и сможет выполнять запросы к API от вашего имени.

ОтклонитьРазрешить
Схема экрана согласия: поля и значения по умолчанию — как на polza.ai.

Что такое вход через Polza

Обычно приложение с нейросетью ходит в API со своим ключом. Каждый запрос пользователя оплачивает автор. Тысяча пользователей — тысяча чужих диалогов на вашем счёте.

Со входом через Polza у каждого пользователя свой API-ключ. Polza.ai выпускает его после согласия пользователя и привязывает к балансу организации, которую он выбрал. Приложение хранит ключ и отправляет с ним запросы, как с обычным ключом Polza.ai.

Технически это OAuth 2.0 с PKCE: обмен кода на ключ защищён одноразовым секретом, который знает только ваше приложение.

Для каких проектов

Подходит везде, где запросы к модели делает пользователь и их число заранее неизвестно.

Telegram-бот с нейросетью

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

Подписчик входит через аккаунт Polza.ai и платит за свои запросы сам.

ИИ-чат или ассистент на сайте

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

Расход ограничен лимитом и балансом каждого пользователя.

Приложение на Lovable, Cursor или Replit

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

Агент добавит вход по промпту из этой страницы.

Десктопное приложение и CLI

Программа на компьютере пользователя, которой нужен доступ к моделям. Просить вставить ключ вручную неудобно.

Callback принимает localhost и 127.0.0.1.

Плагин, расширение, open source

Код открыт, зашить в него свой ключ нельзя. Пользователю приходится заводить ключ и копировать его в настройки.

Вход заменяет ручную вставку ключа.

Сервис для команды

Внутренний инструмент, которым пользуются сотрудники разных отделов. Расходы нужно разнести по подразделениям.

Пользователь выбирает организацию, с баланса которой платить.

Свой ключ или вход через Polza

Свой ключ или вход через Polza
Свой ключ в коде приложенияВход через Polza
Кто платит за запросыВы, за всех пользователейКаждый пользователь со своего баланса
Рост аудиторииСчёт за API растёт вместе с нейВаш счёт за API не меняется
Лимит расходовСтавите сами, общий на всехПользователь ставит свой: на день, неделю, месяц или разовый
Если ключ утёкПод угрозой весь ваш балансЗатронут один пользователь: ключ ограничен его лимитом и балансом
Что хранит приложениеОдин ключ на сервереКлюч каждого пользователя
Доступ к моделям400+ моделей по одному ключу400+ моделей по ключу пользователя

Как подключить нейросеть к сайту, боту или приложению

Ниже — подключение входа через Polza по OAuth PKCE: пять шагов и готовый код под три типа проектов. После входа приложение получает API-ключ пользователя и отправляет запросы к GPT, Claude, DeepSeek, Gemini и другим моделям из каталога. Регистрировать приложение в Polza.ai заранее не нужно: в запросе авторизации нет client_id, приложение называет себя параметром app_name.

Что понадобится

Адрес для callback

Страница или эндпоинт на HTTPS, куда Polza.ai вернёт пользователя. Для разработки подойдут localhost и 127.0.0.1 без HTTPS.

Место для ключей

База или сессия на сервере. Ключ каждого пользователя хранится у вас и не уходит в браузер.

OpenAI SDK

Любой OpenAI-совместимый клиент: openai для Node.js и Python, LangChain, Vercel AI SDK. Адрес API — https://polza.ai/api/v1.

Пять шагов OAuth PKCE

  1. Шаг 1

    Сгенерируйте пару PKCE

    Случайная строка code_verifier длиной 43–128 символов и её SHA-256 хеш code_challenge в Base64url. Verifier сохраните у себя, в URL его не передают.

    TypeScript · шаг 1
    import { randomBytes, createHash } from 'crypto';
    
    const codeVerifier = randomBytes(32).toString('base64url');
    const codeChallenge = createHash('sha256')
      .update(codeVerifier).digest('base64url');
  2. Шаг 2

    Отправьте пользователя на экран согласия

    Перенаправьте на https://polza.ai/api/auth/authorize. Название из app_name пользователь увидит на экране. state — до 256 символов.

    TypeScript · шаг 2
    const params = new URLSearchParams({
      response_type: 'code',
      callback_url: 'https://mybot.ru/callback',
      code_challenge: codeChallenge,
      code_challenge_method: 'S256',
      state: csrfToken,
      app_name: 'Мой бот',
    });
    location.href = `https://polza.ai/api/auth/authorize?${params}`;
  3. Шаг 3

    Примите callback

    После согласия Polza.ai вернёт пользователя на ваш callback_url с параметрами code и state. Если он отказался, придёт error=access_denied.

    TypeScript · шаг 3
    // страница https://mybot.ru/callback
    const url = new URL(location.href);
    const code = url.searchParams.get('code');
    const state = url.searchParams.get('state');
    const error = url.searchParams.get('error');
    
    if (state !== csrfToken) throw new Error('CSRF');
    if (error === 'access_denied') showLoginAgain();
    // иначе — шаг 4, обмен code на ключ
  4. Шаг 4

    Обменяйте код на ключ

    POST на /api/auth/token с кодом и verifier. Код живёт 5 минут и срабатывает один раз.

    TypeScript · шаг 4
    const res = await fetch('https://polza.ai/api/auth/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        grant_type: 'authorization_code',
        code, code_verifier: codeVerifier,
        callback_url: 'https://mybot.ru/callback',
      }),
    });
    if (!res.ok) throw new Error('Обмен кода не удался');
    const { key, user_id } = await res.json();
    // key = "pza_…", user_id = "usr_…"
  5. Шаг 5

    Отправляйте запросы с ключом пользователя

    Ключ работает как обычный API-ключ Polza.ai. Подойдёт любой OpenAI SDK, меняется только адрес API.

    TypeScript · шаг 5
    import OpenAI from 'openai';
    
    const ai = new OpenAI({
      baseURL: 'https://polza.ai/api/v1',
      apiKey: key, // ключ этого пользователя
    });
    await ai.chat.completions.create({
      model: 'openai/gpt-5.4-mini',
      messages: [{ role: 'user', content: 'Привет!' }],
    });

Те же шаги на Python и cURL — в документации.

Где хранить ключ и куда вести callback

Где хранить ключ и куда вести callback
ПроектГде хранить ключcallback_url
Сайт с ИИ-чатомСессия или таблица пользователей на сервереhttps://ваш-сайт/auth/polza/callback
Telegram-ботБаза, ключ по Telegram ID пользователяhttps://ваш-сервер/callback
Приложение на Lovable, Cursor, ReplitСерверная часть проектаhttps://ваш-домен/auth/polza/callback
Десктоп и CLIФайл настроек или хранилище ключей ОС на компьютере пользователяhttp://localhost:порт/callback

Как добавить ИИ-чат на сайт

Кнопка «Войти через Polza» ведёт на ваш сервер, сервер отправляет человека на экран согласия и принимает код. Ключ сохраняется в сессии. Виджет чата шлёт сообщения на ваш эндпоинт, а эндпоинт ходит в модель с ключом этого посетителя.

Пример на Node.js и Express — три маршрута. Если не хватает лимита расходов или баланса, Polza.ai вернёт 402, и сайт покажет человеку понятное сообщение. Нужны пакеты express, express-session и openai.

Node.js · server.js
import express from 'express';
import session from 'express-session';
import { randomBytes, createHash } from 'crypto';
import OpenAI from 'openai';

const app = express();
app.use(express.json());
// в проде — хранилище сессий в базе, не в памяти
app.use(session({ secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false }));

const CALLBACK = 'https://mysite.ru/auth/polza/callback';

// 1–2. Кнопка «Войти через Polza» ведёт сюда
app.get('/auth/polza', (req, res) => {
  const verifier = randomBytes(32).toString('base64url');
  const challenge = createHash('sha256').update(verifier).digest('base64url');
  const state = randomBytes(16).toString('hex');
  req.session.pkce = { verifier, state };
  const params = new URLSearchParams({
    response_type: 'code', callback_url: CALLBACK,
    code_challenge: challenge, code_challenge_method: 'S256',
    state, app_name: 'Мой сайт',
  });
  res.redirect(`https://polza.ai/api/auth/authorize?${params}`);
});

// 3–4. Polza возвращает пользователя с кодом, меняем код на ключ
app.get('/auth/polza/callback', async (req, res) => {
  const { code, state, error } = req.query;
  if (error || state !== req.session.pkce?.state) return res.redirect('/');
  const r = await fetch('https://polza.ai/api/auth/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      grant_type: 'authorization_code', code,
      code_verifier: req.session.pkce.verifier, callback_url: CALLBACK,
    }),
  });
  if (!r.ok) return res.redirect('/');
  const { key } = await r.json();
  req.session.polzaKey = key; // ключ остаётся на сервере
  res.redirect('/chat');
});

// 5. Чат на сайте шлёт сообщения сюда, сервер идёт в модель с ключом пользователя
app.post('/api/chat', async (req, res) => {
  if (!req.session.polzaKey) return res.status(401).end();
  const ai = new OpenAI({ baseURL: 'https://polza.ai/api/v1', apiKey: req.session.polzaKey });
  try {
    const r = await ai.chat.completions.create({ model: 'openai/gpt-5.4-mini', messages: req.body.messages });
    res.json(r.choices[0].message);
  } catch (e) {
    if (e.status === 402) return res.status(402).json({ error: 'Не хватает лимита расходов или баланса' });
    res.status(500).json({ error: 'Модель не ответила' });
  }
});

app.listen(3000);

Как добавить нейросеть в Telegram-бота

Бот присылает ссылку на вход в ответ на /start. В параметре state бот запоминает, какому пользователю Telegram принадлежит вход. Callback принимает тот же процесс через FastAPI, меняет код на ключ и сохраняет его по Telegram ID. После этого каждое сообщение пользователя уходит в модель с его ключом.

Пример на Python: aiogram 3, FastAPI и openai в одном файле. Callback должен быть доступен из интернета по HTTPS. Пакеты: aiogram, fastapi, uvicorn, httpx, openai.

Python · bot.py
# aiogram 3 + FastAPI в одном процессе
import asyncio, base64, hashlib, os, secrets
from urllib.parse import urlencode

import httpx, uvicorn
from aiogram import Bot, Dispatcher, F
from aiogram.filters import CommandStart
from aiogram.types import Message
from fastapi import FastAPI
from fastapi.responses import PlainTextResponse
from openai import AsyncOpenAI, APIStatusError

CALLBACK = "https://mybot.ru/callback"
bot, dp, api = Bot(os.environ["BOT_TOKEN"]), Dispatcher(), FastAPI()
pending, keys = {}, {}  # в проде — база данных


@dp.message(CommandStart())
async def start(m: Message):
    verifier = secrets.token_urlsafe(32)
    digest = hashlib.sha256(verifier.encode()).digest()
    challenge = base64.urlsafe_b64encode(digest).rstrip(b"=").decode()
    state = secrets.token_urlsafe(16)
    pending[state] = (m.from_user.id, verifier)
    url = "https://polza.ai/api/auth/authorize?" + urlencode({
        "response_type": "code", "callback_url": CALLBACK,
        "code_challenge": challenge, "code_challenge_method": "S256",
        "state": state, "app_name": "Мой бот",
    })
    await m.answer(f"Войдите через Polza, и бот будет отвечать за счёт вашего баланса:\n{url}")


@api.get("/callback", response_class=PlainTextResponse)
async def callback(code: str = "", state: str = "", error: str = ""):
    user_id, verifier = pending.pop(state, (None, None))
    if error or user_id is None:
        return "Вход отменён"
    async with httpx.AsyncClient() as c:
        r = await c.post("https://polza.ai/api/auth/token", json={
            "grant_type": "authorization_code", "code": code,
            "code_verifier": verifier, "callback_url": CALLBACK,
        })
    if not r.is_success:
        return "Вход не удался, нажмите /start ещё раз"
    keys[user_id] = r.json()["key"]
    await bot.send_message(user_id, "Готово. Задайте вопрос.")
    return "Готово, вернитесь в Telegram"


@dp.message(F.text)
async def ask(m: Message):
    key = keys.get(m.from_user.id)
    if not key:
        return await m.answer("Сначала нажмите /start")
    ai = AsyncOpenAI(base_url="https://polza.ai/api/v1", api_key=key)
    try:
        r = await ai.chat.completions.create(
            model="openai/gpt-5.4-mini",
            messages=[{"role": "user", "content": m.text}],
        )
        await m.answer(r.choices[0].message.content)
    except APIStatusError as e:
        await m.answer("Не хватает лимита расходов или баланса" if e.status_code == 402 else "Модель не ответила")


async def main():
    server = uvicorn.Server(uvicorn.Config(api, host="0.0.0.0", port=8000))
    await asyncio.gather(server.serve(), dp.start_polling(bot))

asyncio.run(main())

Как подключить нейросеть к приложению на Lovable или Cursor

Если код пишет агент, отдайте ему промпт из раздела ниже. Агент прочитает .md-версию документации и соберёт те же маршруты, что в примере для сайта. Проверьте за ним два места: ключ хранится на сервере, а state сверяется в callback.

Промпт для агента

Вход в десктопном приложении и CLI

Программа поднимает локальный сервер на свободном порту, открывает ссылку на вход в браузере и ждёт один запрос с кодом. HTTPS для localhost и 127.0.0.1 не нужен. Ключ после обмена сохраните на компьютере пользователя.

Python · локальный callback
import http.server, urllib.parse, webbrowser

# authorize_url собран как в шаге 2, с callback_url=http://localhost:8765/callback

class Callback(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        u = urllib.parse.urlparse(self.path)
        if u.path != "/callback":  # favicon и прочие запросы браузера
            self.send_response(404)
            self.end_headers()
            return
        q = urllib.parse.parse_qs(u.query)
        self.server.code = q.get("code", [None])[0]
        self.server.state = q.get("state", [None])[0]
        self.server.done = True
        self.send_response(200)
        self.end_headers()
        done = "Вход выполнен" if self.server.code else "Вход отменён"
        self.wfile.write(f"{done}, вкладку можно закрыть".encode())

srv = http.server.HTTPServer(("127.0.0.1", 8765), Callback)
webbrowser.open(authorize_url)
srv.done = False
while not srv.done:  # ждём запрос на /callback
    srv.handle_request()
if srv.state != state:  # state из шага 2
    raise SystemExit("state не совпал, вход прерван")
if srv.code is None:
    raise SystemExit("Пользователь отклонил доступ")
# обменяйте srv.code на ключ, как в шаге 4

Код целиком — в документации

Примеры на TypeScript, Python и cURL, параметры запросов и ответы сервера.

Открыть документацию

Что видит пользователь

Экран согласия открывается на polza.ai. Пользователь видит название приложения из app_name и домен из callback_url. Приложение, которое Polza.ai не проверяла, помечено «Не верифицировано». Дальше пользователь решает три вещи.

С какого баланса платить

Если у пользователя несколько организаций, он выбирает одну. Polza.ai выпускает ключ в ней, и запросы списываются с её баланса.

Какие данные передать

ID передаётся всегда. Имя на экране уже отмечено, email — нет; пользователь может снять или поставить любую из двух отметок. Отмеченное вы получите через GET /api/auth/userinfo.

Сколько можно потратить

Лимит в рублях на день, неделю, месяц или разовый, без сброса. По умолчанию экран предлагает 100 ₽ в день; лимит можно поменять или снять. Когда лимит кончится, запросы с ключом вернут ошибку 402.

Путь пользователя

  1. 1

    Нажимает «Войти через Polza»

    Кнопка в вашем приложении, рядом с обычным входом.

  2. 2

    Входит в аккаунт на polza.ai

    Без аккаунта Polza.ai сначала откроет вход и регистрацию, затем вернёт человека к запросу доступа.

  3. 3

    Подтверждает доступ

    Выбирает организацию, данные и лимит расходов на экране согласия.

  4. 4

    Возвращается в приложение

    Ваш callback получает код, сервер обменивает его на ключ.

  5. 5

    Пользуется

    Запросы списываются с баланса его организации в Polza.ai. Когда лимит или баланс кончится, приложение получит 402.

Данные пользователя

Данные пользователя
ScopeЧто вы получитеОбязательный
user:idID пользователя вида usr_123Да, включён всегда
user:nameИмяНет, отмечено по умолчанию, пользователь может снять
user:emailEmailНет, не отмечено по умолчанию, пользователь может поставить

Лимиты расходов

Лимиты расходов
ПериодКак работает
dayЛимит на день
weekЛимит на неделю
monthЛимит на месяц
totalРазовый лимит, без сброса

Что получаете вы

API-ключ пользователя

Строка вида pza_…. Работает с https://polza.ai/api/v1 и любым OpenAI-совместимым SDK.

ID и профиль

user_id приходит вместе с ключом. Имя и email — по GET /api/auth/userinfo, если пользователь их разрешил.

Весь каталог моделей

Ключ открывает те же 400+ моделей, что и обычный: текст, код, изображения, видео, речь.

Повторный вход без дублей

Если пользователь снова авторизует приложение в той же организации, ключ ротируется: новый секрет, новые scopes и лимиты. Старый секрет перестаёт работать.

Понятный сигнал о деньгах

Ответ 402 значит, что у пользователя кончился лимит расходов или баланс. Покажите ему ссылку на пополнение или предложите поднять лимит.

Ноль на вашем счёте

Запросы оплачивает пользователь. Подключение входа в Polza.ai бесплатное, комиссии с разработчика нет.

Промпт для Cursor, Lovable и Claude Code

Если приложение пишет агент, код вручную не нужен. Скопируйте промпт и подставьте свой домен и название.

Агент прочитает .md-версию документации по ссылке. В ней те же шаги, что на этой странице, без вёрстки.

  • Cursor
  • Lovable
  • Claude Code
  • Replit
  • Bolt
  • Codex

Как подключить сам Claude Code к Polza — на странице Claude Code.

Промпт для агента
Добавь в приложение вход через Polza.ai по OAuth PKCE.
Документация: https://polza.ai/docs/gaidy/oauth-pkce.md

1. Кнопка «Войти через Polza» на странице входа.
2. callback_url: https://<мой-домен>/auth/polza/callback
   (для локальной разработки — http://localhost:<порт>/...)
3. app_name: <название приложения>
4. Полученный ключ pza_… сохрани у пользователя на сервере,
   в браузер его не отдавай.
5. Все запросы к модели отправляй через OpenAI SDK
   с baseURL https://polza.ai/api/v1 и ключом пользователя.
6. На ответ 402 покажи: «Не хватает лимита расходов или баланса».

Безопасность

Эти правила Polza.ai проверяет на своей стороне.

Только S256

Метод plain не поддерживается: challenge всегда SHA-256 от verifier.

HTTPS для callback

Адрес возврата должен быть на HTTPS. Исключение — localhost и 127.0.0.1 для разработки.

Код живёт 5 минут

Код авторизации одноразовый. Повторный обмен вернёт ошибку.

5 обменов в минуту

На /api/auth/token — не больше 5 обменов в минуту с одного IP-адреса. Шестой запрос за минуту получит 429.

Проверка verifier

Сервер сверяет code_verifier с защитой от timing-атак.

Параметр state

Генерируйте случайный state перед входом и сверяйте его в callback. Так вы закроете CSRF.

Если вход не работает

Ошибки, которые возвращают authorize, token и запросы с ключом.

Пользователь отклонил доступ

На callback придёт error=access_denied. Покажите кнопку входа ещё раз, ключа в этом случае нет.

400: невалидный код или код уже использован

Код одноразовый и живёт 5 минут. Начните вход заново. Частая причина — повторная отправка формы или перезагрузка callback-страницы.

400: callback_url не совпадает

callback_url при обмене должен буквально совпадать с тем, что был в ссылке авторизации, включая слеш на конце.

400: невалидный code_verifier

Verifier не соответствует challenge. Проверьте, что сохраняете verifier между шагами 1 и 4 для того же пользователя.

400 на authorize: невалидный callback_url или code_challenge

Callback должен быть на HTTPS или localhost. Challenge — Base64url длиной 43–128 символов, без знаков = на конце.

402 при запросе к модели

Пользователь исчерпал лимит, который поставил на экране согласия, или на балансе организации не хватает денег. Лимит он поднимет в кабинете или повторным входом, баланс пополнит в кабинете.

429 при обмене кода

Больше 5 обменов в минуту с одного IP-адреса. Обычно это цикл повторов в коде callback. Код живёт 5 минут — обмен можно повторить через минуту.

Нужны все коды ответов?

Таблицы ошибок authorize и token — в документации.

Открыть документацию

Вопросы и ответы

Сколько платит разработчик?

Нисколько. Подключение входа через Polza бесплатное, комиссии с разработчика Polza.ai не берёт. Запросы оплачивает пользователь со своего баланса.

Получает ли разработчик долю от расходов пользователей?

Сейчас нет. Партнёрскую программу для приложений со входом через Polza.ai планируем, но условий и сроков пока нет.

Что если у пользователя нет аккаунта Polza.ai?

Экран согласия сначала откроет вход и регистрацию Polza.ai, после входа человек вернётся к запросу доступа. Пополнить баланс прямо с экрана согласия нельзя: это делается в кабинете, а пока баланс пуст, запросы с ключом возвращают 402.

Как пользователь отзывает доступ?

В кабинете Polza.ai, в разделе «API-ключи»: ключ приложения помечен OAuth и называется «OAuth: <название приложения>». Там пользователь меняет лимит расходов, деактивирует или удаляет ключ, после чего запросы с ним перестают проходить.

Нужно ли регистрировать приложение?

Нет. В запросе авторизации нет client_id: приложение передаёт название в параметре app_name, и пользователь видит его на экране согласия вместе с доменом callback_url. Пока Polza.ai не проверила приложение, рядом с названием стоит отметка «Не верифицировано».

Работает ли вход в десктопном приложении или CLI?

Да. Polza.ai принимает callback на localhost или 127.0.0.1 без HTTPS: приложение поднимает локальный сервер и принимает код.

Какие модели доступны по ключу пользователя?

Те же, что по обычному ключу Polza.ai: весь каталог из 400+ моделей. Модель вы выбираете в запросе.

Что будет, если пользователь войдёт второй раз?

Polza.ai ротирует ключ в той же организации: генерирует новый секрет, обновляет scopes и лимиты. Сохраните новый ключ, старый перестанет работать.

Добавьте вход через Polza

Пять шагов в коде или один промпт для агента. Пользователи сами оплачивают свои запросы в Polza.ai, со своего баланса.

Остались вопросы? Документация по OAuth PKCE, поддержка в Telegram или support@polza.ai

Страницу проверила редакция Polza.AI, обновлено . Модели и цены — в каталоге.

Сайт использует cookie.