> ## 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()

> Ejecuta un giro inmediato y obtiene el resultado de forma síncrona

`spin()` ejecuta un giro inmediato para un usuario y devuelve el resultado completo.

## Uso

<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>

## Parámetros

<ParamField body="userId" type="string" required>
  Identificador del usuario en tu sistema. Ejemplo: `user-123`.
</ParamField>

<ParamField body="campaignId" type="string" required>
  ID de la campaña. Ejemplo: `camp-abc`.
</ParamField>

<ParamField body="idempotencyKey" type="string" default="generado por el SDK">
  Clave para evitar spins duplicados en reintentos. Ejemplo: `checkout-789`.
</ParamField>

## Respuesta

<ResponseField name="spinId" type="string">
  ID único del spin.
</ResponseField>

<ResponseField name="outcome" type="string">
  Resultado del giro. Valores comunes: `won_points`, `lost`, `won_digital`, `won_physical`.
</ResponseField>

<ResponseField name="gift" type="object">
  Premio seleccionado por el spin.
</ResponseField>

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

<ResponseField name="gift.name" type="string">
  Nombre visible del premio.
</ResponseField>

<ResponseField name="gift.pointsValue" type="number | null">
  Puntos otorgados cuando `outcome` es `won_points`.
</ResponseField>

<ResponseField name="animation" type="object">
  Datos para reproducir una animación determinística.
</ResponseField>

<ResponseField name="animation.seed" type="number">
  Semilla usada para reproducir la animación.
</ResponseField>

<ResponseField name="animation.durationMs" type="number">
  Duración recomendada de la animación en milisegundos.
</ResponseField>

<ResponseField name="animation.targetAngle" type="number">
  Ángulo final recomendado de la ruleta.
</ResponseField>

<ResponseField name="inventory.remaining" type="number">
  Stock restante del premio. `-1` indica inventario ilimitado.
</ResponseField>

<ResponseField name="prizeReservation" type="object | null">
  Reserva del premio cuando requiere `claim()`.
</ResponseField>

<ResponseField name="prizeReservation.claimRequired" type="boolean">
  Indica si debes llamar `claim()` para completar la entrega.
</ResponseField>
