The one-sentence test
A design is finished when you can state each of the following in one sentence:
- Latency budget: how long the integration may take, and against which limit.
- Idempotency strategy: what happens when the same input arrives twice.
- Failure behavior: what happens when the integration, or something it depends on, is unavailable.
If any of the three needs a meeting to answer, the design isn't finished. The rest of this page lists what each connection point requires.
API Extension contract
An API Extension runs inside the API request. Its response time adds directly to the request, and its failure fails the request.
Time limits
timeoutInMs for the expected work, then set a lower internal target so transient latency doesn't consume the entire budget. Check the current connection, response, and configurable maximum values in API Extension time limits.How commercetools handles the response
Your Extension responds in one of three valid ways. Any other response is treated as a failure.
Two behaviors matter most for your design:
- A failed Extension fails the customer's request. commercetools doesn't retry an Extension within a request, as Error cases describes, so only the next request calls the Extension again.
- commercetools never fails open. A timeout or bad response always fails the request. If you want the request to succeed when your own dependency is down, your Extension must decide that and respond accordingly.
Choose a failure behavior
When a service your Extension depends on is unavailable, your Extension chooses between two behaviors:
- Fail open: approve the request without changes. The customer continues, but your rule isn't applied.
- Fail closed: reject the request. Your rule is enforced, but the customer is blocked.
isMetroArea Custom Field on the Cart so the same-day Shipping Method can apply. The first response is the normal case. The next two show what the Extension returns when the eligibility service is unavailable, one for each behavior.In the normal case, the eligibility service confirms a metro postcode, and the Extension approves and sets the Custom Field:
{
"actions": [
{ "action": "setCustomField", "name": "isMetroArea", "value": true }
]
}
actions array means "no updates requested":{
"actions": []
}
To fail closed, the Extension rejects the request:
{
"errors": [
{
"code": "InvalidInput",
"message": "Same-day delivery eligibility can't be checked. Try again shortly.",
"localizedMessage": {
"en-AU": "Same-day delivery eligibility can't be checked. Try again shortly."
}
}
]
}
- For the
codeandlocalizedMessagefields, see Validation failed.
504 response with the ExtensionNoResponse error code, whatever failure behavior you designed.setCustomField works only if the Cart already uses a Type that defines isMetroArea, so make sure the storefront creates Carts with that Type. Don't use setCustomType in the Extension instead, because it replaces the Cart's Type and all of its existing Custom Fields.Choose where Extensions are worth the risk
Use risk to decide where an Extension belongs:
- Lower risk: back-office flows that aren't on the customer's critical path, such as enforcing data-quality rules before a Product is published.
- Higher risk: customer-facing flows, such as Cart updates and checkout. A slow or failing Extension directly affects conversion.
Subscription contract
A Subscription doesn't affect the original request. Its obligations fall on the consumer that reads the queue.
Idempotency
Acknowledgment timing
When you acknowledge a notification decides which failure you accept for a side effect, such as sending an email:
- Acknowledge before you act (at-most-once). A failure after the acknowledgment doesn't cause a redelivery, so it can't repeat the effect. The effect is lost instead, because the queue doesn't redeliver an acknowledged notification. commercetools can't help here: its delivery guarantee ends when the notification reaches the queue.
- Acknowledge after you act (at-least-once). A failure is retried. A redelivery repeats the effect unless you deduplicate with the keys above.
Ordering
Delivery time
Retries and health
commercetools retries delivery based on the Subscription's health status:
- The health status decides the retry window; see At-least-once delivery and the health endpoint. Set up automatic alerts for production queues.
- Configure a dead-letter queue on your message queue, so a message that fails on every attempt doesn't block the others.
Payloads that don't fit the queue
payloadNotIncluded when it doesn't fit the queue; the delivery payload reference defines when.Your consumer has two ways to recover the content:
- Retrieve the full Message from the Messages API, if Messages are enabled for the Project.
- Retrieve the resource. The resource returns its current state, which may be newer than the Message. Compare its
versionwith the Message'sresourceVersionbefore you act on it.
Avoid loops
If your consumer writes back to the resource it was notified about, that write can trigger another notification. Filter out changes your own integration made, for example by checking who made the change or by comparing the values before writing.
Other contracts
The following obligations are recommended practice. They come from how each pattern behaves, not from a platform limit.
| Pattern | Obligations |
|---|---|
| Inbound endpoint | Authenticate the caller. Validate the payload. Upsert by a stable key, so a repeated webhook has no extra effect. |
| Scheduled job | Prevent overlapping runs. Save checkpoints, so a restarted job resumes instead of starting over. Make each unit of work idempotent. |
| Import API | Accept eventual consistency. Monitor ImportOperation states. Make sure referenced resources exist within the documented operation lifetime. |
Runtime terms on Connect
504 ExtensionNoResponse. A production Deployment keeps warm instances ready, and Choose where it runs and how to adopt it covers when it's available.Worked example: price two contracts
Zen Electron's team writes the contract for two integrations before building them. The figures are the team's design choices, not platform values.
- Latency budget: respond within 300 ms, against a
timeoutInMsof 1,000 ms, with outbound calls to the postcode service limited to 200 ms. - Idempotency: the Extension sets
isMetroAreafrom the current address, so repeating the call produces the same result. - Failure behavior: if the postcode service is unavailable, fail open by approving with no actions.
isMetroAreastays unset, so same-day delivery isn't offered, but the customer can still check out with other Shipping Methods. Run the Extension on a production Deployment or always-warm infrastructure in the Project's Region.
- Latency budget: acknowledge within the Connect event acknowledgment deadline, and aim to send within 5 minutes of the Order in normal conditions. Delivery time isn't guaranteed, so a delay of several minutes isn't a defect.
- Idempotency: acknowledge before sending, so a failed send doesn't lead to a redelivery and a second attempt. A duplicate is still possible if the acknowledgment doesn't reach the queue in time, and the team accepts that as rare. Sending an email can't be undone, and the team prefers a missed email to a duplicate.
- Failure behavior: if the email provider is down or the send fails after the acknowledgment, the email is dropped, because the queue doesn't redeliver an acknowledged notification. The team accepts that for order confirmations and watches the provider's activity log for missing sends. An email where a miss blocks the customer, such as password reset, needs its own decision.
Key takeaways
- A design is finished when you can state its latency budget, idempotency strategy, and failure behavior in one sentence each.
- An API Extension must respond within its configured platform limit. commercetools never retries it within a request and never fails open.
- Failing open is your Extension's choice: approve with no actions when your dependency is down.
- Subscription consumers must be idempotent (
resource.idwithsequenceNumberorversion), tolerate out-of-order delivery, and pair with reconciliation for time-critical flows. - Acknowledging before a side effect avoids duplicates but loses the effect if it then fails. Acknowledging after it retries failures but needs deduplication. Choose per effect.
- Handle
payloadNotIncluded, and compare versions if you retrieve the current resource. - Sandbox Deployments on Connect scale to zero, so their cold starts can exceed the response budget of a customer-facing Extension.