Skip to main content
GET
/
v1
/
documents
/
search
Search Documents
curl --request GET \
  --url https://api.example.com/v1/documents/search
{
  "data": [
    {
      "id": "<string>",
      "ticker": "<string>",
      "company_name": "<string>",
      "doc_type": "<string>",
      "filing_date": "<string>",
      "section_type": "<string>",
      "section_title": "<string>",
      "snippet": "<string>",
      "relevance_score": 123,
      "semantic_score": 123,
      "content": "<string>"
    }
  ]
}

Overview

Search across SEC filing sections including debt footnotes, credit agreements, indentures, and MD&A sections. Find covenant language, guarantor lists, and specific debt terms. Supports three search modes:
  • Keyword (default) — PostgreSQL full-text search with relevance ranking
  • Semantic — Vector similarity search using Gemini embeddings (finds conceptually similar content even without keyword matches)
  • Hybrid — Combines keyword and semantic results via Reciprocal Rank Fusion for the best of both

Request

q
string
required
Search query. For keyword/hybrid mode, uses full-text search syntax. For semantic mode, use natural language.Example: maintenance covenant, subordinated, can they pay dividends
mode
string
default:"keyword"
Search mode. One of:
  • keyword — Full-text search with relevance ranking (default)
  • semantic — Vector similarity search using AI embeddings
  • hybrid — Combines keyword + semantic via Reciprocal Rank Fusion
ticker
string
Comma-separated company tickers.Example: RIG,CHTR
doc_type
string
Filing type: 10-K, 10-Q, 8-K
section_type
string
Section type to search. See section types below.
filed_after
string
Minimum filing date (YYYY-MM-DD).
filed_before
string
Maximum filing date (YYYY-MM-DD).
fields
string
Fields to return.Example: ticker,section_type,snippet,relevance_score,semantic_score
sort
string
default:"-relevance"
Sort order: -relevance, -filing_date, filing_date
limit
integer
default:"50"
Results per page. Maximum 100.
offset
integer
default:"0"
Pagination offset.

Section Types

TypeDescriptionSource
exhibit_21Subsidiary list10-K Exhibit 21
debt_footnoteLong-term debt details10-K/10-Q Notes
mda_liquidityLiquidity discussionMD&A section
credit_agreementFull credit facility docs8-K Exhibit 10
indentureBond indentures8-K Exhibit 4
guarantor_listGuarantor subsidiariesNotes
covenantsFinancial covenantsNotes/Exhibits

Response

data
array
Array of matching document sections.

Examples

Search Debt Footnotes

curl "https://api.debtstack.ai/v1/documents/search?q=subordinated&section_type=debt_footnote&fields=ticker,section_type,snippet,relevance_score" \
  -H "X-API-Key: ds_xxxxx"

Response

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "ticker": "RIG",
      "company_name": "Transocean Ltd.",
      "doc_type": "10-K",
      "filing_date": "2025-02-15",
      "section_type": "debt_footnote",
      "section_title": "Note 9 - Long-Term Debt",
      "snippet": "...senior <b>subordinated</b> notes due 2028 are structurally <b>subordinated</b> to all obligations of our operating subsidiaries...",
      "relevance_score": 0.85
    },
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "ticker": "CHTR",
      "company_name": "Charter Communications, Inc.",
      "doc_type": "10-K",
      "filing_date": "2025-02-23",
      "section_type": "debt_footnote",
      "section_title": "Note 8 - Long-Term Debt",
      "snippet": "...holdco notes are structurally <b>subordinated</b> to all obligations of CCO Holdings...",
      "relevance_score": 0.78
    }
  ],
  "meta": {
    "query": "subordinated",
    "mode": "keyword",
    "total": 42,
    "limit": 50,
    "offset": 0
  }
}

Search Credit Agreements

Find maintenance covenants:
curl "https://api.debtstack.ai/v1/documents/search?q=maintenance%20covenant&section_type=credit_agreement&ticker=CHTR" \
  -H "X-API-Key: ds_xxxxx"

Search Indentures

Find events of default:
curl "https://api.debtstack.ai/v1/documents/search?q=event%20of%20default&section_type=indenture&limit=10" \
  -H "X-API-Key: ds_xxxxx"
