# Errors

> Learn how the WinWinKit API returns errors and how to handle them in your code.

export const components = {
  pre: CodeSnippet,
};

When you send a request to the WinWinKit API, the response includes an HTTP status code and, in most cases, a response body. To determine your request's status and handle errors, use the HTTP status code along with the `code` from the error response. Interpret the error starting with the most general information first.

## Response HTTP Codes

WinWinKit uses standard HTTP codes to indicate the success or failure of your requests. In general, 2xx codes correspond to success, 4xx codes are for caller-related failures, and 5xx codes are for infrastructure issues.

| Status | Name | Description |
| :----- | :--- | :---------- |
| 200 | OK | Success. |
| 201 | Created | Object created. |
| 400 | Bad Request | Check that the request format was correct. |
| 401 | Unauthorized | The API key was missing or invalid. |
| 403 | Forbidden | The operation is not permitted. |
| 404 | Not Found | The resource was not found. |
| 422 | Unprocessable Entity | Check that the request data was correct. |
| 424 | Failed Dependency | A request to an external service (e.g. App Store Connect) failed. |
| 429 | Too Many Requests | The rate limit was exceeded. |
| 500 | Internal Server Error | Indicates an error with WinWinKit servers. |

## Error Response

The error body returned whenever the API request isn't successful. Contains an array of one or more errors.

```json
{
  "errors": [
    {
      "code": "<string>",
      "status": <number>,
      "message": "<string>",
      "source": "<string | null>"
    }
  ]
}
```

## Error Code

The `code` property is a stable, machine-readable value indicating the exact type of error. Codes are hierarchical — dots separate information from general to specific. The more the system knows about the error, the more levels the code includes.

| Status | Code | Description |
| :----- | :--- | :---------- |
| 400 | `BODY_INVALID` | The request body is the wrong type and is not valid JSON. |
| 401 | `UNAUTHORIZED` | The operation is not authorized due to missing or invalid API key. |
| 403 | `FORBIDDEN.CODE_INACTIVE` | The code cannot be claimed because it is not active. Applies to affiliate codes that haven't been accepted yet, and to inactive promo codes. |
| 403 | `FORBIDDEN.CODE_LIMIT_REACHED` | The code cannot be claimed because its limit has been reached. |
| 403 | `FORBIDDEN.OPERATION_DUPLICATE` | The operation is not allowed to be performed again. Applies to grant a reward and withdraw credits when a previously used `operation_id` is provided. |
| 403 | `FORBIDDEN.USER_ALREADY_CLAIMED_CODE` | The user has already claimed a code. |
| 403 | `FORBIDDEN.USER_CANNOT_CLAIM_OWN_CODE` | The user cannot claim their own referral code. |
| 403 | `FORBIDDEN.USER_NOT_ELIGIBLE_DUE_TO_TIME_CONSTRAINTS` | The user is not eligible to claim a code due to time constraints. By default the user can claim a code within 7 days of their first seen at or creation date. |
| 404 | `NOT_FOUND.CODE` | The code does not exist. |
| 404 | `NOT_FOUND.REWARD` | The reward does not exist. |
| 404 | `NOT_FOUND.USER` | The user does not exist. |
| 404 | `PATH_ERROR` | The path is not valid. For example, `GET https://api.winwinkit.com/lol` is not a valid path. |
| 422 | `PARAMETER_ERROR.INVALID` | The parameter is allowed but has an invalid value or type. The name of the invalid parameter is in the `source` field. |
| 422 | `PARAMETER_ERROR.REQUIRED` | A required parameter is missing. The name of the missing parameter is in the `source` field. |
| 429 | `TOO_MANY_REQUESTS` | Too many requests. |
| 500 | `INTERNAL_SERVER_ERROR` | Indicates an error with WinWinKit servers. |

## Examples

### Unauthorized

Returned when the API key is missing or invalid:

```json
{
  "errors": [
    {
      "code": "UNAUTHORIZED",
      "status": 401,
      "message": "Invalid API Key",
      "source": null
    }
  ]
}
```

### Claiming Own Code

Returned when a user tries to claim their own code:

```json
{
  "errors": [
    {
      "code": "FORBIDDEN.USER_CANNOT_CLAIM_OWN_CODE",
      "status": 403,
      "message": "User Cannot Claim Own Code",
      "source": null
    }
  ]
}
```

### Claiming Code Again

Returned when a user has already claimed a code and attempts to claim again:

```json
{
  "errors": [
    {
      "code": "FORBIDDEN.USER_ALREADY_CLAIMED_CODE",
      "status": 403,
      "message": "User Already Claimed Code",
      "source": null
    }
  ]
}
```

### Code Not Found

Returned when trying to claim a non-existing code:

```json
{
  "errors": [
    {
      "code": "NOT_FOUND.CODE",
      "status": 404,
      "message": "Code Not Found",
      "source": null
    }
  ]
}
```

### User Not Found

Returned when attempting any operation (e.g. fetch or claim code) on a non-existing user:

```json
{
  "errors": [
    {
      "code": "NOT_FOUND.USER",
      "status": 404,
      "message": "User Not Found",
      "source": null
    }
  ]
}
```

### Reward Not Found

Returned when attempting to withdraw credits on a non-existing reward:

```json
{
  "errors": [
    {
      "code": "NOT_FOUND.REWARD",
      "status": 404,
      "message": "Reward Not Found",
      "source": null
    }
  ]
}
```

### Missing Parameter

Returned when a required parameter named `code` is missing:

```json
{
  "errors": [
    {
      "code": "PARAMETER_ERROR.REQUIRED",
      "status": 422,
      "message": "Required",
      "source": "code"
    }
  ]
}
```

<Tip>
  When a required parameter is missing, the error object includes the name of
  the parameter in the `source` field.
</Tip>

### Invalid Parameter

Returned when a parameter named `is_trial` is invalid:

```json
{
  "errors": [
    {
      "code": "PARAMETER_ERROR.INVALID",
      "status": 422,
      "message": "Must be a boolean",
      "source": "is_trial"
    }
  ]
}
```

<Tip>
  When a parameter is invalid, the error object includes a descriptive
  `message` and the name of the parameter in `source`.
</Tip>
