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.

What are smart blocks?

Smart blocks are special Tiptap node types that carry live financial data inside their attrs object. Instead of static text, they embed SEC filing excerpts, market metrics, AI analysis, SQL results, interactive charts, comps tables, valuation models, and 30+ other financial artifact types directly into a document. Every smart block shares this base shape:
{
  "type": "<block_type>",
  "attrs": {
    "block_id":    "550e8400-e29b-41d4-a716-446655440000",
    "status":      "loaded",
    "error":       null,
    "resolved_at": "2026-03-18T12:00:00Z",
    "... type-specific fields ..."
  }
}
FieldValuesDescription
block_idUUIDStable identifier for this block instance
statuspending | loading | loaded | errorResolver lifecycle state
errorstring | nullError message when status == "error"

Block lifecycle

Resolve  →  Save  →  Insert into editor  →  (optionally) Pin to dashboard
Blocks are ephemeral by default — the resolver returns them and you insert them into the editor. Call /blocks/save immediately after resolving to make a block persistent (survives navigation and session loss).
// Full flow: resolve → save → insert → (optional) pin
const BASE = "https://api.ivory.finance";
const HEADERS = {
  "X-API-Key": IVORY_API_KEY,
  "Authorization": `Bearer ${IVORY_JWT}`,
  "Content-Type": "application/json",
};

// 1. Resolve
const { block } = await fetch(`${BASE}/v1/editor/blocks/resolve/ivory_chart`, {
  method: "POST",
  headers: HEADERS,
  body: JSON.stringify(chartSpec),
}).then(r => r.json());

// 2. Save (stable DB row)
const saved = await fetch(`${BASE}/v1/editor/blocks/save`, {
  method: "POST",
  headers: HEADERS,
  body: JSON.stringify({ block, source: "chat", label: "AAPL Revenue Chart" }),
}).then(r => r.json());

// 3. Insert into Tiptap editor
editor.chain().insertContent(block).run();

// 4. (optional) Pin to dashboard
await fetch(`${BASE}/v1/editor/blocks/${saved.id}/pin`, {
  method: "POST",
  headers: HEADERS,
  body: JSON.stringify({ dashboard: "main", position: 0 }),
});

Block persistence endpoints

All persistence endpoints require X-API-Key and Authorization: Bearer <jwt>.

Save a block

