Справочник

Грешки и ограничения

Всяка грешка в REST има едно и също кратко тяло. Решавайте първо по HTTP статуса, после по code, и посочвайте requestId, когато ни пишете за помощ.

Тялото на грешката#

JSON
{
  "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 ще използва нея, така че да свържете своите дневници с нашите. Посочвайте го винаги, когато пишете на поддръжката.

curl
# 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, вече зает час.Не, поправете заявката.
401API ключът липсва, непознат е или е отменен.Не.
403Ключът няма право на това (status=draft с ключ ck_pub_) или сайтът няма право да изпраща този формуляр.Не.
404Няма такава колекция, запис, формуляр или работно пространство, или GraphQL е изключен за работното пространство.Не.
413Тялото на заявката е твърде голямо.Не.
429Достигнато е ограничение на заявките.Да, по-късно.
500Грешка при нас. Съобщението е общо; подробностите се намират по requestId.Да, с нарастваща пауза.
503Временно недостъпно, например спрени изпращания на формуляри.Да, по-късно.

Кодове на грешки#

Повечето грешки ползват общ код, изведен от статуса. Някои адреси добавят собствен. Сравнявайте кодовете точно както са изписани: общите нямат долна черта.

codeСтатусКъде
BADREQUEST400Всяка грешна заявка: непознато поле или оператор във филтъра, непознат език, грешна стойност на richtext, повече от 10 филтъра, отказана captcha, тяло, което не минава валидирането, току-що зает час.
UNAUTHORIZED401Съдържание и GraphQL: без ключ или с невалиден или отменен ключ.
FORBIDDEN403Поискани чернови с ключ ck_pub_.
NOTFOUND404Непозната колекция или запис, непознат slug на работно пространство.
VALIDATION_FAILED400Формуляри: полетата не отговарят на правилата на формуляра; details е [{ field, message }].
ORIGIN_NOT_ALLOWED403Формуляри: Origin не е сред разрешените сайтове на формуляра.
FORM_UNAVAILABLE404Формуляри: формулярът не е активен или модулът „Формуляри“ е изключен.
RATE_LIMITED429Формуляри: надхвърлен е часовият лимит на формуляра по IP или общо.
FORMS_PAUSED503Формуляри: изпращанията са временно спрени за цялата платформа.
ENTITY_TOO_LARGE413Тялото е над допустимия размер.
INTERNAL_SERVER_ERROR500Неочаквана грешка. Опитайте отново по-късно и посочете requestId пред поддръжката.
TOO_MANY_REQUESTS429Достигнато е ограничение по ключ или по IP. Изчакайте и опитайте отново. (Версиите преди 24 септември 2026 г. връщаха INTERNAL_SERVER_ERROR със статус 429, затова проверката по статуса работи навсякъде.)

Грешки при валидиране#

Формулярите обясняват всяко поле:

JSON
{
  "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 тялото стриктно и изброяват всеки проблем, включително полетата, които не приемат:

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.

TypeScript 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.