> 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.

# Convert an Excel asset to an Athena sheet

POST https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet
Content-Type: application/json

Convert an uploaded Excel (.xlsx) asset into an editable Athena sheet — the same conversion the Athena UI performs. By default a new sheet asset is created alongside the source Excel asset; pass run_async for large workbooks to get the sheet immediately and poll its athena_metadata.conversionStatus for completion. With in_place the uploaded file itself becomes the sheet and keeps its asset id (sheet_asset_id is excel_asset_id, and no second asset is created); poll that asset until its media_type is 'athena/spreadsheet', or until athena_metadata.sheet_upload_conversion.status is 'failed' or 'skipped'.

Reference: https://docs.athenaintel.com/api-reference/assets/convert-excel-to-sheet

## Authentication

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

## Request

### Body (application/json)

This endpoint expects a ConvertExcelToSheetRequestIn.

- `excel_asset_id` (string, required) — ID of the Excel (.xlsx) asset to convert into an Athena sheet
- `in_place` (boolean, optional, default: false) — Make the uploaded file itself the Athena sheet, keeping its asset id: sheet_asset_id is excel_asset_id and no second asset is created. Needs edit access to the upload, and takes an .xlsx/.xlsm/.xlsb workbook or a .csv/.tsv file. A password-protected workbook is refused (convert it into a new sheet with `password` instead), and the sheet is always on the rnc engine. Without run_async the request waits up to about 50 seconds for the conversion; conversion_status 'converting' means it is still running. Poll the asset until its media_type is 'athena/spreadsheet', or until athena_metadata.sheet_upload_conversion.status is 'failed' or 'skipped' (with its reason).
- `password` (string, optional, nullable) — Optional password used to decrypt a password-protected workbook. Password-protected workbooks convert on either engine (they are decrypted server-side before an rnc import).
- `run_async` (boolean, optional, default: false) — Return the sheet asset immediately and convert in the background. Large workbooks outlive the gateway's ~60s response window on the synchronous path — with run_async the caller polls athena_metadata.conversionStatus ('converting' | 'completed' | 'failed', with conversionError on failure) instead.
- `spreadsheet_engine` (string, optional, nullable) — Engine for the converted sheet ('rnc' | 'legacy'). Defaults to the deployment's default engine.

## Response

### 200

Excel asset converted successfully

- `asset_type` (string, required) — Type of the created sheet asset
- `excel_asset_id` (string, required) — ID of the source Excel asset
- `sheet_asset_id` (string, required) — ID of the Athena sheet: a new asset, or excel_asset_id itself for an in_place conversion
- `title` (string, required) — Title of the created sheet asset
- `conversion_status` (string, optional, nullable) — Conversion status for background (run_async) conversions: 'converting' immediately after the request. Poll the asset's athena_metadata.conversionStatus for 'completed' | 'failed'. Null for synchronous conversions, which have already completed. An in_place conversion still running answers 'converting' too; see in_place for how to poll it.
- `parent_folder_id` (string, optional, nullable) — ID of the sheet asset's parent folder
- `workspace_id` (string, optional, nullable) — ID of the workspace that owns the sheet asset

## Errors

### 400 Bad Request Error

Asset is not an Excel file or request invalid

- `map from string to any`

### 403 Forbidden Error

Caller lacks access to the source asset

- `message` (string, required)

### 404 Not Found Error

Source Excel asset not found

- `message` (string, required)

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

### 500 Internal Server Error

Conversion failed

- `map from string to any`

### 503 Service Unavailable Error

An in_place conversion could not be started; nothing was converted, so retry shortly

- `any`

## Types

### ValidationError

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)
- `ctx` (ValidationErrorCtx, optional)
- `input` (any, optional)

### ValidationErrorLocItems

- string
- integer

### ValidationErrorCtx

## Examples

**Request**

```json
{
  "excel_asset_id": "asset_92492920-d118-42d3-95b4-00eccfe0754f",
  "in_place": false,
  "run_async": false
}
```

**Response**

```json
{
  "asset_type": "spreadsheet",
  "excel_asset_id": "asset_92492920-d118-42d3-95b4-00eccfe0754f",
  "sheet_asset_id": "asset_12345678-d118-42d3-95b4-00eccfe0754f",
  "title": "Quarterly Report Q1 2024",
  "parent_folder_id": "asset_folder_12345",
  "workspace_id": "workspace_abc123"
}
```

**SDK Code**

```python
import requests

url = "https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet"

payload = {
    "excel_asset_id": "asset_92492920-d118-42d3-95b4-00eccfe0754f",
    "in_place": False,
    "run_async": False
}
headers = {
    "X-API-KEY": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet';
const options = {
  method: 'POST',
  headers: {'X-API-KEY': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"excel_asset_id":"asset_92492920-d118-42d3-95b4-00eccfe0754f","in_place":false,"run_async":false}'
};

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"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet"

	payload := strings.NewReader("{\n  \"excel_asset_id\": \"asset_92492920-d118-42d3-95b4-00eccfe0754f\",\n  \"in_place\": false,\n  \"run_async\": false\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-API-KEY", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	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/convert-excel-to-sheet")

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

request = Net::HTTP::Post.new(url)
request["X-API-KEY"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"excel_asset_id\": \"asset_92492920-d118-42d3-95b4-00eccfe0754f\",\n  \"in_place\": false,\n  \"run_async\": false\n}"

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.post("https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet")
  .header("X-API-KEY", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"excel_asset_id\": \"asset_92492920-d118-42d3-95b4-00eccfe0754f\",\n  \"in_place\": false,\n  \"run_async\": false\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet', [
  'body' => '{
  "excel_asset_id": "asset_92492920-d118-42d3-95b4-00eccfe0754f",
  "in_place": false,
  "run_async": false
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'X-API-KEY' => '<apiKey>',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-KEY", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"excel_asset_id\": \"asset_92492920-d118-42d3-95b4-00eccfe0754f\",\n  \"in_place\": false,\n  \"run_async\": false\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-API-KEY": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "excel_asset_id": "asset_92492920-d118-42d3-95b4-00eccfe0754f",
  "in_place": false,
  "run_async": false
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.athenaintel.com/api/v0/assets/convert-excel-to-sheet")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

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()
```