Skip to main content

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.

Extract Table from Corporate Disclosure

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

s3_url
string
required
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
table_index
integer
required
Zero-indexed table number (0 = first table on page)
export_format
string
required
Output format: csv, xlsx, or json

Response

Returns file download (CSV/XLSX) or JSON data:
csv
file
Comma-separated values file with column headers
xlsx
file
Excel workbook with sheet named “SEC_Data”
json
array
Array of objects, one per row
[
  { "Item": "Revenue", "2023": 1000000, "2022": 950000 },
  { "Item": "Expenses", "2023": 600000, "2022": 580000 }
]

Usage Example

1. Basic Extraction

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

2. Extract Icon Injector (Frontend Integration)

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.561234.56 (removes commas)
  • $5,0005000.00 (removes currency)
  • Labels remain as text

Footnote Removal

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

404 - Table Not Found
{
  "detail": {
    "error": "table_not_found",
    "message": "Table 5 not found. Page has 3 tables.",
    "details": { "available_tables": 3 }
  }
}
400 - Empty Table
{
  "detail": {
    "error": "empty_table",
    "message": "Selected table is empty after extraction",
    "details": null
  }
}
503 - Fetch Failed
{
  "detail": {
    "error": "fetch_failed",
    "message": "Failed to fetch the filing. Check the URL is accessible.",
    "details": "Connection timeout"
  }
}
500 - Processing Error
{
  "detail": {
    "error": "extraction_failed",
    "message": "An unexpected error occurred during extraction",
    "details": "HTML parsing error"
  }
}

Best Practices

  1. Use Discover First - Call /v1/tools/extract/discover to find available tables before extracting
  2. Handle Export Errors - Wrap the export in try/catch for network failures
  3. Show Loading State - Extraction can take a few seconds for large tables
  4. URL Validation - Ensure the filing URL is publicly accessible
  5. 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