Synchronous and asynchronous communication
Understand when to use synchronous responses and when to wait for events to confirm the result of an operation with the Asaas API.
Not every operation is completed at the same instant the API responds.
In some cases, the synchronous response already represents the result needed to continue the flow. In others, it confirms only the initial processing of the request, while the definitive state will be known later through an event or a new query.
By the end of this page, you will understand when to use the API's synchronous response and when your application should wait for an asynchronous confirmation before advancing the flow.
When to use
Consider this distinction when:
- implementing operations whose state may change after the initial response;
- defining when a business action can be executed;
- using Webhooks to confirm later changes;
- modeling flows that depend on banks, payment methods, or other external processing;
- handling operations that may temporarily remain in processing.
Before you start
Before defining whether an operation will be handled synchronously or asynchronously:
- identify what the API response confirms for that operation;
- check whether the entity's state may change later;
- identify the Webhooks related to the flow;
- define which actions depend on a definitive confirmation;
- determine how your application will handle periods when the result is still being processed.
How it works
The first step is to understand what the request response represents.
%%{init: {"flowchart": {"nodeSpacing": 28,"rankSpacing": 32,"diagramPadding": 8,"padding": 10}}}%%
flowchart TD
A["Send request"] --> B["Receive API response"]
B --> C{"Can the result change later?"}
C --> CSim(("Yes"))
C --> CNao(("No"))
CNao --> D["Use the result from the response"]
CSim --> E["Record the current state"]
E --> F["Wait for new information"]
F --> G["Receive Webhook or query the API"]
G --> H["Update the local state"]
H --> I{"Does the state allow advancing?"}
I --> ISim(("Yes"))
I --> INao(("No"))
ISim --> J["Execute next action"]
INao --> K["Keep tracking the operation"]
classDef inicio fill:#DBEAFE,stroke:#2563EB,color:#1E3A8A,stroke-width:3px,font-size:17px
classDef processo fill:#E0F2FE,stroke:#0284C7,color:#0C4A6E,stroke-width:2px,font-size:17px
classDef decisao fill:#FEF3C7,stroke:#D97706,color:#78350F,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
classDef respostaNao fill:#EF4444,stroke:#B91C1C,color:#FFFFFF,stroke-width:3px
class A inicio
class B,E,F,G,H processo
class C,I decisao
class D,J sucesso
class K processo
class CSim,ISim respostaSim
class CNao,INao respostaNao
linkStyle default stroke:#94A3B8,stroke-width:2px
The decision does not depend only on the HTTP status code returned. The main point is to understand whether that response represents the result needed to continue the flow or just an intermediate state of the operation.
1. Identify what the synchronous response confirms
The synchronous response represents the result of the request executed at that moment.
It may be sufficient when the information needed to continue the flow has already been determined in the call itself.
For example, after successfully creating an entity, your application can use the returned data to:
- store the ID generated by Asaas;
- link the entity to the internal record;
- confirm that the data sent was accepted;
- continue steps that depend only on the creation of that record.
In this scenario, there is no need to wait for an event just to confirm again that the entity was created.
Use the synchronous response when it already represents the information needed for the next step of your flow.
2. Identify operations that depend on later confirmation
In other flows, the initial response does not represent the definitive result of the operation.
This happens mainly when there is later processing, such as:
- payment confirmation;
- a change in a charge's status;
- processing by banks or payment methods;
- later review or validation;
- a refund or another change that occurs after the initial call.
In these cases, the API response reports the state known at that moment. Your application must keep tracking the entity until it receives the information needed to move forward.
Do not confuse a processed request with a completed operation. A success response may indicate that the request was accepted without meaning the entire flow has already reached its final state.
3. Wait for confirmation before executing critical actions
When an action depends on the definitive result of the operation, it should not be executed based only on the initial response.
This is especially important before:
- releasing a product or service;
- confirming a purchase;
- updating an operation as completed;
- deducting inventory;
- sending a completion notification;
- starting another financial process that depends on that result.
Before these actions, confirm that the current state really allows moving forward.
An operation that may still change should remain in an intermediate state in your application until the necessary confirmation is received.
4. Consider eventual consistency
In asynchronous flows, your application's state may temporarily differ from the state in Asaas.
This behavior is known as eventual consistency.
For example:
- an operation changes state in Asaas;
- the corresponding event is generated;
- your application receives the Webhook;
- the event is processed;
- the local record is updated.
Between the first and the last step there is a window in which the two systems may show different information.
This temporary difference does not necessarily represent a failure.
The problem occurs when the application is not prepared for this condition or executes a definitive action while the state may still change.
5. Represent intermediate states in the application
When confirmation is not immediate, avoid reducing the flow to states such as success and failure only.
Your application may need to represent situations such as:
- awaiting processing;
- pending confirmation;
- under review;
- awaiting update;
- completed;
- failed.
The states used internally must reflect the actual behavior of the flow and allow the system to differentiate a completed operation from an operation whose result is not yet known.
This also improves the end user's experience, as they can receive appropriate information while processing continues.
6. Define how the confirmation will be received
For each asynchronous operation, define which mechanism will update your application.
Usually, the update happens through Webhooks.
API queries can complement this flow when it is necessary to:
- validate the current state;
- recover an update that was not processed;
- confirm an operation that remained in an intermediate state for longer than expected;
- run a reconciliation routine.
%%{init: {"flowchart": {"nodeSpacing": 28,"rankSpacing": 32,"diagramPadding": 8,"padding": 10}}}%%
flowchart TD
A["Operation awaiting confirmation"] --> B{"Webhook received?"}
B --> BSim(("Yes"))
B --> BNao(("No"))
BSim --> C["Process event"]
C --> D["Update local state"]
BNao --> E{"Was the expected time exceeded?"}
E --> ESim(("Yes"))
E --> ENao(("No"))
ENao --> F["Keep waiting"]
ESim --> G["Query state in Asaas"]
G --> H["Reconcile local state"]
classDef inicio fill:#DBEAFE,stroke:#2563EB,color:#1E3A8A,stroke-width:3px,font-size:17px
classDef processo fill:#E0F2FE,stroke:#0284C7,color:#0C4A6E,stroke-width:2px,font-size:17px
classDef decisao fill:#FEF3C7,stroke:#D97706,color:#78350F,stroke-width:2px,font-size:17px
classDef sucesso fill:#DCFCE7,stroke:#16A34A,color:#14532D,stroke-width:3px,font-size:17px
classDef recuperacao fill:#FEE2E2,stroke:#DC2626,color:#7F1D1D,stroke-width:2px,font-size:17px
classDef respostaSim fill:#22C55E,stroke:#15803D,color:#FFFFFF,stroke-width:3px
classDef respostaNao fill:#EF4444,stroke:#B91C1C,color:#FFFFFF,stroke-width:3px
class A inicio
class B,E decisao
class C processo
class D sucesso
class F processo
class G,H recuperacao
class BSim,ESim respostaSim
class BNao,ENao respostaNao
linkStyle default stroke:#94A3B8,stroke-width:2px
The query does not need to replace the event flow. It can act as a recovery mechanism when the expected confirmation does not arrive or is not processed correctly.
7. Define limits for waiting
Asynchronous operations should not wait indefinitely for an update without any monitoring.
For each flow, determine:
- how long a state change is expected to take;
- when the operation should be considered outside the expected behavior;
- when a query should be made;
- when a reconciliation routine should step in;
- when the situation should trigger an alert or investigation.
These limits must take into account the behavior of each operation and do not need to be the same for all flows.
How to decide between synchronous and asynchronous
Before implementing an operation, answer:
| Question | What to evaluate |
|---|---|
| Can the result change after the response? | If it can, the initial response should not be treated as definitive |
| Is there an event related to the change? | Use that event to track the state later |
| Does a critical action depend on this confirmation? | Wait for the required state before executing the action |
| Is there a normal processing period? | Represent that period as an intermediate state |
| What happens if the update does not arrive? | Define a query, reconciliation, or another recovery mechanism |
If an operation may change after the initial response, the flow must be prepared to track that evolution instead of assuming it has already been completed.
Attention — common mistakes
Avoid architectures that:
- treat every API response as definitive confirmation;
- confuse an accepted request with a completed operation;
- execute critical actions before the necessary confirmation;
- update the local state to completed before the definitive result;
- do not represent intermediate states;
- ignore the eventual consistency window;
- depend on an event without defining what to do if it is delayed or not processed.
Confirm your architecture
Before go-live, confirm that your application can answer:
- Which operations can be completed based on the synchronous response?
- Which depend on a later update?
- Which Webhooks represent these updates?
- Which actions need to wait for an asynchronous confirmation?
- How will an operation in processing be represented locally?
- What happens if the confirmation takes longer than expected?
- When should your application query the state again?
- How will the end user be informed while the operation is still being processed?
- How will a mismatch be identified and reconciled?
If these answers are not defined, the application may make definitive decisions while the operation is still in progress.
Best practices
- differentiate the result of the request from the complete result of the operation;
- use intermediate states to represent processing that has not yet completed;
- wait for the necessary confirmation before executing critical actions;
- use Webhooks to track later changes;
- define query and reconciliation mechanisms for exceptional situations;
- do not rely on fixed waiting times to assume an operation has been completed;
- inform the user when an operation is still being processed.
Next steps
After defining which operations depend on asynchronous communication, structure how these events will be received and processed:
Updated 2 days ago
