Коды ошибок
На неудачный вызов API отвечает HTTP-статусом и JSON-объектом ошибки, в котором поле code указывает, что пошло не так. Ниже — все 25 кодов, которые может вернуть API. В рамках v1 могут появиться новые коды: незнакомый код обрабатывайте по его HTTP-статусу.
Объект ошибки
Тело любой ошибки имеет такую структуру; поля code и message присутствуют всегда.
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
| error | object | да | |
| error.code | string | да | Machine-readable error code. Each response lists the codes it can carry; new codes may be added within v1, so treat an unknown code by its HTTP status. |
| error.message | string | да | Human-readable explanation (English). |
| error.requestId | string | нет | The X-Request-Id of this request — quote it when reporting a problem. Sent since v1.1. |
| error.detail | object | нет | Structured context for the error, such as the offending field; omitted when there is none.
|
| error.docs | string | нет | Where the error codes are explained. Sent since v1.1.
|
Настоящий ответ с ошибкой — в запросе пропущено обязательное поле:
curl -sS 'https://ecdsa.com/api/v1/jwt/decode' \
-H 'content-type: application/json' \
-d '{}'{
"error": {
"code": "missing_field",
"message": "Field \"token\" is required and must be a non-empty string.",
"requestId": "docs-example",
"docs": "https://ecdsa.com/developers#errors"
}
}Все коды
| Код | HTTP | Значение | Когда возникает | Что делать | SDK |
|---|---|---|---|---|---|
| invalid_json | 400 | The body is not valid JSON or not a JSON object; or the input nests arrays and objects more than 64 levels deep (JSON documents inside string fields count too), or is too complex to inspect for private keys. | Типичные причины: тело в кодировке формы (form-encoded) или обычный текст вместо JSON, массив или строка JSON на верхнем уровне либо сгенерированные входные данные с очень глубокой вложенностью. Заголовок content-type значения не имеет, важно само тело. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Отправляйте в теле один JSON-объект. Если входные данные генерируются программно, проверьте их вложенность. | Не повторяется |
| missing_field | 400 | A required field is absent or empty. | Обязательное для операции поле отсутствует, равно null, пустое или не строковое — часто его имя просто написано иначе, например public_key вместо publicKey. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Добавьте поле, указанное в сообщении; обязательные поля перечислены на справочной странице операции. | Не повторяется |
| invalid_input | 400 | A field could not be parsed — the message explains exactly why. | Поле есть, но его не удаётся разобрать: ключ, подпись, токен или сертификат в кодировке или формате, которые операция не распознаёт. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, Create a webhook endpoint | Прочитайте сообщение: в нём указаны поле и причина. Проверьте кодировку (hex, base64, PEM), а для подписей — ещё и кривую. | Не повторяется |
| private_key_rejected | 400 | The request contains private-key material (a PEM PRIVATE KEY block, an OpenSSH, SSH2 or PuTTY private key, or a JWK with "d"). Never send private keys anywhere. | Туда, где нужна только открытая часть ключа, вставлен весь файл ключа: PEM в формате PKCS#8 или SEC1, закрытый ключ OpenSSH или PuTTY, JWK, в котором остался параметр «d». Такой ключ обнаруживается и внутри строки, содержащей JSON. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Отправляйте только открытые данные. Для работы с закрытым ключом используйте инструменты в браузере — они работают на вашем компьютере и ничего не отправляют. | Не повторяется |
| unsupported_algorithm | 400 | The token's algorithm is not one this operation verifies. | JWT подписан алгоритмом, который операция не проверяет: HS*, RS*, PS*, EdDSA, ES256K или none. | Этот API проверяет ES256, ES384 и ES512. Токены с другими алгоритмами проверяйте локально с помощью библиотеки для JWT — секрет HMAC никогда и никуда нельзя отправлять. | Не повторяется |
| invalid_domain | 400 | Not a public DNS hostname (IP addresses, single-label names and paths are refused). | Сегмент пути — IP-адрес, имя без точки (например, localhost) или текст, который не может быть именем хоста. Схему, порт или путь вокруг имени API предварительно отбрасывает. Операции: TLS signature-health grade for a domain | Укажите публичное имя хоста, например github.com. IP-адреса и внутренние имена отсюда сканировать нельзя. | Не повторяется |
| scan_dns_error | 400 | The domain does not resolve in public DNS. | Не удаётся разрешить имя через публичный DNS: такого домена нет (опечатка, истёкшая регистрация, имя, известное только внутреннему DNS), у имени нет записи A или AAAA либо произошёл сбой DNS. Операции: TLS signature-health grade for a domain | Проверьте написание имени и наличие у него записей A или AAAA. | Не повторяется |
| scan_private_address | 400 | The domain resolves (at least partly) to a private or reserved address. | Один из адресов имени (IPv4, IPv6 или IPv4, встроенный в IPv6) попадает в частный или зарезервированный диапазон, например во внутреннюю сеть или в петлевые адреса (loopback). Если публичные адреса смешаны с частными, имя отклоняется целиком. Операции: TLS signature-health grade for a domain | Проверяйте хост, доступный из публичного интернета: внутренние хосты отсюда сканировать нельзя. | Не повторяется |
| webhook_url_refusedс API-ключами | 400 | The webhook URL cannot receive deliveries: it is not https on port 443, its host is not a public DNS name, or the name does not resolve or resolves (at least partly) to a private or reserved address. | Создание эндпоинта с URL на http, с портом, отличным от 443, с IP-адресом или внутренним именем либо с хостом, в DNS-ответе которого есть частный или зарезервированный адрес, — даже если таков только один из нескольких адресов. Операции: Create a webhook endpoint | Используйте URL с https на стандартном порту и с публичным именем хоста. В сообщении сказано, какое правило нарушил URL, а для отклонённого адреса — какой это адрес и диапазон. | Не повторяется |
| unauthorized | 401 | The Authorization or X-API-Key header is malformed, the API key is not valid (wrong checksum, unknown, revoked or expired), or the operation needs a key. | Заголовок Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Уберите заголовок, чтобы вызывать API анонимно, или передайте полный действительный ключ. | Не повторяется |
| forbidden_scopeс API-ключами | 403 | The API key is valid but lacks a scope this operation requires; the message names it. | Ключ создан без области доступа, которая нужна операции: например, ключ только с областью api вызывает операцию проверки состояния домена, которой нужна область scan. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Вызывайте операцию с ключом, у которого есть эта область доступа. | Не повторяется |
| webhook_limit_reachedс API-ключами | 403 | The account already has as many webhook endpoints as its plan allows. | Создание эндпоинта, когда у аккаунта уже столько эндпоинтов, сколько позволяет его тариф; бесплатный тариф позволяет один. Операции: Create a webhook endpoint | Удалите эндпоинт, который больше не нужен, или, чтобы изменить описание или события существующего эндпоинта, создайте его заново с тем же URL. | Не повторяется |
| not_found | 404 | No operation exists at this path. | Путь, начинающийся с Любая операция может вернуть этот код. | Сверьте путь со справочником API; пути всех операций начинаются с /api/v1. | Не повторяется |
| webhook_not_foundс API-ключами | 404 | The API key's account has no webhook endpoint with this id. | Идентификатор эндпоинта не относится к аккаунту ключа: эндпоинт уже удалён, в идентификаторе опечатка или эндпоинт принадлежит другому аккаунту. Операции: Delete a webhook endpoint, Send a test event | Получите список эндпоинтов аккаунта запросом GET /api/v1/webhooks и возьмите идентификатор оттуда. | Не повторяется |
| method_not_allowed | 405 | The path exists but does not accept this HTTP method; see the Allow header. | POST-операция вызвана методом GET (например, её адрес открыли в адресной строке браузера) или наоборот. Любая операция может вернуть этот код. | Используйте метод из заголовка Allow: POST для операций, которые принимают тело в формате JSON, GET для остальных. | Не повторяется |
| payload_too_large | 413 | The body exceeds 100 KB. | Тело больше 100 КБ: обычно потому, что в одно поле вставили целый пакет сертификатов или файл. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Отправляйте меньше данных за один вызов: одну цепочку сертификатов, один токен. | Не повторяется |
| rate_limited | 429 | Too many requests — see Retry-After. | Слишком много запросов в текущем окне: по IP, если ключа нет, и по ключу, если он есть. Настоящие сканирования домена расходуют ещё и лимиты на хост и общий лимит. Операции: API self-description, Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Подождите столько секунд, сколько указано в Retry-After, затем повторите запрос; кешируйте ответы на своей стороне. | Повторяется до 2 раз |
| quota_exceededс API-ключами | 429 | A daily or monthly quota of the API key's account is used up. X-Quota-Reset (and Retry-After) say when it starts over; retrying earlier cannot succeed. | Вызовы с ключом израсходовали дневную или месячную квоту аккаунта (в единицах квоты) либо его дневную квоту сканирований доменов; у тестовых ключей собственные квоты, они меньше. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Не повторяйте запрос раньше времени, указанного в X-Quota-Reset: квота обновится именно тогда, не раньше. | Не повторяется |
| internal_error | 500 | Unexpected server error. | Непредвиденный сбой в API. Он записывается в лог вместе с ID запроса; тело запроса в лог никогда не попадает. Любая операция может вернуть этот код. | Если ошибка повторяется, сообщите значение requestId из тела ошибки. | Не повторяется |
| scan_unreachable | 502 | The domain refused or dropped the connection on port 443. | Имя разрешается, но установить TCP-соединение с портом 443 из интернета не удаётся: HTTPS-сервера нет, межсетевой экран отклоняет или отбрасывает соединение либо хост не работает. Операции: TLS signature-health grade for a domain | Убедитесь, что хост принимает HTTPS-соединения на порту 443 из публичного интернета. | Повторяется до 2 раз |
| scan_tls_error | 502 | The TLS handshake failed or presented no usable certificate. | Соединение с портом 443 открывается, но TLS-рукопожатие завершается оповещением или несовпадением протоколов либо сервер не присылает сертификат, понятный сканеру. Операции: TLS signature-health grade for a domain | Проверьте настройку TLS на сервере, например с помощью отчёта о состоянии подписей домена. | Повторяется до 2 раз |
| service_unavailableс API-ключами | 503 | API keys cannot be verified right now (the key store is unreachable); retry shortly. | Хранилище ключей недоступно, поэтому переданный ключ невозможно проверить. Вызов с ключом никогда не обслуживается анонимно. Операции: Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, TLS signature-health grade for a domain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Повторите запрос чуть позже — SDK так и делают. | Повторяется до 2 раз |
| webhooks_unavailableс API-ключами | 503 | Webhooks are switched off on this server: it has no signing keys configured. | На сервере не настроены ключи подписи вебхуков, поэтому он не может подписывать доставки; пока ключи не заданы, все операции с вебхуками возвращают этот код. Операции: List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | В запросе ничего менять не нужно: на этом сервере вебхуки пока отключены. Повторите попытку позже. | Повторяется до 2 раз |
| scan_timeout | 504 | The scan did not finish in time. | Разрешение имени, подключение или TLS-рукопожатие заняли больше времени, чем допускает сканер: хост медленный или перегружен либо пакеты молча отбрасываются. Операции: TLS signature-health grade for a domain | Повторите попытку позже: медленные или перегруженные хосты могут не уложиться в отведённое время. | Повторяется до 2 раз |
| timeout | 504 | The operation did not finish within its time budget. | Обработка запроса не уложилась в лимит времени в 10 секунд. Входные данные в пределах лимитов на запрос не должны к этому приводить. Операции: API self-description, Verify an ECDSA signature, Convert a signature between DER and raw r‖s, Decode a JWT (no signature check), Verify an ES256/ES384/ES512 JWT signature, Decode an X.509 certificate or chain, List webhook endpoints, Create a webhook endpoint, Delete a webhook endpoint, Send a test event | Повторите запрос один раз; если с теми же входными данными время снова истечёт, сообщите значение requestId из тела ошибки. | Повторяется до 2 раз |
Повторные запросы
Официальные SDK повторяют запросы, получившие 429 (кроме quota_exceeded), 502, 503 и 504, не более 2 раз: ждут столько, сколько просит заголовок Retry-After (но не более 60 секунд), а без него используют экспоненциальную задержку с полным джиттером (full jitter). Каждая операция — чистая функция от входных данных, поэтому повторять запрос всегда безопасно; ваш собственный клиент может следовать тому же правилу.