Build for failures without creating duplicates.
Market delivery and lifecycle callbacks are server-to-server HTTP requests. Network failures, timeouts, deployments and temporary application errors can prevent an event from completing successfully.
Your receiving endpoints should therefore be designed so that an event can be safely received again without creating duplicate markets, repeated lifecycle transitions or duplicate financial actions.
Return 2xx only after the event has been safely accepted.
When your endpoint returns a successful HTTP response, wrangle.win treats the delivery attempt as accepted.
Validate and persist enough information to safely continue processing before returning success.
Failures can occur on either receiving endpoint.
Initial market delivery uses your Market URL. Subsequent lifecycle notifications use your Callback URL. Both endpoints should follow the same HTTP acceptance and idempotency principles.
How responses are interpreted
Your Market URL and Callback URL should return standard HTTP status codes.
Accepted
Your platform successfully accepted the event.
Request Rejected
Your endpoint rejected the request because of validation, authorization, routing or another request-level problem.
Server Failure
Your server was unable to complete the request because of an application or infrastructure problem.
Why a delivery can fail
Your application, web server or load balancer is temporarily unavailable.
Your endpoint does not return a response within the delivery timeout.
Your application throws an exception or returns a server error.
The configured Market URL or Callback URL no longer points to a valid route.
Your application rejects the incoming payload before accepting it.
A deployment or infrastructure restart temporarily interrupts your receiving endpoint.
Delivery requests use a 20-second timeout.
Do not use the incoming HTTP request to perform long-running business operations.
Accept the event, persist the information required for processing and move expensive work to your own background queue whenever possible.
↓
Process thousands of user positions
↓
Update balances
↓
Call external services
↓
Return 200
↓
Validate
↓
Persist / Queue
↓
Return 2xx
↓
Process asynchronously
Never assume an event can arrive only once.
A request can reach your application successfully while the response is lost or delayed before the sender receives it.
From the receiving platform's perspective, every event should therefore be safe to process more than once.
The same event must produce the same final state.
Idempotent processing protects your platform against duplicate records and repeated business operations.
Do not create the market twice.
Use market.id as the external wrangle.win identifier and update or reuse the existing local mapping when the same delivery is received again.
Do not start settlement.
Resolving is non-terminal. A repeated resolving callback should leave the market in the same local state and must not create or infer a winning answer.
Never settle the market twice.
Before settlement, verify the supplied winning_answer_id and confirm that the final result has not already been processed.
Never cancel or refund twice.
Cancellation is terminal and has no winner. A duplicate callback must not repeat void, refund, balance or other financial operations.
A duplicate terminal callback is not a second financial operation.
This distinction is especially important for both market.resolved and market.cancelled when your platform maintains player balances or other financial records.
if ($market->settled_at) {
return response()->json([
'accepted' => true,
'already_processed' => true,
]);
}
Returning success for an already processed terminal event is normally preferable to treating a legitimate duplicate as a new settlement, cancellation, refund or balance operation.
Enforce uniqueness at the database level.
Application checks are useful, but database constraints provide additional protection when two requests arrive almost simultaneously.
Schema::table('markets', function (Blueprint $table) {
$table->unsignedBigInteger('wrangle_market_id')
->unique();
});
Idempotent market delivery
public function receive(Request $request)
{
$payload = $request->validate([
'event' => ['required', 'string'],
'market.id' => ['required', 'integer'],
]);
if ($payload['event'] !== 'market.published') {
return response()->json([
'message' => 'Unsupported event',
], 422);
}
$market = Market::updateOrCreate(
[
'wrangle_market_id' => $payload['market']['id'],
],
[
'status' => $payload['market']['status'] ?? null,
]
);
ProcessMarket::dispatch(
$market->id,
$payload['market']
);
return response()->json([
'accepted' => true,
]);
}
Common HTTP responses
| Status | Meaning | Recommended Action |
|---|---|---|
| 200 | Event accepted | No additional action required. |
| 400 | Invalid request | Review request validation and endpoint implementation. |
| 401 / 403 | Request not authorized | Review the security rules configured by your endpoint. |
| 404 | Endpoint not found | Check your configured Market URL or Callback URL. |
| 422 | Payload rejected | Review your validation rules and expected payload. |
| 429 | Too many requests | Review endpoint capacity and rate limiting. |
| 500 | Application failure | Check your application logs and exception handling. |
| 502 / 503 / 504 | Infrastructure unavailable | Check your proxy, application server and infrastructure. |
Log enough information to investigate failures.
Your integration logs should make it possible to determine which market was received, which event was processed and whether processing completed successfully.
Do not use HTTP success to represent business settlement completion.
A successful callback response should indicate that your platform has safely accepted the lifecycle event.
It does not need to mean that every user position, balance update or payout has already completed synchronously.
Those operations belong to your internal platform and can continue asynchronously after the lifecycle event has been durably recorded.
wrangle.win delivers lifecycle events. Your platform controls financial processing.
wrangle.win does not need information about player stakes, winnings, losses, balances or payout calculations in order to deliver market lifecycle events.
Your platform determines how resolved or cancelled markets affect its users and financial records.
Secure your receiving endpoints.
Continue with security recommendations for production Market and Callback endpoints.
API Security в†’