Find conceptually similar content using natural language — no exact keyword match needed:
curl "https://api.debtstack.ai/v1/documents/search?q=can%20they%20pay%20dividends&ticker=RIG&mode=semantic&fields=ticker,section_type,section_title,semantic_score" \
  -H "X-API-Key: ds_xxxxx"
{
  "data": [
    {
      "ticker": "RIG",
      "section_type": "indenture",
      "section_title": "Limitation on Restricted Payments",
      "semantic_score": 0.67
    },
    {
      "ticker": "RIG",
      "section_type": "indenture",
      "section_title": "Covenants - Restricted Payments",
      "semantic_score": 0.64
    }
  ],
  "meta": {
    "query": "can they pay dividends",
    "mode": "semantic",
    "total": 15,
    "limit": 50,
    "offset": 0
  }
}
Semantic search finds “Limitation on Restricted Payments” for the query “can they pay dividends” — even though none of the keywords match. This is the power of vector similarity search.
Combine keyword precision with semantic understanding:
curl "https://api.debtstack.ai/v1/documents/search?q=restricted%20payment%20basket&ticker=CHTR&mode=hybrid&fields=ticker,section_type,relevance_score,semantic_score" \
  -H "X-API-Key: ds_xxxxx"

Get Full Document Content

response = requests.get(
    f"{BASE_URL}/documents/search",
    params={
        "q": "redemption",
        "section_type": "indenture",
        "ticker": "RIG",
        "fields": "ticker,section_title,content",  # Include full content
        "limit": 1
    },
    headers={"X-API-Key": API_KEY}
)

doc = response.json()["data"][0]
print(f"Full content length: {len(doc['content'])} characters")

Use Cases

Find Covenant Details

def find_covenants(ticker):
    """Find all covenant mentions for a company."""
    response = requests.get(
        f"{BASE_URL}/documents/search",
        params={
            "q": "leverage ratio OR interest coverage",
            "ticker": ticker,
            "section_type": "covenants,credit_agreement",
            "sort": "-relevance"
        },
        headers={"X-API-Key": API_KEY}
    )

    return response.json()["data"]

# Usage
covenants = find_covenants("CHTR")
for cov in covenants[:5]:
    print(f"{cov['section_type']}: {cov['snippet'][:150]}...")

Search for Specific Terms

def search_filings(query, companies=None, section_type=None):
    """Search SEC filings for specific terms."""
    params = {
        "q": query,
        "fields": "ticker,filing_date,section_type,snippet,relevance_score",
        "sort": "-relevance",
        "limit": 20
    }

    if companies:
        params["ticker"] = ",".join(companies)
    if section_type:
        params["section_type"] = section_type

    response = requests.get(
        f"{BASE_URL}/documents/search",
        params=params,
        headers={"X-API-Key": API_KEY}
    )

    return response.json()["data"]

# Find change of control provisions
results = search_filings("change of control", section_type="indenture")

Monitor Filing Updates

from datetime import datetime, timedelta

def recent_filings(query, days=30):
    """Find matches in recent filings."""
    since = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")

    response = requests.get(
        f"{BASE_URL}/documents/search",
        params={
            "q": query,
            "filed_after": since,
            "sort": "-filing_date"
        },
        headers={"X-API-Key": API_KEY}
    )

    return response.json()["data"]

# Find recent mentions of refinancing
recent = recent_filings("refinancing OR amendment", days=90)

Search Modes

ModeBest ForHow It Works
keywordExact terms, legal languagePostgreSQL full-text search with ts_rank relevance scoring
semanticNatural language questions, conceptual searchEmbeds query with Gemini, finds similar document chunks via cosine similarity (threshold 0.3)
hybridBest overall resultsRuns both keyword and semantic, combines via Reciprocal Rank Fusion (RRF)
When to use each mode:
  • Use keyword when you know the exact terminology (e.g., event of default, SOFR)
  • Use semantic when asking questions in plain English (e.g., can they pay dividends, what happens if they miss a payment)
  • Use hybrid when you want comprehensive results that catch both exact matches and conceptually related content

Notes

  • Keyword mode uses PostgreSQL full-text search with relevance ranking
  • Semantic mode uses 768-dimensional Gemini embeddings with cosine similarity
  • Hybrid mode combines both via Reciprocal Rank Fusion (k=60)
  • Snippets highlight matching terms with <b> tags (keyword and hybrid modes)
  • Credit agreements and indentures can be large (up to 500K chars)
  • Use content field sparingly to avoid large responses
  • Credit cost: 3 credits per request