> ## Documentation Index
> Fetch the complete documentation index at: https://psxdata.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduction

> Base URL, rate limits, error format, and authentication for the psxdata REST API.

## Base URL

All API requests are made to the following base URL:

```text theme={null}
https://psxdata-api.fastapicloud.dev
```

## Authentication

No authentication is required. All endpoints are public and can be called directly without API keys or tokens.

## Rate limits

Requests are rate-limited to **60 requests per minute per IP address** across all endpoints. The limit is enforced by [slowapi](https://github.com/laurentS/slowapi) using the client's remote IP address.

When the limit is exceeded the API returns HTTP `429` with the `rate_limited` error code (see [Error codes](#error-codes) below).

### Using the API in a multi-user app

The 60 req/min limit is keyed on the **remote IP address that reaches the API**, not on individual end users. This matters when you build a frontend (Next.js, React, mobile app) on top of psxdata:

* **Calling the API directly from the browser** — every user calls from their own IP, so each user has their own 60 req/min budget. In local development, though, every request comes from your single machine and shares one budget, so you will hit `429` quickly while testing.
* **Calling the API from your backend** (Next.js API route, `getServerSideProps`, a serverless function, or any server you own) — every request comes from the same server IP, so **all of your users share one 60 req/min budget**. This will fail under real traffic unless you cache.

For any production, multi-user app the recommended pattern is:

1. Call psxdata from your backend, not the browser.
2. Cache the response on your side (in-memory, Redis, or a database). Historical prices never change; intraday data on psxdata refreshes every 15 minutes, so a 15-minute TTL on quotes and index snapshots is a safe default.
3. Serve subsequent user requests from your cache, and refresh in the background.

One cached fetch on your backend can serve thousands of end users without hitting the limit.

If you also need to work with the data in Python — for example to run analytics or backtests — the [psxdata Python SDK](/sdk/getting-started) talks to PSX directly and caches to disk, so it is not affected by the REST API rate limit.

## Response format

Every response — success or error — is a JSON object with a single top-level key.

### Success response (single object)

```json theme={null}
{
  "data": { "...": "..." },
  "meta": {
    "timestamp": "2025-01-15T10:30:00+00:00",
    "cached": false
  }
}
```

### Success response (list)

```json theme={null}
{
  "data": ["..."],
  "meta": {
    "timestamp": "2025-01-15T10:30:00+00:00",
    "cached": false,
    "count": 100
  }
}
```

| Field            | Type            | Description                                               |
| ---------------- | --------------- | --------------------------------------------------------- |
| `data`           | object or array | The requested resource(s).                                |
| `meta.timestamp` | ISO 8601 string | Server time at which the response was generated.          |
| `meta.cached`    | boolean         | Whether the response was served from cache.               |
| `meta.count`     | integer         | Number of items returned. Present on list responses only. |

### Error response

```json theme={null}
{
  "error": {
    "status": 429,
    "code": "rate_limited",
    "message": "Rate limit exceeded"
  }
}
```

| Field           | Type    | Description                              |
| --------------- | ------- | ---------------------------------------- |
| `error.status`  | integer | Mirrors the HTTP status code.            |
| `error.code`    | string  | Machine-readable error identifier.       |
| `error.message` | string  | Human-readable description of the error. |

## Error codes

| HTTP status | `error.code`      | When it occurs                                                       |
| ----------- | ----------------- | -------------------------------------------------------------------- |
| `400`       | `bad_request`     | Invalid query parameters or request body.                            |
| `404`       | `not_found`       | Symbol or resource not found.                                        |
| `422`       | `bad_request`     | Request validation failed (e.g. missing required field, wrong type). |
| `429`       | `rate_limited`    | 60 requests per minute per IP exceeded.                              |
| `503`       | `psx_unavailable` | The PSX website was unreachable when the request was processed.      |
| `500`       | `internal_error`  | Unexpected server error.                                             |

## Quick example

Fetch the market summary with a single `curl` call:

```bash theme={null}
curl -s https://psxdata-api.fastapicloud.dev/market/summary
```

A successful response looks like:

```json theme={null}
{
  "data": {
    "kse100": 115432.67,
    "kse30": 36210.45,
    "kmiallshare": 82140.12
  },
  "meta": {
    "timestamp": "2025-01-15T10:30:00+00:00",
    "cached": false
  }
}
```

Ready to build something? Continue with the [quickstart guide](/rest-api/guides/quickstart).
