Автентифікація

Один заголовок у кожному запиті, крім індексу з описом API.

Authorization: Bearer <your api key>

Токени створюються на сторінці профілю - до десяти на обліковий запис, кожен можна відкликати окремо, тож токен, що потрапив до сторонніх, можна видалити, не зачіпаючи інших. Потрібен платний тариф: без нього всі ендпоінти, крім / і /v1/account, відповідають 403 plan_required.

Застосунок також може отримати токен для вас через OAuth 2.1: ви входите, бачите, що він запитує, і натискаєте «Дозволити». Його токен передається в тому самому заголовку й працює так само.

Чому не ?key=

Ключ у рядку запиту потрапляє туди, куди ви його не клали: у журнали доступу вебсервера, історію браузера, журнали проксі та заголовок Referer усього, на що посилається відповідь. Тому API його не приймає й відповідає 401 missing_key з поясненням.

Старі URL з ?export= на основному сайті досі приймають ?key=, бо від цього залежать скрипти, написані багато років тому, і прибрати його означало б їх зламати. Це єдине місце, де він залишився, - див. старі URL експорту.

Як перевірити, що ключ працює

/v1/account - найдешевший виклик: він не витрачає денного ліміту й працює навіть на обліковому записі без тарифу, тож відповідає і на запитання «чи дійсний цей ключ», і на «що мені доступно».

curl -H "Authorization: Bearer $KEY" https://api.publicwww.com/v1/account
{
  "plan": "enterprise",
  "plan_until": 1819461840,
  "full_access": true,
  "quota": {
    "searches": { "limit": 300, "used": 12, "resets_at": 1787961600 },
    "snippets": { "limit": 100, "used": 3,  "resets_at": 1787961600 }
  },
  "limits": {
    "disclosed_positions": 4294967295,
    "max_per_page": 1000000,
    "max_per_page_snippets": 10000
  }
}

Що може піти не так

СтатусКодЗначення
401missing_keyНемає заголовка Authorization: Bearer. Ключ у рядку запиту не рахується.
401invalid_keyКлюч не належить жодному обліковому запису. Перевірте, чи не потрапив зайвий перенос рядка або лапка.
403plan_requiredІз ключем усе гаразд, але в облікового запису немає платного тарифу.

Відповідь 401 також містить заголовок WWW-Authenticate: Bearer, тож HTTP-клієнти, які обробляють автентифікацію універсально, поводяться правильно.

OAuth 2.1 для застосунків

Застосунок, що працює від імені інших людей, - асистент, інтеграція, хмарний сервіс, - не повинен просити кожного з них скопіювати токен. Натомість він відправляє їх до PublicWWW: вони входять, схвалюють застосунок, і той отримує власний токен. Цей токен передається як Authorization: Bearer, як і будь-який інший, і відкриває все API та MCP-сервер за адресою https://api.publicwww.com/mcp у межах тарифу, денного ліміту й обмеження частоти облікового запису.

ЩоДе
Метадані сервера авторизації (RFC 8414)https://publicwww.com/.well-known/oauth-authorization-server
Метадані захищеного ресурсу (RFC 9728)https://api.publicwww.com/.well-known/oauth-protected-resource
Ендпоінт авторизаціїhttps://publicwww.com/oauth/authorize
Ендпоінт токенівhttps://publicwww.com/oauth/token
Ендпоінт відкликання (RFC 7009)https://publicwww.com/oauth/revoke

Ідентифікація застосунку

Реєстрації клієнтів немає. client_id - це https-URL невеликого JSON-документа, який публікує застосунок, - документа метаданих клієнта. PublicWWW читає його щоразу, коли хтось підключається, тож назва й адреси повернення завжди актуальні, а людина, яка дає дозвіл, бачить, який хост їх опублікував.

{
  "client_id": "https://app.example.com/oauth/client.json",
  "client_name": "Example App",
  "redirect_uris": ["https://app.example.com/oauth/callback"],
  "grant_types": ["authorization_code"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none"
}
  • client_id усередині документа має точно збігатися з URL, за яким документ віддається. Документ завантажується через https, з URL, що містить шлях, без переходу за перенаправленнями; він має відповісти протягом 5 секунд і бути меншим за 64 КБ.
  • redirect_uris - це https-адреси або http на 127.0.0.1, localhost чи [::1] для застосунку, що працює на власному комп’ютері користувача, - там підходить будь-який порт. Власні схеми на кшталт myapp:// не приймаються.
  • Кожен застосунок - публічний клієнт: запит токена не містить секрету, хоч би який token_endpoint_auth_method був указаний у документі. Код авторизації натомість захищає PKCE.

Процес

Код авторизації з PKCE; єдиний метод - S256. Відправте людину на ендпоінт авторизації:

https://publicwww.com/oauth/authorize
    ?response_type=code
    &client_id=https%3A%2F%2Fapp.example.com%2Foauth%2Fclient.json
    &redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fcallback
    &code_challenge=<BASE64URL(SHA-256(code_verifier))>
    &code_challenge_method=S256
    &state=<random>

Якщо людина ще не ввійшла, вона входить за одноразовим кодом, надісланим на електронну пошту, бачить назву застосунку, хост його документа й адресу, куди повернеться, і натискає «Дозволити» або «Скасувати». На redirect_uri повертаються code, ваш state і iss=https://publicwww.com (RFC 9207). Код дійсний десять хвилин і спрацьовує один раз. Обміняйте його:

curl https://publicwww.com/oauth/token \
     -d grant_type=authorization_code \
     -d code="$CODE" \
     -d code_verifier="$VERIFIER" \
     -d client_id=https://app.example.com/oauth/client.json \
     -d redirect_uri=https://app.example.com/oauth/callback
{ "access_token": "<token>", "token_type": "Bearer", "scope": "mcp" }

scope можна не вказувати: область доступу одна, mcp, і вона охоплює все API. resource (RFC 8707) теж можна не вказувати; якщо його передано, це https://api.publicwww.com/mcp або https://api.publicwww.com.

Скільки живе токен

Доки його не відкличуть: строку дії немає, токена оновлення теж. Інтеграція, яка працює сьогодні, працюватиме й завтра, без жодного втручання. Токен відкликається лише навмисно: людина відключає застосунок на своїй сторінці профілю, застосунок сам відкликає токен або обліковий запис видаляють.

curl https://publicwww.com/oauth/revoke \
     -d token="$TOKEN" \
     -d client_id=https://app.example.com/oauth/client.json

Ендпоінт відкликання завжди відповідає 200 - незалежно від того, чи існував токен.

Помилки OAuth

ДеКодЗначення
Авторизаціясторінка помилкиНе вдалося прочитати документ client_id, або в ньому немає redirect_uri. Людину не повертають назад: за неперевіреною адресою перехід не виконується ніколи.
Авторизаціяinvalid_requestНемає code_challenge, або метод інший, ніж S256.
Авторизаціяunsupported_response_typeБудь-що, крім response_type=code.
Авторизація, токенinvalid_targetresource, що не є цим API.
Авторизаціяaccess_deniedЛюдина натиснула «Скасувати».
Токенinvalid_grantКод невідомий, уже використаний, прострочений або виданий іншому client_id; або не збігається code_verifier чи redirect_uri.
Токенunsupported_grant_typeБудь-що, крім authorization_code.

Помилки авторизації, крім сторінки помилки, повертаються на redirect_uri як error, error_description, state та iss; помилки токена - це 400 з тими самими двома полями в JSON.

Далі Надсилання запитів