wrangle.win
wrangle.win

Resolution Callbacks

Learn how wrangle.win sends verified prediction market results to your platform using market.resolved callbacks, winning answer IDs and server-to-server resolution delivery.

API В· Lifecycle Callbacks

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.

Callback Events

One Callback URL. Three lifecycle events.

These callbacks are sent only for markets that were previously delivered to your merchant account.

market.resolving

Outcome determination has started. This event is non-terminal and does not contain a final winner.

market.resolved

The market has a confirmed final winning answer.

market.cancelled

The market is terminal without a winning answer.

Example Merchant Callback Endpoint
POST https://merchant.example.com/api/wrangle/callback
Resolution Flow

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.

01
Monitor

Track the underlying real-world event.

02
Analyze

Analyze relevant information and available sources.

03
Verify

Human review verifies the evidence.

04
Confirm

The winning answer is confirmed.

05
Deliver

A terminal lifecycle event is sent to your Callback URL.

Payload

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.

market.resolving
{
  "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
  }
}
market.cancelled
{
  "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
  }
}
market.resolved В· Full Example
{
  "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"
      }
    ]
  }
}
Resolution Fields

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.
Market Mapping

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.

Find Your Market
market.id
wrangle_market_id в†’ internal_market_id
Find Winning Outcome
winning_answer_id
wrangle_answer_id в†’ internal_outcome_id
Recommended Processing

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.

01
Validate

Validate the incoming event and required fields.

02
Find

Locate your market using the stored wrangle.win ID.

03
Check

Verify that the market has not already been settled.

04
Settle

Apply the winning outcome using your own business logic.

05
Confirm

Return a successful HTTP response.

Example Implementation

Laravel lifecycle callback receiver

The example below demonstrates the basic processing pattern. Your platform can use any framework, database structure or settlement architecture.

routes/api.php
Route::post('/wrangle/callback', [
    MarketLifecycleController::class,
    'receive'
]);
MarketLifecycleController.php
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.

Important

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.

HTTP Response

Confirm that the callback was accepted.

Successful
HTTP 2xx
{
  "accepted": true
}

A successful HTTP response confirms that your platform accepted the lifecycle event.

Failed
Non-2xx

A non-successful response is treated as a failed callback delivery.

Response Time

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.

Responsibility Boundary

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.

wrangle.win

Market Resolution

  • Monitor the underlying event
  • Analyze relevant information
  • Perform AI-assisted analysis
  • Perform human verification
  • Confirm the winning outcome
  • Send lifecycle callbacks
Your Platform

User Settlement

  • Identify participating users
  • Calculate positions and results
  • Determine winnings and losses
  • Update user balances
  • Process payouts where applicable
  • Maintain your financial records
Billing

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.

Next

Make your integration resilient.

Learn how to handle unsuccessful deliveries, duplicate events, temporary server errors and retries.

Errors & Retries в†’