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

# API Guidelines

> How to authenticate, handle rate limits, CORS, errors, and best practices when integrating with the Niftipay API.

# API Guidelines

This page describes the **recommended way to consume the Niftipay API** across server integrations, dashboards, and embedded widgets.

It covers:

* Authentication methods
* Required/request headers
* Rate limits and `429` handling
* CORS rules and allowed origins
* Common response & error patterns
* Integration best practices (timeouts, retries, idempotency, pagination)

***

## Base URL

All examples use:

* `https://www.niftipay.com`

***

# Authentication

You can authenticate using either:

## 1) API Key (recommended for integrations)

Send your API key in the `x-api-key` header:

```bash theme={null}
curl -X GET "https://www.niftipay.com/api/payment-methods" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

## 2) Session cookie (dashboard / browser)

If you are authenticated in the dashboard, requests are auhtorized..

> If you're building a backend integration (WooCommerce plugin, external servers, POS systems), use API keys.

> For IP allowlisting and key rotation, see [API Keys](/api/api-keys).

***

# Standard headers

## Request headers

Common headers you may send:

* `Accept: application/json`
* `Content-Type: application/json` (for JSON bodies)
* `x-api-key: ...` (API key auth)
* `Idempotency-Key: ...` or `x-idempotency-key: ...` (when supported by an endpoint)
* `x-publishable-key: ...` (for embeddable ramping widget flows)

> Not all endpoints use all headers; only send what the endpoint requires.

### CORS allowlist headers

The proxy middleware allows these request headers for CORS:

* `Content-Type`
* `Authorization`
* `x-api-key`
* `x-publishable-key`
* `x-public-key`
* `x-timestamp`
* `x-signature`

***

# Rate limits

Niftipay applies rate limiting at multiple layers.

## 1) Proxy-level enforcement for `/api/*`

All API routes are rate-limited by the proxy middleware:

If you exceed a limit, you’ll receive:

* `429 Too Many Requests`

### 429 handling (recommended)

When you receive a `429`:

1. **Back off** (exponential backoff recommended)
2. **Retry** after a delay
3. Avoid parallel bursts; queue requests

Example retry strategy:

* wait 1s → 2s → 4s → 8s (cap at 30s)
* retry up to 3–5 times max (depending on endpoint criticality)

> If you have high-volume needs, consolidate requests, cache responses, and avoid polling.

***

# Request/response conventions

## JSON responses

Most endpoints return JSON and use standard HTTP codes:

* `200` OK
* `201` Created
* `204` No Content (delete success)
* `400` Bad Request (invalid payload / missing params)
* `401` Unauthorized
* `403` Forbidden (method disabled, not allowed, failed guards)
* `404` Not Found
* `409` Conflict (duplicate reference, unsafe delete, etc.)
* `429` Too Many Requests
* `500` Internal Error
* `502` Upstream Error (provider/PSP failure)

## Error shape

Most error responses are shaped like:

```json theme={null}
{ "error": "Human readable message" }
```

Some endpoints also include:

```json theme={null}
{ "error": "Message", "details": { } }
```

> Treat `error` as display-safe text. Treat `details` as diagnostic.

***

# Pagination guidelines

Several list endpoints use **cursor pagination** (recommended for stable ordering).

Example (fiat orders):

* Response includes `nextCursor`
* Pass it back as `?cursor=<nextCursor>` to fetch older rows

Recommended:

* Keep `limit` between **20–50**
* Do not request `limit > 100` (clamped server-side)

***

# Idempotency and safe retries

Some endpoints support idempotent behavior when you provide a stable identifier (like `reference`) and/or an idempotency header.

Recommended approach:

1. Generate a **stable reference** for your business object (e.g. POS receipt number, WooCommerce order id).
2. Send it consistently on create calls.
3. If you must retry, reuse:
   * the same `reference`, and when supported
   * the same `Idempotency-Key`

This prevents accidental duplicates when:

* the client times out
* the network drops
* you retry after transient errors

***

# Timeouts & retries

## Recommended timeouts

* **Client timeout:** 10–20 seconds (PSP and blockchain calls can take longer, but order creation typically should not hang)
* **Webhook receivers:** respond in \< 2 seconds (providers often retry if slow)

## Retry guidance

Safe to retry:

* `GET` requests
* `DELETE` that is explicitly idempotent (returns same state if already deleted/cancelled)
* `POST` only if you have **idempotency** (reference/idempotency key) and the endpoint supports it

Avoid blind retries on:

* payment creation without idempotency protection
* refunds, cancellations, or wallet operations unless the endpoint is designed to be idempotent

***

# Webhooks and signatures

Niftipay supports webhooks for order state changes and refunds.

Best practices for webhook receivers:

* Always verify signatures (if enabled for your webhook)
* Respond quickly with `200`
* Treat events as **at-least-once** delivery:
  * you may receive duplicates
  * you must dedupe using event id / order reference / order id

If your webhook endpoint is down, the sender may retry.

> If you are using the default platform webhook (`/api/niftipay/webhook` on your domain), keep it publicly reachable and stable.

***

# Troubleshooting checklist

## Getting `401 Unauthorized`

* Missing/invalid `x-api-key`
* Using a browser without a valid session cookie

## Getting `403 Forbidden`

* Payment method category disabled (e.g. fiat/crypto not enabled)
* Test/protected or guarded route requirements not met
* CORS preflight rejected due to origin rules

## Getting `429 Too Many Requests`

* Slow down and retry with backoff
* Avoid request bursts
* Cache responses where possible

## Getting `502 Upstream Error`

* Provider/PSP failed (e.g. NoPayn/Tatum)
* Retry only if safe and idempotent (see above)
* Log `details` for debugging

***

# Example: minimal integration flow

1. Fetch payment methods:

```bash theme={null}
curl -X GET "https://www.niftipay.com/api/payment-methods" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: application/json"
```

2. Create a crypto or fiat order (depending on `enabled` methods)

3. Listen for webhook events (paid/cancelled/refunded) and update your system

***
