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

Reference

# Response shapes
 The payload in data comes in four different shapes — row arrays, table lists, pre-rendered text and multi-segment structures. Check the type before reading it, or you will index into a string where you should read a field, or the reverse.

## The four shapes

 `data` is not one thing. Check what type it is before deciding how to read it:

 
 | 

| 
 | Shape 
 | Type of `data` 
 | How to read it 




 

| 
 | **Row array** 
 | array, one item per row 
 | `data[0].field`; more rows are `data[0]` → `data[n]` 



| 
 | **Table list** 
 | array of arrays, one item per table 
 | `data[0]` is the first table, `data[0][0]` is its first row 



| 
 | **Pre-rendered text** 
 | string (markdown) 
 | use `data` for display; use the extra `structured` / `tables` for programmatic access 



| 
 | **Multi-segment structure** 
 | object containing `tables` 
 | read segments from `data.tables`; each has `title` / `slug` / `rows` 






 A one-line rule: **look at whether the first character is [ , { or "**.


## Which of the 33 endpoints uses which shape

 
 | 

| 
 | Shape 
 | Endpoints 




 

| 
 | **Row array** 
 | `quote` · `kline` · `minute` · `hot` · `technical` · `chip` · `profile` · `search` · `ipo` · `dividend` · `block-trade` · `margin-trade` · `orderbook` · `snapshot` 



| 
 | **Table list** 
 | `finance` 



| 
 | **Pre-rendered text** 
 | `market-overview` · `changedist` · `events` · `lhb` · `sector` · `sector-valuation` · `macro` · `bond` · `etf` · `dehydrated` · `screen` 



| 
 | **Multi-segment structure** 
 | `shareholder` · `calendar` 



| 
 | **Object (neither array nor text)** 
 | `fund` · `industry-chain` 



| 
 | **Special cases** 
 | `health` (no `data`) · `usage` (plain text, not JSON) · `challenge` (returns the challenge itself) 







## The ones that trip people up

 **orderbook and snapshot are row arrays too**, just always exactly **one row**. The design keeps everything a row array so clients do not need a special case for single-object endpoints — read `data[0].field` and you are right.

 ⚠️ The table above is the shape for a **single code**. **Sending several codes changes the shape** — `quote` / `technical` / `profile` add a code column, while `chip` becomes a **wide table with prefixed column names** (the row count does not double). See [Batch fetching](/en/wiki/batch-fetch) for details.

 **finance is a table list, not a multi-segment structure.** `data[0]` / `data[1]` / `data[2]` are the income statement / balance sheet / cash-flow statement — the **order is fixed**. To address them by name, see the next section.

 **shareholder and calendar are multi-segment structures.** `data.tables` is an ordered list of tables. ⚠️ **Do not pick shareholder segments by index** — A-shares and Hong Kong both have 3 segments, but they mean completely different things (A-shares: top-ten holders / top-ten float holders / holder-count stats; Hong Kong: shareholders / distribution / institutional holdings). Address them by `slug`.

 **fund is a genuine object** (not text): read `data.main_net`, `data.main_rank` and so on directly.


## How to read text endpoints programmatically

 For text endpoints, `data` is human-readable markdown, but two **extra** fields appear alongside:

 
 | 

| 
 | Field 
 | What it is 




 

| 
 | `structured` 
 | **The first table**, as `[{column: value}]` 



| 
 | `tables` 
 | **Every table**, as `[[{column: value}], ...]` 






 `data` itself is **unchanged** — text clients keep using `data`, programmatic clients use `structured` / `tables`. For multi-segment output (such as `calendar` or `macro`), only `tables` gets you everything.

 `structured` gives you just the first table, so **use it when one table is all you need** (e.g. the `screen` result); **when there are several segments, always use tables**.


## Common misuses

 

- **Treating a text endpoint as an array** — for `market-overview`, `sector` and friends `data` is a string, so `data[0]` is the **first character**, not the first row.


- **Treating a row array as an object** — `quote`’s `data` is an array; `data.last` finds nothing, you need `data[0].last`.


- **Addressing finance by name** — it is an **order-fixed table list** with no slugs; addressing by name gets you the wrong table.


- **Picking shareholder segments by index** — A-shares and Hong Kong have the same segment count but different meanings; always use `slug`.


- **Forgetting structured holds only the first table** — reading only it silently drops every later segment.




 Last updated: 2026-10-07
 Shapes measured endpoint by endpoint on 2026-10-07 by calling the data layer directly and printing each return type and key set; the extra structured / tables fields for text endpoints come from the server-side injection logic.

 Read next

-
[Response envelope](/en/wiki/envelope)

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

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