Home / Guides / Identifiers & company lists
Identifiers & company lists

Map a CUSIP to ticker and CIK

Convert CUSIPs to tickers and SEC CIKs with the SecFeed CUSIP mapping API, then map a whole 13F portfolio, with a validated name fallback for the CUSIPs that do not match.

13F holdings, 13D and 13G cover pages, N-PORT fund holdings and most bond documents identify securities by CUSIP. Market data and EDGAR use tickers and CIKs. /v1/mapping/cusip bridges the two. SecFeed learns CUSIPs from 13F information tables, where every institutional holding since 2013 is reported by CUSIP with the issuer's name, and matches that name to the SEC's ticker list.

Setup

import os
import re
import requests

BASE = "https://secfeedapi.com"
HEADERS = {"Authorization": f"Bearer {os.environ['SECFEED_KEY']}"}

def get(path, **params):
    r = requests.get(f"{BASE}{path}", params=params, headers=HEADERS, timeout=60)
    r.raise_for_status()
    return r.json()

One CUSIP

print(get("/v1/mapping/cusip", cusip="594918104")[0])

Output:

{'cusip': '594918104', 'issuerName': 'MICROSOFT CORP', 'matches': [{'cik': 789019, 'name': 'MICROSOFT CORP', 'ticker': 'MSFT', 'exchange': 'Nasdaq'}]}

The response is a list with one entry per way 13F filers have spelled the issuer's name, most common first. For NVIDIA's CUSIP 67066G104 there are three: NVIDIA CORP, NVIDIA CORP COM and NVIDIA Corp, all matching CIK 1045810. Use the first entry's first match.

A whole 13F portfolio

The realistic job is converting a fund's holdings. Take Berkshire Hathaway's 13F for the quarter ended June 30, 2026, collect the distinct CUSIPs and map each one:

rows = get("/v1/form-13f/holdings", cik=1067983, period="06-30-2026")
cusips = {}
for r in rows:
    cusips.setdefault(r["cusip"], r["issuer"])
print(len(rows), "holdings rows,", len(cusips), "distinct CUSIPs")
89 holdings rows, 29 distinct CUSIPs

13F names are abbreviated by the filer ("CAPITAL ONE FINL CORP", "D R HORTON INC"), and sometimes the abbreviation does not match the SEC's company name. When the CUSIP lookup finds no ticker, retry with /v1/mapping/name. Accept a name hit only if the issuer's most distinctive word appears in it, otherwise the first fuzzy hit can be a different company:

def to_ticker(cusip, issuer):
    m = get("/v1/mapping/cusip", cusip=cusip)
    if m and m[0]["matches"]:
        return m[0]["matches"][0], "cusip"
    words = re.sub(r"[^A-Za-z0-9 ]", " ", issuer).split()
    key = max(words, key=len).upper()  # must appear in the match, or it is a guess
    for n in (3, 2):
        for hit in get("/v1/mapping/name", name=" ".join(words[:n])):
            if key in hit["name"].upper():
                return hit, "name"
    return {}, "none"

found = {"cusip": 0, "name": 0, "none": 0}
for cusip, issuer in sorted(cusips.items()):
    best, how = to_ticker(cusip, issuer)
    found[how] += 1
    print(f"{cusip}  {issuer[:26]:26} {best.get('ticker', ''):6} {str(best.get('cik', '')):8} via {how}")
print(found)

Output:

02005N100  ALLY FINL INC                              via none
02079K107  ALPHABET INC               GOOGL  1652044  via cusip
02079K305  ALPHABET INC               GOOGL  1652044  via cusip
025816109  AMERICAN EXPRESS CO        AXP    4962     via cusip
037833100  APPLE INC                  AAPL   320193   via cusip
060505104  BANK OF AMER CORP          BAC    70858    via cusip
14040H105  CAPITAL ONE FINL CORP      COF    927628   via name
166764100  CHEVRON CORPORATION        CVX    93410    via cusip
191216100  COCA COLA CO               KO     21344    via cusip
23331A109  D R HORTON INC             DHI    882184   via name
23918K108  DAVITA INC                 DVA    927066   via name
247361702  DELTA AIR LINES INC        DAL    27904    via name
47233W109  JEFFERIES FINANCIAL GROUP  JEF    96223    via name
500754106  KRAFT HEINZ CO             KHC    1637459  via cusip
501044101  KROGER CO                  KR     56873    via cusip
526057104  LENNAR CORP                LEN    920760   via cusip
526057302  LENNAR CORP                LEN    920760   via cusip
530909100  LIBERTY LIVE HOLDINGS INC  LLYVA  2078416  via cusip
530909308  LIBERTY LIVE HOLDINGS INC  LLYVA  2078416  via cusip
546347105  LOUISIANA PAC CORP                         via none
55616P104  MACYS INC                                  via none
615369105  MOODYS CORP                MCO    1059556  via cusip
62944T105  NVR INC                    NVR    906163   via cusip
650111107  NEW YORK TIMES CO MTN BE   NYT    71691    via cusip
670346105  NUCOR CORP                 NUE    73309    via cusip
674599105  OCCIDENTAL PETE CORP                       via none
829933100  SIRIUSXM HOLDINGS INC                      via none
92343E102  VERISIGN INC               VRSN   1014473  via cusip
H1467J104  CHUBB LIMITED                              via none
{'cusip': 18, 'name': 5, 'none': 6}

23 of 29 CUSIPs resolve, 18 directly and 5 through the validated name search. The run took about 15 seconds.

The ones that do not match

The six misses all come from the way 13F filers abbreviate names. Here is each one next to the name the SEC lists:

13F issuer nameSEC company nameWhy the name search missed
ALLY FINL INCAlly Financial Inc.FINL abbreviation
LOUISIANA PAC CORPLOUISIANA-PACIFIC CORPPAC abbreviation and the hyphen
OCCIDENTAL PETE CORPOCCIDENTAL PETROLEUM CORP /DE/PETE abbreviation
CHUBB LIMITEDChubb LtdLIMITED versus Ltd
MACYS INCMacy's, Inc.apostrophe
SIRIUSXM HOLDINGS INCSIRIUS XM HOLDINGS INC.spacing

Normalize before searching to recover most of these: expand common 13F abbreviations (FINL to FINANCIAL, PAC to PACIFIC, PETE to PETROLEUM, LIMITED to LTD), drop punctuation, and compare names with spaces removed. A search on the first distinctive word alone (/v1/mapping/name?name=occidental) also finds the right company, but then check the match yourself.

Leave them unmatched rather than accept a guess. A wrong ticker silently joins the wrong price series, which is worse than a gap you can see.

Two share classes, one company

Alphabet (02079K107 class A, 02079K305 class C), Lennar and Liberty Live each have two CUSIPs that map to the same CIK and ticker. When you aggregate a portfolio by company, group by CIK; when you need the exact security, keep the CUSIP.

Next steps

More identifiers & company lists guides

Run this guide with your own key

500 free API calls a month. Every example on this page works on the free plan.

Get free API key →