Skip to main content

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.

The SDK throws NippyError instances for operational errors. Use NippyErrorCodes to handle each case explicitly.
Do not show internal error messages directly to users. Log error.code, error.status, and error.traceId for diagnostics.

Base pattern

import { NippyError, NippyErrorCodes } from '@nippy/sdk'

try {
  await nippy.spin({ userId, campaignId })
} catch (error) {
  if (!(error instanceof NippyError)) throw error

  console.error(error.code, error.message, error.traceId)
}

Error codes

Cause: The user spun recently and the campaign cooldown is still active.Fix: Call getState() and show nextEligibleAt.
if (error.code === NippyErrorCodes.COOLDOWN_ACTIVE) {
  const state = await nippy.getState({ userId, campaignId })
  return { reason: 'cooldown', nextEligibleAt: state.nextEligibleAt }
}
Cause: The user used all allowed spins for the campaign.Fix: Disable the spin action and show the current state.
if (error.code === NippyErrorCodes.SPIN_LIMIT_REACHED) {
  return { reason: 'spin_limit_reached' }
}
Cause: The campaignId does not exist, belongs to another business, or the campaign is inactive.Fix: Verify the campaign ID and status before exposing it in your app.
if (error.code === NippyErrorCodes.CAMPAIGN_NOT_FOUND) {
  return { reason: 'campaign_unavailable' }
}
Cause: claim() was called for a prize that was already claimed.Fix: Treat it as idempotent and show the already-claimed prize.
if (error.code === NippyErrorCodes.ALREADY_CLAIMED) {
  return { reason: 'already_claimed' }
}
Cause: The user did not claim the prize before the reservation expired.Fix: Inform the user that time ran out and call getState() again.
if (error.code === NippyErrorCodes.RESERVATION_EXPIRED) {
  const state = await nippy.getState({ userId, campaignId })
  return { reason: 'reservation_expired', state }
}
Cause: The API key is missing or invalid.Fix: Check NIPPY_API_KEY and confirm it uses the correct prefix.
if (error.code === NippyErrorCodes.UNAUTHORIZED) {
  logger.error('Invalid Nippy API key')
}
Cause: The API key does not have access to the requested resource.Fix: Check permissions and resource ownership in the console.
if (error.code === NippyErrorCodes.FORBIDDEN) {
  logger.error('Nippy key does not have access to this resource')
}
Cause: Required fields are missing or a value has the wrong format.Fix: Validate data before calling the SDK.
if (error.code === NippyErrorCodes.INVALID_PARAMETERS) {
  return { reason: 'invalid_request' }
}
Cause: Nippy returned a 5xx error after automatic retries.Fix: Log traceId, show a generic state, and retry later.
if (error.code === NippyErrorCodes.SERVER_ERROR) {
  logger.error('Nippy server error', { traceId: error.traceId })
  return { reason: 'temporary_error' }
}

NippyError properties

error.code      // string
error.message   // string
error.status    // number
error.traceId   // string | undefined