> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nippy.la/llms.txt
> Use this file to discover all available pages before exploring further.

# spin()

> Run an immediate spin and receive the result synchronously

`spin()` runs an immediate spin for a user and returns the full result.

## Usage

<CodeGroup>
  ```typescript TypeScript theme={null}
  const result = await nippy.spin({
    userId: 'user-123',
    campaignId: 'camp-abc',
    idempotencyKey: 'checkout-789'
  })
  ```

  ```bash curl theme={null}
  curl -X POST https://ms.nippy.la/v1/public/spins \
    -H "x-api-key: npk_live_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "userId": "user-123",
      "campaignId": "camp-abc",
      "idempotencyKey": "checkout-789"
    }'
  ```
</CodeGroup>

## Parameters

<ParamField body="userId" type="string" required>
  User identifier from your system. Example: `user-123`.
</ParamField>

<ParamField body="campaignId" type="string" required>
  Campaign ID. Example: `camp-abc`.
</ParamField>

<ParamField body="idempotencyKey" type="string" default="generated by the SDK">
  Key used to avoid duplicate spins during retries. Example: `checkout-789`.
</ParamField>

## Response

<ResponseField name="spinId" type="string">
  Unique spin ID.
</ResponseField>

<ResponseField name="outcome" type="string">
  Spin outcome. Common values: `won_points`, `lost`, `won_digital`, `won_physical`.
</ResponseField>

<ResponseField name="gift" type="object">
  Prize selected by the spin.
</ResponseField>

<ResponseField name="gift.giftId" type="string">
  Prize ID.
</ResponseField>

<ResponseField name="gift.name" type="string">
  Display name of the prize.
</ResponseField>

<ResponseField name="gift.pointsValue" type="number | null">
  Points awarded when `outcome` is `won_points`.
</ResponseField>

<ResponseField name="animation" type="object">
  Data for rendering a deterministic animation.
</ResponseField>

<ResponseField name="animation.seed" type="number">
  Seed used to reproduce the animation.
</ResponseField>

<ResponseField name="animation.durationMs" type="number">
  Recommended animation duration in milliseconds.
</ResponseField>

<ResponseField name="animation.targetAngle" type="number">
  Recommended target angle for the roulette.
</ResponseField>

<ResponseField name="inventory.remaining" type="number">
  Remaining prize stock. `-1` means unlimited inventory.
</ResponseField>

<ResponseField name="prizeReservation" type="object | null">
  Prize reservation when the result requires `claim()`.
</ResponseField>

<ResponseField name="prizeReservation.claimRequired" type="boolean">
  Whether you must call `claim()` to complete delivery.
</ResponseField>
