> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.athenaintel.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.athenaintel.com/_mcp/server.

# Read an uploaded or linked spreadsheet file's rows

GET https://api.athenaintel.com/api/v0/assets/{asset_id}/workbook

Read a spreadsheet file's contents as rows, every tab: an uploaded .xlsx, .xlsm, .xls, .csv, .tsv or Parquet file, or a linked file in SharePoint, Google Drive, OneDrive or iManage. Excel and Parquet cells keep their types; a CSV or TSV field that reads as a number becomes one. A sheet is read whole up to a safety ceiling, and a file over 40 MB is refused (413). A native Athena spreadsheet answers 409: its contents are the collaborative sheet, which the spreadsheet SDK opens directly. Nothing is written.

Reference: https://docs.athenaintel.com/api-reference/assets/get-workbook

## Authentication

- `X-API-KEY` header (required) — API Key authentication via header

## Request

### Path parameters

- `asset_id` (string, required) — The spreadsheet file asset to read

## Response

### 200

Successful Response

- `read_only` (true, required) — Always true: a file's contents are read here, never written.
- `sheets` (list of FileBackedSheetResponseOut, required) — Every tab of the file, in its order.

## Errors

### 404 Not Found Error

The asset does not exist, the caller may not read it, it is outside the workspace the caller acts in, or no file is stored for it

- `any`

### 409 Conflict Error

A native Athena spreadsheet: read it through its collaborative contents instead

- `any`

### 413 Content Too Large Error

The file is over the 40 MB this route reads

- `any`

### 415 Unsupported Media Type Error

Not a file type this route reads, or a linked file whose provider has no downloadable spreadsheet

- `any`

### 422 Unprocessable Entity Error

The asset is not a spreadsheet

- `any`

## Types

### FileBackedSheetResponseOut

One tab of a spreadsheet file, as rows of values.

- `name` (string, required) — The tab's name; for a CSV, TSV or Parquet file, the file's name without its extension.
- `rows` (list of list of any, required) — The tab's rows from its first row down, each a list of its cell values: numbers, strings, booleans, ISO dates, or null for an empty cell. A CSV or TSV field that reads as a number is one.

## Examples

**Response**

```json
{
  "read_only": true,
  "sheets": [
    {
      "name": "Sheet1",
      "rows": [
        [
          "Region",
          "Revenue"
        ],
        [
          "EMEA",
          1200
        ]
      ]
    }
  ]
}
```

**SDK Code**

```python
import requests

url = "https://api.athenaintel.com/api/v0/assets/asset_id/workbook"

headers = {"X-API-KEY": "<apiKey>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.athenaintel.com/api/v0/assets/asset_id/workbook';
const options = {method: 'GET', headers: {'X-API-KEY': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.athenaintel.com/api/v0/assets/asset_id/workbook"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("X-API-KEY", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.athenaintel.com/api/v0/assets/asset_id/workbook")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.athenaintel.com/api/v0/assets/asset_id/workbook")
  .header("X-API-KEY", "<apiKey>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.athenaintel.com/api/v0/assets/asset_id/workbook', [
  'headers' => [
    'X-API-KEY' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.athenaintel.com/api/v0/assets/asset_id/workbook");
var request = new RestRequest(Method.GET);
request.AddHeader("X-API-KEY", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["X-API-KEY": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.athenaintel.com/api/v0/assets/asset_id/workbook")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```