FieldRequiredDefaultDescription
blockThe full block dict returned by any /resolve/* endpoint
sourceNo"chat"Where the block was generated: "chat" | "editor" | "api"
doc_idNonullDocument UUID the block was generated for
labelNoAuto-derivedHuman-readable label (falls back to attrs.title or attrs.company_name)
curl -X POST https://api.ivory.finance/v1/editor/blocks/save \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "block":   { "type": "ivory_chart", "attrs": { "block_id": "...", "status": "loaded" } },
    "source":  "chat",
    "doc_id":  "doc_01JK4...",
    "label":   "AAPL Revenue Chart"
  }'
{
  "id":         "a1b2c3d4-...",
  "block_type": "ivory_chart",
  "source":     "chat",
  "created_at": "2026-03-22T09:00:00Z",
  "block":      { "type": "ivory_chart", "attrs": { "block_id": "...", "status": "loaded" } }
}

List saved blocks

Query paramDefaultDescription
block_type(all)Filter to a specific type, e.g. ivory_chart, comps_table
source(all)chat | editor | api
limit50Max 100 per page
offset0Pagination offset
curl "https://api.ivory.finance/v1/editor/blocks?block_type=ivory_chart&source=chat&limit=20" \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT"
{
  "blocks": [
    {
      "id":         "a1b2c3d4-...",
      "block_type": "ivory_chart",
      "label":      "AAPL Revenue Chart",
      "source":     "chat",
      "doc_id":     "doc_01JK4...",
      "created_at": "2026-03-22T09:00:00Z",
      "attrs":      { "block_id": "...", "status": "loaded" }
    }
  ],
  "limit":  20,
  "offset": 0
}

Copy a block

Duplicates a saved block — creates a new DB row and a new block_id inside attrs. The original is unchanged.
curl -X POST \
  "https://api.ivory.finance/v1/editor/blocks/a1b2c3d4-.../copy?label=AAPL+chart+copy" \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT"
{
  "id":         "e5f6g7h8-...",
  "block_type": "ivory_chart",
  "created_at": "2026-03-22T09:05:00Z",
  "block": {
    "type": "ivory_chart",
    "attrs": { "block_id": "new-uuid-...", "status": "loaded" }
  }
}

Pin a block to the dashboard

Idempotent — calling again updates position. Supports multiple named dashboards via the dashboard field.
curl -X POST "https://api.ivory.finance/v1/editor/blocks/a1b2c3d4-.../pin" \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT" \
  -H "Content-Type: application/json" \
  -d '{ "dashboard": "main", "position": 0 }'
{
  "pin_id":    "p1q2r3s4-...",
  "block_id":  "a1b2c3d4-...",
  "dashboard": "main",
  "position":  0,
  "pinned_at": "2026-03-22T09:10:00Z"
}

Get dashboard pins

Returns all pinned blocks for a dashboard ordered by position then pinned_at. Full attrs included — no second fetch needed to render.
curl "https://api.ivory.finance/v1/editor/blocks/pinned?dashboard=main" \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT"
{
  "dashboard": "main",
  "pins": [
    {
      "pin_id":     "p1q2r3s4-...",
      "position":   0,
      "pinned_at":  "2026-03-22T09:10:00Z",
      "block_id":   "a1b2c3d4-...",
      "block_type": "ivory_chart",
      "label":      "AAPL Revenue Chart",
      "source":     "chat",
      "attrs":      { "block_id": "...", "status": "loaded", "plotly_spec": { "data": [], "layout": {} } }
    }
  ]
}

Unpin a block

curl -X DELETE \
  "https://api.ivory.finance/v1/editor/blocks/a1b2c3d4-.../pin?dashboard=main" \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT"
{ "unpinned": true, "block_id": "a1b2c3d4-...", "dashboard": "main" }

Delete a saved block

Soft-deletes the block. Pins cascade-delete automatically — no need to unpin first.
curl -X DELETE "https://api.ivory.finance/v1/editor/blocks/a1b2c3d4-..." \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT"

Get all block schemas

Returns the full attrs schema for all 30+ block types — no auth required. Use this to generate TypeScript types.
curl https://api.ivory.finance/v1/editor/blocks/schemas

Block type resolvers

To auto-write a block into a document in one call, pass doc_id in the request body with an Authorization: Bearer <jwt> header. The resolver appends the block to doc_ast automatically.
Performs a KNN semantic search within a specific SEC filing and returns the top matching chunks as an inline citation.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/sec_citation \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "accession_number": "0000320193-25-000001",
    "query": "revenue growth cloud services",
    "chunk_limit": 5,
    "doc_id": "doc_01JK4..."
  }'
FieldRequiredDefaultDescription
accession_numberSEC filing accession number
querySemantic search query
chunk_limitNo5Max excerpts to include (1–10)
doc_idNonullAuto-append block to this document
{
  "block": {
    "type": "sec_citation",
    "attrs": {
      "block_id":         "550e8400-...",
      "status":           "loaded",
      "accession_number": "0000320193-25-000001",
      "cik":              "0000320193",
      "company_name":     "APPLE INC",
      "form_type":        "10-K",
      "filed_date":       "2025-11-01",
      "period_end":       "2025-09-27",
      "query":            "revenue growth cloud services",
      "excerpts": [
        {
          "text":    "Services net sales increased 14% to $96.2 billion...",
          "heading": "Results of Operations",
          "score":   0.9412
        }
      ],
      "filing_url":   "https://www.sec.gov/Archives/...",
      "markdown_url": "https://s3.presigned.url/...",
      "resolved_at":  "2026-03-18T12:00:00Z"
    }
  },
  "written_to_document": "Block appended to document doc_01JK4..."
}
Fetches the most recent income statement, balance sheet, and EPS figures from the Ivory database. Provide either cik or ticker.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/market_data \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "ticker": "AAPL",
    "metrics": ["revenue_ttm_usd_millions", "net_margin", "eps_ttm"]
  }'

Available metrics

KeyDescription
revenue_ttm_usd_millionsTrailing-12-month revenue ($ millions)
net_income_ttm_usd_millionsNet income TTM
total_assets_usd_millionsTotal assets
total_liabilities_usd_millionsTotal liabilities
cash_and_equivalents_usd_millionsCash and equivalents
operating_income_ttm_usd_millionsOperating income TTM
eps_ttmBasic EPS TTM
net_marginNet margin %
Calls the LLM with a prompt and optional document context. Auth required.If doc_id is provided, the document’s text is automatically used as context. Pass context_text to override.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/ai_insight \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Summarise the key risks and rate them by severity",
    "doc_id": "doc_01JK4...",
    "llm_provider": "bedrock",
    "max_tokens": 800
  }'
Executes a read-only SELECT query. Write operations are rejected with 422. Max 200 rows. Auth required.Query failures return an error block (not 500) so the document can display the error inline.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/sql_query \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "SELECT ticker, period_end, value FROM public.financials WHERE cik = %s LIMIT 10",
    "params": ["0000320193"]
  }'
Generates a Plotly JSON chart. Uses the same chart_type / spec format as the orchestrator generate_chart tool.Chart types: dual_axis, bar, line, heatmap
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/chart \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "chart_type": "bar",
    "title": "AAPL Revenue by Segment (FY2025)",
    "spec": {
      "x": ["Services", "iPhone", "Mac", "iPad", "Wearables"],
      "series": [{ "name": "Revenue ($B)", "data": [96.2, 201.0, 29.1, 26.7, 37.0] }],
      "y_label": "Revenue ($B)"
    }
  }'
See Visualization for the full spec reference.
Packages a peer comps grid (EV/EBITDA, P/E, P/S, margins, growth) with auto-computed median and mean rows.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/comps_table \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "peers": [
      { "ticker": "MSFT", "company_name": "Microsoft", "ev_ebitda": 25.1, "pe_ratio": 32.4, "net_margin": 35.2 },
      { "ticker": "GOOGL", "company_name": "Alphabet",  "ev_ebitda": 18.7, "pe_ratio": 21.8, "net_margin": 23.5 }
    ],
    "title": "Software Comps — March 2026"
  }'
Packages model outputs (assumptions, outputs, optional sensitivity table).model_type: dcf | lbo | comps | merger
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/valuation_model \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model_type":   "dcf",
    "company_name": "Apple Inc",
    "ticker":       "AAPL",
    "assumptions":  { "wacc": 0.09, "terminal_growth": 0.025, "forecast_years": 5 },
    "outputs":      { "equity_value_per_share": 198.40, "implied_upside_pct": 12.3 },
    "sensitivity_table": {
      "row_label": "WACC",
      "col_label": "Terminal Growth",
      "rows": [0.08, 0.09, 0.10],
      "cols": [0.02, 0.025, 0.03],
      "data": [[210, 220, 232], [195, 204, 215], [182, 190, 200]]
    }
  }'
Queries filing_forensics and returns a 6-category × N-period risk matrix with flags and drift scores.Categories: Litigation, Liquidity, Regulatory, Market, Operational, Governance
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/risk_heatmap \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "cik": "0000320193", "form_type": "10-K", "periods": 5 }'
Packages beat/miss, guidance, key management quotes, and QoQ metrics.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/earnings_brief \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name":      "Apple Inc",
    "ticker":            "AAPL",
    "fiscal_period":     "Q1 FY2025",
    "call_date":         "2025-01-30",
    "revenue_beat_miss": { "actual": 124.3, "estimate": 121.9, "beat_pct": 1.97 },
    "eps_beat_miss":     { "actual": 2.40,  "estimate": 2.35,  "beat_pct": 2.13 },
    "guidance": { "revenue_low": 88.0, "revenue_high": 92.0, "commentary": "Record services quarter expected" },
    "key_quotes": [
      { "speaker": "Tim Cook", "role": "CEO", "text": "Services momentum is incredible.", "sentiment": "positive" }
    ]
  }'
Packages a structured bull/base/bear thesis. If cases are not provided but context_text is, the LLM generates them automatically. Auth required.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/thesis_block \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Authorization: Bearer $IVORY_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name":      "Apple Inc",
    "ticker":            "AAPL",
    "recommendation":    "Buy",
    "price_target_usd":  230.00,
    "current_price_usd": 198.40,
    "time_horizon":      "12 months",
    "context_text":      "... research notes ...",
    "confidence":        "High"
  }'
Queries revenue_breakdowns + revenue_segment_lines for hierarchical segment data.breakdown_type: segment | geography | product — omit for all.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/revenue_breakdown \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "cik": "0000320193", "periods": 4, "breakdown_type": "segment" }'
Returns Form 4 insider buy/sell activity with buy/sell totals.
curl -X POST https://api.ivory.finance/v1/editor/blocks/resolve/ownership_snapshot \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "ticker": "AAPL", "limit": 20 }'
The following block types follow the same resolve pattern — POST /v1/editor/blocks/resolve/<type>:
TypeDescription
revenue_trendTime-series revenue sparkline from the financials table
deal_trackerM&A timeline with parties, events, advisors, key terms
quality_of_earningsQoE adjustments → adjusted EBITDA bridge
audit_findingStructured audit finding (condition / criteria / cause / effect)
due_diligence_checklistDD workstream checklist with completion tracking
materiality_calculationASC 320 / ISA 320 materiality thresholds
icfr_controlSOX / ICFR control with test results and auto-derived conclusion
tax_provisionASC 740 / IAS 12 tax provision with ETR reconciliation
benchmarking_tableOperational benchmarking with quartile ranks
project_statusEngagement status, milestones, RAG, budget vs actual
regulatory_trackerCompliance gap tracker per regulation
process_narrativeWalkthrough / process flow with control points
executive_kpi_dashboardRAG KPI grid with AI-generated highlights
competitive_landscapeMarket map with optional Plotly scatter positioning
esg_scorecardESG ratings (MSCI / Sustainalytics / S&P), controversies
analyst_consensusBuy/Hold/Sell consensus, price target distribution
capital_structureDebt waterfall, credit ratings, covenant headroom
news_sentimentNews articles with sentiment scoring
activist_watchActivist investor positions and campaign status
strategic_initiativeInitiative tracker with milestones and KPIs
macro_environmentMacro indicators (rates, FX, commodities, PMI)
scenario_analysisBull/base/bear scenario comparison table
financial_statement_comparisonMulti-company income statement side-by-side
earnings_quality_forensicsAccruals, operating leverage, working capital flags
filing_change_trackerYoY wording diff on SEC filing sections
knowledge_graph_mapNetwork graph from FalkorDB (entity relationships)
credit_memoCredit analysis memo with recommendation
capital_allocation_analysisCapEx / dividends / buybacks / M&A mix with ROIC vs WACC
deal_economicsM&A / LBO term sheet with synergies and accretion
document_intelligenceKey terms, defined terms, obligations extraction
portfolio_snapshotPortfolio positions with sector/geography exposure
meeting_notesStructured meeting notes with action items
Call GET /v1/editor/blocks/schemas for the full attrs schema of each type.Generic pattern:
cURL
curl -X POST "https://api.ivory.finance/v1/editor/blocks/resolve/<block_type>" \
  -H "X-API-Key: $IVORY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... type-specific fields ... }'

Registering custom Tiptap extensions

Each smart block requires a matching Tiptap Node extension. Use GET /v1/editor/blocks/schemas to get the exact attrs list for each type.
import { Node, mergeAttributes } from "@tiptap/core";

export const SecCitationBlock = Node.create({
  name: "sec_citation",
  group: "block",
  atom: true,          // treat as a single non-editable unit
  addAttributes() {
    return {
      block_id:         { default: null },
      status:           { default: "pending" },
      accession_number: { default: null },
      company_name:     { default: null },
      form_type:        { default: null },
      filed_date:       { default: null },
      period_end:       { default: null },
      query:            { default: null },
      excerpts:         { default: [] },
      filing_url:       { default: null },
      markdown_url:     { default: null },
      resolved_at:      { default: null },
      error:            { default: null },
    };
  },
  parseHTML()  { return [{ tag: 'div[data-type="sec_citation"]' }]; },
  renderHTML({ HTMLAttributes }) {
    return ["div", mergeAttributes(HTMLAttributes, { "data-type": "sec_citation" })];
  },
});