---
title: "Errors"
description: "Complete error reference, status codes, and defensive client patterns for the Papers API."
canonical_url: "https://www.scholarxiv.com/developers/docs/papers-api/errors"
markdown_url: "https://www.scholarxiv.com/developers/docs/papers-api/errors.md"
---

# Errors
URL: /developers/docs/papers-api/errors
LLM index: /llms.txt
Description: Complete error reference, status codes, and defensive client patterns for the Papers API.

# Errors

All errors are returned as JSON:

```json title="error.json"
{ "error": "Missing search query" }
```

## Status Codes

| Status | Message                                            | How to Fix |
|--------|----------------------------------------------------|------------|
| 400    | `Missing search query`                             | Provide a non-empty `q` for simple GET search |
| 400    | `Missing advanced search filters`                  | `searchFilterString` must contain at least one non-empty string value |
| 401    | `API Key is required`                              | Send `Authorization: Bearer sxv_...` or `x-api-key: sxv_...` |
| 401    | `Invalid API key format. Should start with 'sxv_'` | Use a real ScholarXIV key |
| 401    | `Invalid API key`                                  | Key was revoked, expired, or does not exist |
| 429    | `Rate limit exceeded`                              | You hit the shared hourly limit for your plan. Respect `Retry-After` |

> [!WARNING]
> Always send valid JSON on POST requests. Malformed bodies return generic parse errors.

## Handling Rate Limits (429)

Rate limits are per-user and shared. When you receive 429:

- Read the `Retry-After` header (seconds).
- Back off and retry after that time.
- Consider spreading work or upgrading your plan for sustained high volume.

See the [Code Examples](/developers/docs/papers-api/examples) page for a complete retry helper and client handling patterns.

## Defensive Client Pattern

```ts title="client.ts"
import axios from 'axios';

export async function searchPapers(filters: Record<string, string>, limit = 20) {
  const active = Object.fromEntries(
    Object.entries(filters).filter(([, v]) => typeof v === 'string' && v.trim())
  );

  if (Object.keys(active).length === 0) {
    throw new Error('Provide at least one search filter');
  }

  try {
    const { data } = await axios.post(
      'https://scholarxiv.com/api/v1/papers/search',
      { searchFilterString: active, limit },
      {
        headers: {
          Authorization: `Bearer ${process.env.SCHOLARXIV_API_KEY}`,
          'Content-Type': 'application/json'
        }
      }
    );
    return data;
  } catch (err: any) {
    const message = axios.isAxiosError(err)
      ? err.response?.data?.error ?? err.message
      : err.message;
    throw new Error(`Papers API error: ${message}`);
  }
}
```

## Troubleshooting Checklist

1. Key starts with `sxv_` and is passed in the correct header.
2. For simple search: `q` is present and not empty.
3. For advanced search: at least one value inside `searchFilterString` is non-empty.
4. `limit` is between 1 and 100.
5. On 429: check your current plan and usage in the dashboard. Wait or upgrade.
6. Pagination: always use the `nextPage` value from the previous response.

> [!TIP]
> Add request IDs or correlation IDs in your own wrapper logs. Never log the full API key. For failed authentication attempts you can safely log the key **prefix** (e.g. `sxv_abc123...`) — this is exactly what the Usage page shows for debugging.

**Common beginner mistakes**
- Forgetting the `Bearer ` prefix.
- Sending an empty `searchFilterString` object on POST.
- Assuming the next page exists without checking `hasMore` / `nextPage`.
- Treating 429 as a permanent failure instead of a temporary quota signal.

**Example: Logging safe key prefix on error**

```ts
const key = extractApiKey(req);
const prefix = key ? key.slice(0, 10) : 'none';
console.error(`Auth failed for key prefix ${prefix}`);
```

## Still Stuck?

- Use the **Playground** in the dashboard — it shows the exact request and error the server received.
- Check the live **Usage** page for current consumption against your plan.
- Review the [Paper fields](/developers/docs/papers-api#paper-object) in the overview.
- See [Rate Limits & Quotas](/developers/docs/papers-api/limits) for plan changes and entitlements.
- See [Code Examples](/developers/docs/papers-api/examples) for all code samples and the production checklist.
- Review the [Dashboard guide](/developers/docs/dashboard) for key and limit management.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
Docs-scoped sitemap: [/docs/sitemap.md](/docs/sitemap.md).
Well-known sitemap: [/.well-known/sitemap.md](/.well-known/sitemap.md).
