Documentation Index
Fetch the complete documentation index at: https://docs.ivory.finance/llms.txt
Use this file to discover all available pages before exploring further.
Extracts a specific table from a corporate disclosure filing HTML and exports it to your requested format.
Perfect for:
- Converting corporate disclosure tables to spreadsheets
- Automating financial data extraction
- Building data analysis pipelines
- Integrating with your apps
Request
URL to the corporate disclosure filing HTML (must be publicly accessible)Examples:
https://www.sec.gov/Archives/edgar/...
https://your-s3-bucket.s3.amazonaws.com/filing.html
Zero-indexed table number (0 = first table on page)
Output format: csv, xlsx, or json
Response
Returns file download (CSV/XLSX) or JSON data:
Comma-separated values file with column headers
Excel workbook with sheet named “SEC_Data”
Array of objects, one per row[
{ "Item": "Revenue", "2023": 1000000, "2022": 950000 },
{ "Item": "Expenses", "2023": 600000, "2022": 580000 }
]
Usage Example
const response = await fetch('https://api.ivory.finance/v1/tools/extract', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
s3_url: 'https://www.sec.gov/Archives/edgar/.../0000789019-23-000015.htm',
table_index: 0,
export_format: 'xlsx'
})
});
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'income_statement.xlsx';
a.click();
Inject export buttons directly on SEC filing pages:
// Inject this on pages with corporate disclosure tables
document.querySelectorAll('table').forEach((table, index) => {
const btnGroup = document.createElement('div');
btnGroup.innerHTML = `
<div class="extract-container"
style="position: absolute; right: 10px; top: 10px; z-index: 100; display: flex; gap: 5px;">
<button onclick="triggerExport(${index}, 'xlsx')"
title="Export as Excel"
style="background:#217346; color:white; border:none; cursor:pointer;
padding:8px 12px; border-radius:4px; font-weight:bold;">
XLSX
</button>
<button onclick="triggerExport(${index}, 'csv')"
title="Export as CSV"
style="background:#333; color:white; border:none; cursor:pointer;
padding:8px 12px; border-radius:4px; font-weight:bold;">
CSV
</button>
</div>
`;
table.style.position = 'relative';
table.prepend(btnGroup);
});
async function triggerExport(tableIndex, format) {
const s3Url = window.location.href; // or get from data attribute
try {
const response = await fetch('https://api.ivory.finance/v1/tools/extract', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
s3_url: s3Url,
table_index: tableIndex,
export_format: format
})
});
if (!response.ok) {
const error = await response.json();
alert('Error: ' + error.detail.message);
return;
}
const blob = await response.blob();
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `table_${tableIndex}.${format}`;
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(url);
} catch (error) {
alert('Export failed: ' + error.message);
}
}
3. Parse JSON Response
const response = await fetch('https://api.ivory.finance/v1/tools/extract', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
s3_url: 'https://www.sec.gov/Archives/edgar/.../form.htm',
table_index: 0,
export_format: 'json'
})
});
const tableData = await response.json();
console.log('Rows:', tableData.length);
console.log('First row:', tableData[0]);
Data Processing
Financial Value Normalization
The endpoint automatically normalizes financial values:
(1,234.00) → -1234.00 (accounting notation)
1,234.56 → 1234.56 (removes commas)
$5,000 → 5000.00 (removes currency)
- Labels remain as text
Corporate disclosures often have footnote references like (See Note 8). These are automatically stripped from cell values.
Empty Cell Handling
- Empty rows are removed
- Empty numeric cells default to
0.0
- Empty text cells are preserved
Errors
{
"detail": {
"error": "table_not_found",
"message": "Table 5 not found. Page has 3 tables.",
"details": { "available_tables": 3 }
}
}
{
"detail": {
"error": "empty_table",
"message": "Selected table is empty after extraction",
"details": null
}
}
{
"detail": {
"error": "fetch_failed",
"message": "Failed to fetch the filing. Check the URL is accessible.",
"details": "Connection timeout"
}
}
{
"detail": {
"error": "extraction_failed",
"message": "An unexpected error occurred during extraction",
"details": "HTML parsing error"
}
}
Best Practices
- Use Discover First - Call
/v1/tools/extract/discover to find available tables before extracting
- Handle Export Errors - Wrap the export in try/catch for network failures
- Show Loading State - Extraction can take a few seconds for large tables
- URL Validation - Ensure the filing URL is publicly accessible
- Format Selection - Use XLSX for Excel users, CSV for data analysis, JSON for APIs
Limits
- Maximum filing size: 50MB
- Request timeout: 30 seconds
- Maximum tables per page: 500
- No authentication required