Receive market lifecycle updates.
After a prediction market has been delivered, wrangle.win can send subsequent lifecycle updates to the Callback URL configured for your merchant account.
The Callback URL receives market.resolving, market.resolved and market.cancelled events.
Use the top-level event field to route each callback into the appropriate internal workflow.
One Callback URL. Three lifecycle events.
These callbacks are sent only for markets that were previously delivered to your merchant account.
Outcome determination has started. This event is non-terminal and does not contain a final winner.
The market has a confirmed final winning answer.
The market is terminal without a winning answer.
AI-assisted. Human verified.
When outcome determination begins, wrangle.win first sends market.resolving. After verification, the lifecycle ends with either market.resolved or market.cancelled.
Track the underlying real-world event.
Analyze relevant information and available sources.
Human review verifies the evidence.
The winning answer is confirmed.
A terminal lifecycle event is sent to your Callback URL.
Lifecycle callback payloads
All callback events contain the market and its related content. Winner fields differ according to the lifecycle state.
The values below are illustrative. Use the IDs supplied in the original market delivery to map every callback to your own market and outcomes.
{
"event": "market.resolving",
"market": {
"id": 572,
"status": "resolving",
"resolved_at": null,
"winning_answer_id": null,
"answers": [
{
"id": 1141,
"sort_order": 1,
"is_winner": false,
"translations": [...]
}
],
"winning_answer": null
}
}
{
"event": "market.cancelled",
"market": {
"id": 572,
"status": "cancelled",
"resolved_at": null,
"winning_answer_id": null,
"answers": [
{
"id": 1141,
"sort_order": 1,
"is_winner": false,
"translations": [...]
}
],
"winning_answer": null
}
}
{
"event": "market.resolved",
"market": {
"id": 572,
"status": "resolved",
"source_locale": "en",
"finish_at": "2026-10-15T18:00:00+00:00",
"published_at": "2026-09-30T10:00:00+00:00",
"resolved_at": "2026-10-15T18:15:00+00:00",
"winning_answer_id": 1141,
"translations": [
{
"locale": "en",
"title": "Will Bitcoin be above $120,000 on October 15?",
"description": "This market resolves according to the defined resolution conditions."
}
],
"answers": [
{
"id": 1141,
"sort_order": 1,
"is_winner": true,
"translations": [
{
"locale": "en",
"title": "Yes"
}
]
},
{
"id": 1142,
"sort_order": 2,
"is_winner": false,
"translations": [
{
"locale": "en",
"title": "No"
}
]
}
],
"winning_answer": {
"id": 1141,
"sort_order": 1,
"translations": [
{
"locale": "en",
"title": "Yes"
}
]
},
"sources": [
{
"url": "https://example.com/source",
"sort_order": 1
}
],
"categories": [
{
"id": 3,
"name": "Crypto",
"slug": "crypto"
}
],
"countries": [],
"country_groups": [
{
"id": 1,
"name": "Global",
"slug": "global"
}
]
}
}
Fields that identify the result
| Field | Type | Description |
|---|---|---|
| event | string | Resolution event type: market.resolved. |
| market.id | integer | Same wrangle.win market ID supplied during the original market delivery. |
| market.resolved_at | ISO 8601 | Time the market resolution was confirmed. |
| market.winning_answer_id | integer | ID of the confirmed winning answer. |
| market.answers[].is_winner | boolean | Indicates whether the individual answer is the confirmed winning outcome. |
| market.winning_answer | object | Complete winning answer object including its translations. |
Match the callback using the IDs you already stored.
Lifecycle callbacks use the same market and answer identifiers delivered with the original market.published event.
Process every lifecycle event safely.
Callback processing should be idempotent. Repeated resolving events must not create duplicate state transitions, and repeated terminal events must never cause settlement, cancellation, refund or balance operations to run twice.
Validate the incoming event and required fields.
Locate your market using the stored wrangle.win ID.
Verify that the market has not already been settled.
Apply the winning outcome using your own business logic.
Return a successful HTTP response.
Laravel lifecycle callback receiver
The example below demonstrates the basic processing pattern. Your platform can use any framework, database structure or settlement architecture.
Route::post('/wrangle/callback', [
MarketLifecycleController::class,
'receive'
]);
public function receive(Request $request)
{
$payload = $request->validate([
'event' => [
'required',
'string',
'in:market.resolving,market.resolved,market.cancelled',
],
'market' => ['required', 'array'],
'market.id' => ['required', 'integer'],
'market.winning_answer_id' => ['nullable', 'integer'],
'market.resolved_at' => ['nullable'],
]);
$market = Market::where(
'wrangle_market_id',
$payload['market']['id']
)->firstOrFail();
switch ($payload['event']) {
case 'market.resolving':
// Non-terminal. Do not settle or infer a winner.
ProcessMarketResolving::dispatch($market->id);
break;
case 'market.resolved':
// Validate the supplied winner and process settlement idempotently.
ProcessMarketResolution::dispatch(
$market->id,
$payload['market']['winning_answer_id']
);
break;
case 'market.cancelled':
// Terminal without a winner. Apply existing cancellation rules.
ProcessMarketCancellation::dispatch($market->id);
break;
}
return response()->json([
'accepted' => true,
]);
}
This example illustrates the integration pattern only. Settlement, accounting, wallet updates and user balance calculations remain entirely within your platform.
Never process a terminal event twice.
Network conditions can cause an event to be delivered again. A duplicate callback must not result in duplicate settlement, cancellation, refunds, payouts, balance changes or accounting operations.
Your platform should persist processed lifecycle state and check it before executing terminal financial operations.
Confirm that the callback was accepted.
{
"accepted": true
}
A successful HTTP response confirms that your platform accepted the lifecycle event.
A non-successful response is treated as a failed callback delivery.
Acknowledge first. Process safely.
For reliable integrations, validate and persist the lifecycle event before performing expensive processing.
If your settlement process involves many users, transactions or balance operations, queue the internal settlement process and return a successful HTTP response after the lifecycle event has been safely recorded.
We report the market lifecycle. You control user settlement.
The market.resolved callback communicates the confirmed outcome of the prediction market.
It does not contain instructions about individual player winnings, losses, balances or payouts.
Market Resolution
- Monitor the underlying event
- Analyze relevant information
- Perform AI-assisted analysis
- Perform human verification
- Confirm the winning outcome
- Send lifecycle callbacks
User Settlement
- Identify participating users
- Calculate positions and results
- Determine winnings and losses
- Update user balances
- Process payouts where applicable
- Maintain your financial records
Lifecycle callbacks are not a second market charge.
Resolving, resolution and cancellation callbacks are part of the lifecycle of a market already delivered to your merchant account.
Receiving market.resolving, market.resolved or market.cancelled does not create another per-market delivery charge for the same market.
Make your integration resilient.
Learn how to handle unsuccessful deliveries, duplicate events, temporary server errors and retries.
Errors & Retries в†’