# Error Handling

The Fuul API uses standard HTTP status codes to indicate success or failure. The SDK catches API errors and throws typed error classes for common failure modes.

## HTTP status codes

| Status | Meaning                                              |
| ------ | ---------------------------------------------------- |
| `200`  | Success                                              |
| `400`  | Bad Request — invalid parameters or validation error |
| `401`  | Unauthorized — missing or invalid API key            |
| `403`  | Forbidden — API key lacks required permissions       |
| `404`  | Not Found                                            |
| `409`  | Conflict — duplicate resource                        |
| `429`  | Too Many Requests — rate limit exceeded              |
| `500`  | Server Error                                         |

## SDK error types

The SDK throws these typed errors for `createAffiliateCode`, `updateAffiliateCode`, and `updateRebateRate`. Each extends `Error` and sets a `.name` property. Note: `updateRebateRate` can throw `InvalidSignatureError` and `ValidationError` but not `AddressInUseError` or `CodeInUseError`.

| Error class             | `.name`                   | When thrown                                                                      |
| ----------------------- | ------------------------- | -------------------------------------------------------------------------------- |
| `ValidationError`       | `'ValidationError'`       | Invalid characters in the code. Has an `errors: string[]` property with details. |
| `InvalidSignatureError` | `'InvalidSignatureError'` | Signature doesn't match the address and message                                  |
| `AddressInUseError`     | `'AddressInUseError'`     | Address already has a code registered. Has an `address` property.                |
| `CodeInUseError`        | `'CodeInUseError'`        | Code is already taken. Has a `code` property.                                    |

These are exported from `@fuul/sdk` and can be used with `instanceof`:

```typescript
import { Fuul, CodeInUseError, AddressInUseError, ValidationError, InvalidSignatureError } from '@fuul/sdk';

try {
  await Fuul.createAffiliateCode({
    userIdentifier: '0x1234...',
    identifierType: 'evm_address',
    signature: '0xabc...',
    code: 'my-code',
  });
} catch (error) {
  if (error instanceof CodeInUseError) {
    // Code already taken — prompt the user to choose another
    console.log('Taken code:', error.code);
  } else if (error instanceof AddressInUseError) {
    // Address already has a code
    console.log('Address:', error.address);
  } else if (error instanceof ValidationError) {
    // Invalid code format
    console.log('Validation errors:', error.errors);
  } else if (error instanceof InvalidSignatureError) {
    // Signature verification failed
  } else {
    // Unexpected error
    console.error('Unexpected error:', error);
  }
}
```

{% hint style="info" %}
For API calls not related to affiliate codes, the SDK throws standard `Error` objects with the API error message.
{% endhint %}

## API key permissions reference

| Endpoint category                                | Required key type               |
| ------------------------------------------------ | ------------------------------- |
| Read data (leaderboards, rewards, conversions)   | Any key type                    |
| Send tracking events (pageview, connect\_wallet) | `send:tracking_event` or higher |
| Send trigger events (custom offchain events)     | `send:trigger_event`            |
| Manage audiences, webhooks, set referrers        | `service_role`                  |

For full details on key types, see [API Key Management](/developer-guide/api-key-management.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fuul.xyz/developer-guide/error-handling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
