Справочник
Грешки и ограничения
Всяка грешка в REST има едно и също кратко тяло. Решавайте първо по HTTP статуса, после по code, и посочвайте requestId, когато ни пишете за помощ.
Тялото на грешката#
{
"error": {
"code": "NOTFOUND",
"message": "Entry not found",
"requestId": "0f6c1d2e-3b4a-4c5d-8e9f-a0b1c2d3e4f5"
}
}| Поле | |
|---|---|
code | Код за програмна обработка (вижте по-долу). |
message | Обяснение за човек, обикновено на английски; някои съобщения при срещите са на български, както ги виждат посетителите. При валидиране на тялото е списък със съобщения. |
details | Има го, когато има какво още да се каже: проблеми по полета или списъкът със съобщения от валидирането. |
requestId | Открива заявката в дневниците на Citron. |
GraphQL съобщава за грешки в заявката в собствения си масив errors; вижте грешки в GraphQL.
Идентификатори на заявки#
Всяка грешка съдържа requestId, а успешните отговори за контакт и срещи го имат в meta.requestId. Изпратете своя заглавка X-Request-Id и API ще използва нея, така че да свържете своите дневници с нашите. Посочвайте го винаги, когато пишете на поддръжката.
# Send your own id and it comes back as requestId (and in the API's logs)
curl https://api.console.citronos.com/v1/content/nope \
-H "Authorization: Bearer $CITRON_API_KEY" \
-H "X-Request-Id: my-site-7f3a"
# {"error":{"code":"NOTFOUND","message":"Collection \"nope\" not found","requestId":"my-site-7f3a"}}HTTP статуси#
| Статус | Значение | Нов опит? |
|---|---|---|
200, 201 | Успех. Записванията отговарят с 201. | |
303 | Обикновен HTML формуляр е приет; следвайте пренасочването. | |
304 | Без промяна: вашият ETag в If-None-Match е актуален. | |
400 | Нещо в заявката е грешно: параметър, филтър, тялото, captcha, вече зает час. | Не, поправете заявката. |
401 | API ключът липсва, непознат е или е отменен. | Не. |
403 | Ключът няма право на това (status=draft с ключ ck_pub_) или сайтът няма право да изпраща този формуляр. | Не. |
404 | Няма такава колекция, запис, формуляр или работно пространство, или GraphQL е изключен за работното пространство. | Не. |
413 | Тялото на заявката е твърде голямо. | Не. |
429 | Достигнато е ограничение на заявките. | Да, по-късно. |
500 | Грешка при нас. Съобщението е общо; подробностите се намират по requestId. | Да, с нарастваща пауза. |
503 | Временно недостъпно, например спрени изпращания на формуляри. | Да, по-късно. |
Кодове на грешки#
Повечето грешки ползват общ код, изведен от статуса. Някои адреси добавят собствен. Сравнявайте кодовете точно както са изписани: общите нямат долна черта.
code | Статус | Къде |
|---|---|---|
BADREQUEST | 400 | Всяка грешна заявка: непознато поле или оператор във филтъра, непознат език, грешна стойност на richtext, повече от 10 филтъра, отказана captcha, тяло, което не минава валидирането, току-що зает час. |
UNAUTHORIZED | 401 | Съдържание и GraphQL: без ключ или с невалиден или отменен ключ. |
FORBIDDEN | 403 | Поискани чернови с ключ ck_pub_. |
NOTFOUND | 404 | Непозната колекция или запис, непознат slug на работно пространство. |
VALIDATION_FAILED | 400 | Формуляри: полетата не отговарят на правилата на формуляра; details е [{ field, message }]. |
ORIGIN_NOT_ALLOWED | 403 | Формуляри: Origin не е сред разрешените сайтове на формуляра. |
FORM_UNAVAILABLE | 404 | Формуляри: формулярът не е активен или модулът „Формуляри“ е изключен. |
RATE_LIMITED | 429 | Формуляри: надхвърлен е часовият лимит на формуляра по IP или общо. |
FORMS_PAUSED | 503 | Формуляри: изпращанията са временно спрени за цялата платформа. |
ENTITY_TOO_LARGE | 413 | Тялото е над допустимия размер. |
INTERNAL_SERVER_ERROR | 500 | Неочаквана грешка. Опитайте отново по-късно и посочете requestId пред поддръжката. |
TOO_MANY_REQUESTS | 429 | Достигнато е ограничение по ключ или по IP. Изчакайте и опитайте отново. (Версиите преди 24 септември 2026 г. връщаха INTERNAL_SERVER_ERROR със статус 429, затова проверката по статуса работи навсякъде.) |
Грешки при валидиране#
Формулярите обясняват всяко поле:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "Please check the highlighted fields",
"details": [{ "field": "email", "message": "Enter a valid email" }],
"requestId": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f"
}
}Адресите за контакт и срещи проверяват JSON тялото стриктно и изброяват всеки проблем, включително полетата, които не приемат:
{
"error": {
"code": "BADREQUEST",
"message": ["mode must be one of the following values: online, in_office"],
"details": ["mode must be one of the following values: online, in_office"],
"requestId": "5e6f7a8b-9c0d-4e1f-8a2b-3c4d5e6f7a8b"
}
}Ограничения на заявките#
| Какво | Лимит | Брои се за |
|---|---|---|
| API за съдържание и GraphQL | По подразбиране 300 заявки в минута | API ключ, във фиксирани едноминутни прозорци. REST и GraphQL го делят. |
| Изпращане на контакт, записване на среща, изпращане на формуляр | По подразбиране 10 в минута и 60 в час | IP адрес на посетителя, за всеки адрес поотделно. |
| Изпращания на формуляри | По подразбиране 30 на IP адрес в час и 500 на формуляр в час | Настройват се за всеки формуляр в конзолата. |
- Над лимита отговорът е
429. Ограниченията по IP добавятRetry-After-short(прозорецът от минута) илиRetry-After-long(прозорецът от час) със секундите за изчакване. Лимитът за ключ се нулира в началото на следващата минута. - Сървърът на сайта ви обикновено чете съдържанието от един IP адрес; API за съдържание е ограничено по ключ, а не по IP, така че посетителите никога не забавят изобразяването на страниците.
- Ако препращате изпращанията през своя сървър, подавайте
x-forwarded-for, за да има всеки посетител собствен лимит. - Кеширайте при себе си (ETag, обновяване в Next.js, уебкуки), вместо да четете при всяко отваряне на страница.
В SDK#
SDK превръща всяко тяло на грешка в CitronError и сам повтаря заявките при 429 и 5xx. Вижте грешки в SDK.
import { CitronGraphQLError, isCitronError } from '@citron/sdk';
try {
await citron.collection('products').get('does-not-exist');
} catch (err) {
if (err instanceof CitronGraphQLError) {
console.error(err.errors, err.data); // GraphQL errors and partial data
} else if (isCitronError(err)) {
console.error(err.status, err.code, err.message, err.requestId, err.details);
if (err.isNotFound) { /* render your 404 */ }
if (err.isRetryable) { /* 0, 408, 429 or 5xx; err.retryAfter when the server said */ }
} else {
throw err;
}
}Справочникът описва само публичното API и следва договора му за съвместимост: публичните отговори само получават нови полета. Описанието на тези адреси във формат OpenAPI е на /developers/openapi.json.