> Source: https://ashareapi.com/en/wiki/envelope/  ·  Markdown version for LLMs / AI agents

Reference

# Response envelope
 Every endpoint wraps its result in the same six outer fields, and the payload itself lives in data, which comes in more than one shape. Some errors (missing parameter, over the limit, a paid endpoint without a key) use a different structure — do not parse those as the envelope.

## What it looks like

 Except for `/v1/health`, every successful response has these six outer fields:

```
{
 "ok": true,
 "endpoint": "kline",
 "tier": "free",
 "elapsed_ms": 701,
 "source": "multi",
 "data": [ "…the actual data is here…" ]
}
```
 
 | 

| 
 | Field 
 | Type 
 | Meaning 




 

| 
 | `ok` 
 | boolean 
 | Whether data was retrieved. **Check this before reading data** 



| 
 | `endpoint` 
 | string 
 | Endpoint name (e.g. `kline`, `quote`) 



| 
 | `tier` 
 | string 
 | **The tier this request was served at** (`free` for anonymous calls; the key’s tier when a key is used) 



| 
 | `elapsed_ms` 
 | number 
 | Server-side latency in milliseconds 



| 
 | `source` 
 | string 
 | Data-source label 



| 
 | `data` 
 | depends on endpoint 
 | The actual payload 







## The shapes `data` can take

 `data` differs by endpoint, so check the type before reading it:

 
 | 

| 
 | Shape 
 | Appears on 
 | How to read it 




 

| 
 | **Array** (one row per element) 
 | `kline`, `quote`, `hot` … 
 | `data[0]`, then a field, e.g. `data[0].last` 



| 
 | **Object** 
 | single-record endpoints 
 | read fields directly 



| 
 | **Pre-rendered text** (a string) 
 | `market-overview`, `changedist` … 
 | `structured` / `tables` are added alongside; use those for programmatic access 



| 
 | **Multi-segment** 
 | endpoints that return several tables at once 
 | pick segments out of `tables` 






 For text endpoints: `data` is a block of markdown, and two **extra** fields appear — `structured` is the first table (`[{column: value}]`) and `tables` is every table. `data` itself is **unchanged**: text clients keep using `data`, programmatic clients use `structured`.


## Can you trust `source`?

 `source` is a data-source label. **You may look at it, but do not branch on it in business logic** — its value is not guaranteed to be stable, and it does not identify any particular upstream.


## What a failure looks like

 `ok: false` means no data was retrieved this time (`data` may be empty or absent). Two things to note:

 

- The HTTP status is **still 200** (the envelope is the body);


- Check `ok` first, then decide whether to use `data`.




## Responses that are **not** the envelope

 These do **not** use the structure above — do not parse them as the envelope:

 
 | 

| 
 | Situation 
 | HTTP 
 | What comes back 




 

| 
 | Missing required parameter (e.g. no `code`) 
 | 422 
 | `{"detail": [{"loc": ["query", "code"], "msg": "Field required", "input": null}]}` 



| 
 | Paid endpoint called anonymously 
 | 401 
 | `{"error": "需要 API Key（此端点属付费层）", "docs": "/docs"}` 



| 
 | Anonymous rate limit exceeded 
 | 429 
 | `{"error": "匿名限流 …", "pow": { … }, "how_to": "…"}` 






 The common trait: **no ok field** — the top level is `error` or `detail`. A robust client should therefore **check the HTTP status first, then check for ok**. Other error codes are listed under [Errors and rate limits](/en/docs/errors).


## `/v1/health` is the exception

 `/v1/health` returns no `data`; it returns service status:

```
{ "ok": true, "uptime_s": 123456, "data_ready": true, "tiers": ["free", "pro"] }
```
 `data_ready: true` means the data channel is available.


 Last updated: 2026-10-05
 Field meanings and failure semantics taken from live responses and the endpoint definitions on 2026-10-05; error shapes measured against free endpoints such as /v1/kline.

 Read next

-
[Errors and rate limits](/en/docs/errors)

-
[Full endpoint list](/en/endpoints)

 [← All wiki pages](/en/wiki)
