Skip to content

Errors

Every error response has the same JSON body:

{
"code": "hook_not_found",
"message": "We couldn't find this webhook. Check the link or create a new one in the app.",
"docs": "https://developers.ggspeak.app/webhooks/erros#hook_not_found"
}
  • code is stable: branch on it in your code. message is for a person to read.
  • message comes in the language of the Accept-Language header (Portuguese, Spanish or English). With no header it’s Portuguese.
  • docs points to the section of the Portuguese page named after the code. The same sections live on this page, under the same names.
  • A 429 also carries retry_after.
Status code When
404 hook_not_found Wrong id or token, deleted webhook or channel
404 message_not_found A message that isn’t from the webhook
410 hook_paused The webhook is paused
413 payload_too_large Body over 16 KB
422 payload_unrecognized No format recognized
422 payload_invalid Broken JSON or an invalid field
429 rate_limited Over the send rate
500 internal Our side failed

404. The link doesn’t lead to any webhook. The response is the same for a wrong id and a wrong token, so it never confirms that an id exists.

{
"code": "hook_not_found",
"message": "We couldn't find this webhook. Check the link or create a new one in the app.",
"docs": "https://developers.ggspeak.app/webhooks/erros#hook_not_found"
}

Causes: the link was copied partially, the webhook was deleted, its token was replaced with New link, the channel was deleted, Integrations are turned off on the platform, or the URL suffix doesn’t exist (only /discord, /slack and /betterstack).

What to do: check the whole link. If it’s no longer in the app, generate a new one under Integrations and update the tool.

404. On PATCH or DELETE of a message, the id doesn’t exist, belongs to a person, or belongs to another webhook.

{
"code": "message_not_found",
"message": "This message doesn't exist or wasn't sent by this webhook.",
"docs": "https://developers.ggspeak.app/webhooks/erros#message_not_found"
}

What to do: use the id returned by a ?wait=true response. A webhook can only touch messages it sent itself.

410. Someone who manages the community paused the webhook.

{
"code": "hook_paused",
"message": "This webhook is paused. Someone who manages the community can resume it.",
"docs": "https://developers.ggspeak.app/webhooks/erros#hook_paused"
}

What to do: ask whoever manages the community to use Resume on the webhook. Retrying won’t help while it’s paused.

413. The body is over 16 KB.

{
"code": "payload_too_large",
"message": "The body is over 16 KB. Send less text.",
"docs": "https://developers.ggspeak.app/webhooks/erros#payload_too_large"
}

What to do: send only the essentials. A card takes a title, a body and up to 6 fields: a whole log won’t fit, so send a summary and a link (Limits).

422. The JSON arrived, but it lacks the fields of the expected format: with a suffix (/discord, /slack, /betterstack), that format’s fields; on the bare URL, no format matched (detection goes GGspeak, then Discord, then Slack).

{
"code": "payload_unrecognized",
"message": "We don't recognize this format. Send text or card, or a Discord or Slack body.",
"docs": "https://developers.ggspeak.app/webhooks/erros#payload_unrecognized"
}

On the bare URL, the body must be a JSON object with card or key (GGspeak), content or embeds (Discord), or text, attachments or blocks (Slack). With a suffix, that format applies: /betterstack expects the incident body (data.attributes). A Better Stack body is only read on the URL ending in /betterstack.

What to do: use one of the formats. If your tool sends its own JSON that GGspeak doesn’t know, add a step in between that builds a text or a card.

422. The body isn’t valid JSON, or a field is outside what GGspeak accepts. The message names the field and the reason.

{
"code": "payload_invalid",
"message": "Check the card.state field: use alert, warn, ok or info.",
"docs": "https://developers.ggspeak.app/webhooks/erros#payload_invalid"
}

Broken JSON comes back as “The body isn’t valid JSON.” The field reasons:

Reason When
must be an object card isn’t an object
must be a string text, key or card.body isn’t a string
must be a list card.fields isn’t a list
each field needs name and value as strings An item in card.fields with no name or value
use alert, warn, ok or info card.state has any other value
title is missing card.title empty or absent
content or embeds is missing content or embeds is present but has nothing to show (with neither field, it is payload_unrecognized)
text or card is missing A GGspeak body with neither text nor card
text or attachments is missing text, attachments or blocks is present but there is no text and no attachments with a color (with none of the three fields, it is payload_unrecognized)
is over 2,000 characters text is too long
must be 1 to 128 visible ASCII characters, no spaces key has the wrong shape

What to do: fix the field the message names.

429. Too many sends in a row. The body carries retry_after (seconds, decimal), and the Retry-After header carries the same value in whole seconds, like Discord.

{
"code": "rate_limited",
"message": "Too many requests in a row. Wait a moment and try again.",
"docs": "https://developers.ggspeak.app/webhooks/erros#rate_limited",
"retry_after": 0.8
}

What to do: wait retry_after seconds and send again. If your tool fires a lot at once, fold the notices into one card or use the key (Card and key). The numbers are in Limits.

500. Something went wrong on our side.

{
"code": "internal",
"message": "Something went wrong on our side. Try again.",
"docs": "https://developers.ggspeak.app/webhooks/erros#internal"
}

What to do: try again shortly. If it keeps happening, tell the GGspeak team.