Error 400 (Bad Request)
What should I do when I see this error in the Asaas Webhook logs?
The 400 Bad Request error indicates that the Webhook request reached the endpoint, but was rejected while validating or interpreting the received content.
In this scenario, mainly check the parser, the validations, and the structure expected by your application.
Main causes
The error may occur when the application:
- expects fields that do not exist in the payload;
- treats optional or null fields as required;
- cannot deserialize the JSON;
- rejects unknown attributes;
- has overly restrictive validations;
- tries to convert values to incompatible types;
- only accepts certain events;
- uses fixed structures that do not allow the payload to evolve.
AttentionIf not fixed, the 400 error can completely interrupt synchronization between your application and Asaas.
Check optional and null fields
Not every payment belongs to a subscription. An application may expect:
{
"payment": {
"subscription": "sub_123"
}
}But receive:
{
"payment": {
"subscription": null
}
}If payment.subscription is treated as required, the endpoint may reject the event with HTTP 400.
Only validate as required the fields needed for your business rule, and handle the null values expected for the resource.
Accept new attributes in the payload
An application may be prepared to receive:
{
"id": "evt_xxx",
"event": "PAYMENT_RECEIVED"
}The payload may receive new attributes over time:
{
"id": "evt_xxx",
"event": "PAYMENT_RECEIVED",
"newAttribute": "value"
}The parser should not reject the request just because it received an attribute that the application does not use yet.
ImportantThe Webhook payload may evolve over time. Your system must be prepared to accept new attributes without throwing exceptions.
How to identify the cause
1. Check the Webhook Logs
Go to Webhook Logs and find the attempt that returned HTTP 400.
Check:
- the payload sent;
- the time of the attempt;
- the HTTP code returned;
- the number of resends.
2. Compare the payload with the corresponding event
Confirm that the application is prepared to handle:
- optional attributes;
- null fields;
- attributes not yet used by the integration;
- the different events configured in the Webhook.
See the specific event page in Webhook Events.
3. Review your application logs
Use the attempt time recorded in the Webhook Logs to find the request in your system.
Check at which stage the rejection occurred, such as:
- deserialization;
- field validation;
- type conversion;
- event validation;
- business rule executed during the request.
Fix and validate the endpoint
After identifying the cause:
- adjust the parser or validation responsible for the
HTTP 400; - allow optional fields, null values, and unknown attributes when applicable;
- persist the event before starting long-running processing;
- respond with
HTTP 200after confirming persistence; - run additional rules asynchronously.
Webhooks follow the at least once model. Use the event id to prevent a retry from causing duplicate processing.
See how to implement idempotency in Webhooks.
Fix flow
%%{init: {"flowchart": {"nodeSpacing": 28,"rankSpacing": 32,"diagramPadding": 8,"padding": 10}}}%%
flowchart TD
A["Identify HTTP 400"] --> B["Check Webhook Logs"]
B --> C["Check the payload"]
C --> D["Fix parser or validations"]
D --> E["Test again"]
E --> F{"Is the queue interrupted?"}
F --> FSim(("Yes"))
F --> FNao(("No"))
FSim --> G["Reactivate the queue"]
FNao --> H["Wait for a new delivery"]
G --> I["Confirm HTTP 200"]
H --> I
classDef inicio fill:#DBEAFE,stroke:#2563EB,color:#1E3A8A,stroke-width:3px,font-size:17px
classDef decisao fill:#FEF3C7,stroke:#D97706,color:#78350F,stroke-width:3px,font-size:17px
classDef validacao fill:#E0F2FE,stroke:#0284C7,color:#0C4A6E,stroke-width:2px,font-size:17px
classDef sucesso fill:#DCFCE7,stroke:#16A34A,color:#14532D,stroke-width:3px,font-size:17px
classDef respostaSim fill:#22C55E,stroke:#15803D,color:#FFFFFF,stroke-width:3px,font-size:16px
classDef respostaNao fill:#EF4444,stroke:#B91C1C,color:#FFFFFF,stroke-width:3px,font-size:16px
class A inicio
class B,C,D,E,G,H validacao
class F decisao
class I sucesso
class FSim respostaSim
class FNao respostaNao
linkStyle default stroke:#94A3B8,stroke-width:2px
linkStyle 5 stroke:#22C55E,stroke-width:4px
linkStyle 6 stroke:#EF4444,stroke-width:4px
What happens while the error persists
Each HTTP 400 response is considered a delivery failure.
With consecutive failures:
- the same event may be sent again;
- the configuration enters the progressive penalty mechanism;
- after 15 consecutive failures, the Webhook queue is interrupted;
- while it is interrupted, new events are stored and are no longer sent.
If the queue is already interrupted, fix the error before reactivating it.
See how to reactivate an interrupted queue.
Next steps
Updated 15 days ago
