[{"data":1,"prerenderedAt":1804},["ShallowReactive",2],{"doc-api/authentication":3},{"id":4,"title":5,"appLink":6,"body":7,"category":1787,"description":1788,"extension":1789,"level":1790,"meta":1791,"navigation":151,"next":1793,"path":1794,"related":1795,"seo":1796,"stem":1797,"tags":1798,"__hash__":1803,"_path":1794},"docs/docs/api/authentication.md","API Authentication",null,{"type":8,"value":9,"toc":1751},"minimark",[10,14,25,30,33,82,85,89,92,97,113,117,122,200,205,235,240,249,254,298,302,305,320,323,327,434,438,441,444,455,458,463,466,471,513,517,585,588,652,656,661,673,678,692,696,699,754,758,761,769,773,780,855,860,935,939,944,947,953,956,962,967,970,975,978,982,985,1025,1031,1119,1123,1127,1133,1201,1206,1274,1279,1347,1351,1356,1442,1446,1450,1488,1491,1627,1631,1660,1667,1671,1675,1682,1686,1701,1705,1716,1720,1723,1747],[11,12,5],"h1",{"id":13},"api-authentication",[15,16,17],"blockquote",{},[18,19,20,24],"p",{},[21,22,23],"strong",{},"Developer Resource:"," This guide covers authentication setup for the Profitelligence API. Choose the method that fits your use case.",[26,27,29],"h2",{"id":28},"authentication-methods","Authentication Methods",[18,31,32],{},"The API supports two authentication methods:",[34,35,36,52],"table",{},[37,38,39],"thead",{},[40,41,42,46,49],"tr",{},[43,44,45],"th",{},"Method",[43,47,48],{},"Use Case",[43,50,51],{},"Best For",[53,54,55,69],"tbody",{},[40,56,57,63,66],{},[58,59,60],"td",{},[21,61,62],{},"Firebase JWT",[58,64,65],{},"User-authenticated requests",[58,67,68],{},"Web/mobile apps where users log in",[40,70,71,76,79],{},[58,72,73],{},[21,74,75],{},"API Key",[58,77,78],{},"Server-to-server requests",[58,80,81],{},"Backend services, scripts, automation",[18,83,84],{},"Both methods provide the same data access. Your subscription tier (Free, Pro, Elite) determines which symbols and features you can access.",[26,86,88],{"id":87},"method-1-firebase-jwt","Method 1: Firebase JWT",[18,90,91],{},"Use Firebase Authentication when building applications where end users log in with their Profitelligence accounts.",[93,94,96],"h3",{"id":95},"how-it-works","How It Works",[98,99,100,104,107,110],"ol",{},[101,102,103],"li",{},"User logs in via Firebase Auth (email/password, Google, etc.)",[101,105,106],{},"Firebase returns a JWT token",[101,108,109],{},"Include the token in API requests",[101,111,112],{},"API validates the token and applies user's subscription tier",[93,114,116],{"id":115},"setup","Setup",[18,118,119],{},[21,120,121],{},"1. Initialize Firebase in your app:",[123,124,129],"pre",{"className":125,"code":126,"language":127,"meta":128,"style":128},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { initializeApp } from 'firebase/app';\nimport { getAuth, signInWithEmailAndPassword } from 'firebase/auth';\n\nconst firebaseConfig = {\n  apiKey: \"YOUR_FIREBASE_API_KEY\",\n  authDomain: \"profitelligence.firebaseapp.com\",\n  projectId: \"profitelligence\"\n};\n\nconst app = initializeApp(firebaseConfig);\nconst auth = getAuth(app);\n","javascript","",[130,131,132,140,146,153,159,165,171,177,183,188,194],"code",{"__ignoreMap":128},[133,134,137],"span",{"class":135,"line":136},"line",1,[133,138,139],{},"import { initializeApp } from 'firebase/app';\n",[133,141,143],{"class":135,"line":142},2,[133,144,145],{},"import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';\n",[133,147,149],{"class":135,"line":148},3,[133,150,152],{"emptyLinePlaceholder":151},true,"\n",[133,154,156],{"class":135,"line":155},4,[133,157,158],{},"const firebaseConfig = {\n",[133,160,162],{"class":135,"line":161},5,[133,163,164],{},"  apiKey: \"YOUR_FIREBASE_API_KEY\",\n",[133,166,168],{"class":135,"line":167},6,[133,169,170],{},"  authDomain: \"profitelligence.firebaseapp.com\",\n",[133,172,174],{"class":135,"line":173},7,[133,175,176],{},"  projectId: \"profitelligence\"\n",[133,178,180],{"class":135,"line":179},8,[133,181,182],{},"};\n",[133,184,186],{"class":135,"line":185},9,[133,187,152],{"emptyLinePlaceholder":151},[133,189,191],{"class":135,"line":190},10,[133,192,193],{},"const app = initializeApp(firebaseConfig);\n",[133,195,197],{"class":135,"line":196},11,[133,198,199],{},"const auth = getAuth(app);\n",[18,201,202],{},[21,203,204],{},"2. Authenticate the user:",[123,206,208],{"className":125,"code":207,"language":127,"meta":128,"style":128},"const userCredential = await signInWithEmailAndPassword(\n  auth,\n  email,\n  password\n);\n",[130,209,210,215,220,225,230],{"__ignoreMap":128},[133,211,212],{"class":135,"line":136},[133,213,214],{},"const userCredential = await signInWithEmailAndPassword(\n",[133,216,217],{"class":135,"line":142},[133,218,219],{},"  auth,\n",[133,221,222],{"class":135,"line":148},[133,223,224],{},"  email,\n",[133,226,227],{"class":135,"line":155},[133,228,229],{},"  password\n",[133,231,232],{"class":135,"line":161},[133,233,234],{},");\n",[18,236,237],{},[21,238,239],{},"3. Get the JWT token:",[123,241,243],{"className":125,"code":242,"language":127,"meta":128,"style":128},"const token = await userCredential.user.getIdToken();\n",[130,244,245],{"__ignoreMap":128},[133,246,247],{"class":135,"line":136},[133,248,242],{},[18,250,251],{},[21,252,253],{},"4. Include in API requests:",[123,255,257],{"className":125,"code":256,"language":127,"meta":128,"style":128},"const response = await fetch(\n  'https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL',\n  {\n    headers: {\n      'Authorization': `Bearer ${token}`\n    }\n  }\n);\n",[130,258,259,264,269,274,279,284,289,294],{"__ignoreMap":128},[133,260,261],{"class":135,"line":136},[133,262,263],{},"const response = await fetch(\n",[133,265,266],{"class":135,"line":142},[133,267,268],{},"  'https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL',\n",[133,270,271],{"class":135,"line":148},[133,272,273],{},"  {\n",[133,275,276],{"class":135,"line":155},[133,277,278],{},"    headers: {\n",[133,280,281],{"class":135,"line":161},[133,282,283],{},"      'Authorization': `Bearer ${token}`\n",[133,285,286],{"class":135,"line":167},[133,287,288],{},"    }\n",[133,290,291],{"class":135,"line":173},[133,292,293],{},"  }\n",[133,295,296],{"class":135,"line":179},[133,297,234],{},[93,299,301],{"id":300},"token-refresh","Token Refresh",[18,303,304],{},"Firebase tokens expire after 1 hour. The Firebase SDK handles automatic refresh, but you should:",[123,306,308],{"className":125,"code":307,"language":127,"meta":128,"style":128},"// Always get a fresh token before API calls\nconst token = await auth.currentUser.getIdToken(/* forceRefresh */ false);\n",[130,309,310,315],{"__ignoreMap":128},[133,311,312],{"class":135,"line":136},[133,313,314],{},"// Always get a fresh token before API calls\n",[133,316,317],{"class":135,"line":142},[133,318,319],{},"const token = await auth.currentUser.getIdToken(/* forceRefresh */ false);\n",[18,321,322],{},"The SDK returns a cached token if valid, or refreshes automatically if expired.",[93,324,326],{"id":325},"python-example","Python Example",[123,328,332],{"className":329,"code":330,"language":331,"meta":128,"style":128},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import firebase_admin\nfrom firebase_admin import credentials, auth\nimport requests\n\n# Initialize Firebase Admin SDK\ncred = credentials.Certificate('path/to/serviceAccount.json')\nfirebase_admin.initialize_app(cred)\n\n# For server-side token verification (if you're validating tokens):\n# decoded_token = auth.verify_id_token(id_token)\n\n# For making API calls with a user's token:\ndef fetch_company_profile(jwt_token: str, symbol: str):\n    response = requests.get(\n        f\"https://apollo.profitelligence.com/v1/company-profile\",\n        params={\"symbol\": symbol},\n        headers={\"Authorization\": f\"Bearer {jwt_token}\"}\n    )\n    return response.text  # CSV data\n","python",[130,333,334,339,344,349,353,358,363,368,372,377,382,386,392,398,404,410,416,422,428],{"__ignoreMap":128},[133,335,336],{"class":135,"line":136},[133,337,338],{},"import firebase_admin\n",[133,340,341],{"class":135,"line":142},[133,342,343],{},"from firebase_admin import credentials, auth\n",[133,345,346],{"class":135,"line":148},[133,347,348],{},"import requests\n",[133,350,351],{"class":135,"line":155},[133,352,152],{"emptyLinePlaceholder":151},[133,354,355],{"class":135,"line":161},[133,356,357],{},"# Initialize Firebase Admin SDK\n",[133,359,360],{"class":135,"line":167},[133,361,362],{},"cred = credentials.Certificate('path/to/serviceAccount.json')\n",[133,364,365],{"class":135,"line":173},[133,366,367],{},"firebase_admin.initialize_app(cred)\n",[133,369,370],{"class":135,"line":179},[133,371,152],{"emptyLinePlaceholder":151},[133,373,374],{"class":135,"line":185},[133,375,376],{},"# For server-side token verification (if you're validating tokens):\n",[133,378,379],{"class":135,"line":190},[133,380,381],{},"# decoded_token = auth.verify_id_token(id_token)\n",[133,383,384],{"class":135,"line":196},[133,385,152],{"emptyLinePlaceholder":151},[133,387,389],{"class":135,"line":388},12,[133,390,391],{},"# For making API calls with a user's token:\n",[133,393,395],{"class":135,"line":394},13,[133,396,397],{},"def fetch_company_profile(jwt_token: str, symbol: str):\n",[133,399,401],{"class":135,"line":400},14,[133,402,403],{},"    response = requests.get(\n",[133,405,407],{"class":135,"line":406},15,[133,408,409],{},"        f\"https://apollo.profitelligence.com/v1/company-profile\",\n",[133,411,413],{"class":135,"line":412},16,[133,414,415],{},"        params={\"symbol\": symbol},\n",[133,417,419],{"class":135,"line":418},17,[133,420,421],{},"        headers={\"Authorization\": f\"Bearer {jwt_token}\"}\n",[133,423,425],{"class":135,"line":424},18,[133,426,427],{},"    )\n",[133,429,431],{"class":135,"line":430},19,[133,432,433],{},"    return response.text  # CSV data\n",[26,435,437],{"id":436},"method-2-api-key","Method 2: API Key",[18,439,440],{},"Use API keys for backend services, scripts, and automated systems that don't involve user login.",[93,442,96],{"id":443},"how-it-works-1",[98,445,446,449,452],{},[101,447,448],{},"Request an API key from your account settings",[101,450,451],{},"Include the key in a custom header",[101,453,454],{},"API validates the key and applies your account's subscription tier",[93,456,116],{"id":457},"setup-1",[18,459,460],{},[21,461,462],{},"1. Obtain your API key:",[18,464,465],{},"Contact support or visit your account settings to generate an API key. Keys are tied to your account and inherit your subscription tier.",[18,467,468],{},[21,469,470],{},"2. Include in requests:",[123,472,476],{"className":473,"code":474,"language":475,"meta":128,"style":128},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl -H \"X-API-Key: YOUR_API_KEY\" \\\n  \"https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL\"\n","bash",[130,477,478,502],{"__ignoreMap":128},[133,479,480,484,488,492,495,498],{"class":135,"line":136},[133,481,483],{"class":482},"sBMFI","curl",[133,485,487],{"class":486},"sfazB"," -H",[133,489,491],{"class":490},"sMK4o"," \"",[133,493,494],{"class":486},"X-API-Key: YOUR_API_KEY",[133,496,497],{"class":490},"\"",[133,499,501],{"class":500},"sTEyZ"," \\\n",[133,503,504,507,510],{"class":135,"line":142},[133,505,506],{"class":490},"  \"",[133,508,509],{"class":486},"https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL",[133,511,512],{"class":490},"\"\n",[93,514,516],{"id":515},"javascript-example","JavaScript Example",[123,518,520],{"className":125,"code":519,"language":127,"meta":128,"style":128},"const API_KEY = process.env.PROFITELLIGENCE_API_KEY;\n\nasync function getCompanyProfile(symbol) {\n  const response = await fetch(\n    `https://apollo.profitelligence.com/v1/company-profile?symbol=${symbol}`,\n    {\n      headers: {\n        'X-API-Key': API_KEY\n      }\n    }\n  );\n  return response.text();\n}\n",[130,521,522,527,531,536,541,546,551,556,561,566,570,575,580],{"__ignoreMap":128},[133,523,524],{"class":135,"line":136},[133,525,526],{},"const API_KEY = process.env.PROFITELLIGENCE_API_KEY;\n",[133,528,529],{"class":135,"line":142},[133,530,152],{"emptyLinePlaceholder":151},[133,532,533],{"class":135,"line":148},[133,534,535],{},"async function getCompanyProfile(symbol) {\n",[133,537,538],{"class":135,"line":155},[133,539,540],{},"  const response = await fetch(\n",[133,542,543],{"class":135,"line":161},[133,544,545],{},"    `https://apollo.profitelligence.com/v1/company-profile?symbol=${symbol}`,\n",[133,547,548],{"class":135,"line":167},[133,549,550],{},"    {\n",[133,552,553],{"class":135,"line":173},[133,554,555],{},"      headers: {\n",[133,557,558],{"class":135,"line":179},[133,559,560],{},"        'X-API-Key': API_KEY\n",[133,562,563],{"class":135,"line":185},[133,564,565],{},"      }\n",[133,567,568],{"class":135,"line":190},[133,569,288],{},[133,571,572],{"class":135,"line":196},[133,573,574],{},"  );\n",[133,576,577],{"class":135,"line":388},[133,578,579],{},"  return response.text();\n",[133,581,582],{"class":135,"line":394},[133,583,584],{},"}\n",[93,586,326],{"id":587},"python-example-1",[123,589,591],{"className":329,"code":590,"language":331,"meta":128,"style":128},"import os\nimport requests\n\nAPI_KEY = os.environ.get('PROFITELLIGENCE_API_KEY')\n\ndef get_company_profile(symbol: str) -> str:\n    response = requests.get(\n        \"https://apollo.profitelligence.com/v1/company-profile\",\n        params={\"symbol\": symbol},\n        headers={\"X-API-Key\": API_KEY}\n    )\n    response.raise_for_status()\n    return response.text\n",[130,592,593,598,602,606,611,615,620,624,629,633,638,642,647],{"__ignoreMap":128},[133,594,595],{"class":135,"line":136},[133,596,597],{},"import os\n",[133,599,600],{"class":135,"line":142},[133,601,348],{},[133,603,604],{"class":135,"line":148},[133,605,152],{"emptyLinePlaceholder":151},[133,607,608],{"class":135,"line":155},[133,609,610],{},"API_KEY = os.environ.get('PROFITELLIGENCE_API_KEY')\n",[133,612,613],{"class":135,"line":161},[133,614,152],{"emptyLinePlaceholder":151},[133,616,617],{"class":135,"line":167},[133,618,619],{},"def get_company_profile(symbol: str) -> str:\n",[133,621,622],{"class":135,"line":173},[133,623,403],{},[133,625,626],{"class":135,"line":179},[133,627,628],{},"        \"https://apollo.profitelligence.com/v1/company-profile\",\n",[133,630,631],{"class":135,"line":185},[133,632,415],{},[133,634,635],{"class":135,"line":190},[133,636,637],{},"        headers={\"X-API-Key\": API_KEY}\n",[133,639,640],{"class":135,"line":196},[133,641,427],{},[133,643,644],{"class":135,"line":388},[133,645,646],{},"    response.raise_for_status()\n",[133,648,649],{"class":135,"line":394},[133,650,651],{},"    return response.text\n",[93,653,655],{"id":654},"security-best-practices","Security Best Practices",[18,657,658],{},[21,659,660],{},"Never expose API keys in:",[662,663,664,667,670],"ul",{},[101,665,666],{},"Client-side JavaScript",[101,668,669],{},"Public repositories",[101,671,672],{},"Browser network requests",[18,674,675],{},[21,676,677],{},"Do:",[662,679,680,683,686,689],{},[101,681,682],{},"Store keys in environment variables",[101,684,685],{},"Use keys only in backend/server code",[101,687,688],{},"Rotate keys periodically",[101,690,691],{},"Use separate keys for development and production",[26,693,695],{"id":694},"rate-limits","Rate Limits",[18,697,698],{},"Both authentication methods are subject to rate limits based on subscription tier:",[34,700,701,714],{},[37,702,703],{},[40,704,705,708,711],{},[43,706,707],{},"Tier",[43,709,710],{},"Daily Limit",[43,712,713],{},"Hourly Limit",[53,715,716,729,742],{},[40,717,718,723,726],{},[58,719,720],{},[21,721,722],{},"Free",[58,724,725],{},"10 requests",[58,727,728],{},"2 requests",[40,730,731,736,739],{},[58,732,733],{},[21,734,735],{},"Pro",[58,737,738],{},"100 requests",[58,740,741],{},"25 requests",[40,743,744,749,752],{},[58,745,746],{},[21,747,748],{},"Elite",[58,750,751],{},"1,000 requests",[58,753,738],{},[93,755,757],{"id":756},"rate-limit-headers","Rate Limit Headers",[18,759,760],{},"Every response includes rate limit information:",[123,762,767],{"className":763,"code":765,"language":766},[764],"language-text","X-RateLimit-Limit: 100        # Your daily limit\nX-RateLimit-Remaining: 87     # Requests remaining today\nX-RateLimit-Reset: 1705449600 # Unix timestamp when limit resets\n","text",[130,768,765],{"__ignoreMap":128},[93,770,772],{"id":771},"handling-rate-limits","Handling Rate Limits",[18,774,775,776,779],{},"When you exceed your limit, the API returns ",[130,777,778],{},"429 Too Many Requests",":",[123,781,785],{"className":782,"code":783,"language":784,"meta":128,"style":128},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"error\": \"Rate limit exceeded\",\n  \"code\": \"RATE_LIMIT_EXCEEDED\",\n  \"details\": \"Daily limit of 100 requests exceeded. Resets at 2024-01-17T00:00:00Z\"\n}\n","json",[130,786,787,792,814,833,851],{"__ignoreMap":128},[133,788,789],{"class":135,"line":136},[133,790,791],{"class":490},"{\n",[133,793,794,796,800,802,804,806,809,811],{"class":135,"line":142},[133,795,506],{"class":490},[133,797,799],{"class":798},"spNyl","error",[133,801,497],{"class":490},[133,803,779],{"class":490},[133,805,491],{"class":490},[133,807,808],{"class":486},"Rate limit exceeded",[133,810,497],{"class":490},[133,812,813],{"class":490},",\n",[133,815,816,818,820,822,824,826,829,831],{"class":135,"line":148},[133,817,506],{"class":490},[133,819,130],{"class":798},[133,821,497],{"class":490},[133,823,779],{"class":490},[133,825,491],{"class":490},[133,827,828],{"class":486},"RATE_LIMIT_EXCEEDED",[133,830,497],{"class":490},[133,832,813],{"class":490},[133,834,835,837,840,842,844,846,849],{"class":135,"line":155},[133,836,506],{"class":490},[133,838,839],{"class":798},"details",[133,841,497],{"class":490},[133,843,779],{"class":490},[133,845,491],{"class":490},[133,847,848],{"class":486},"Daily limit of 100 requests exceeded. Resets at 2024-01-17T00:00:00Z",[133,850,512],{"class":490},[133,852,853],{"class":135,"line":161},[133,854,584],{"class":490},[18,856,857],{},[21,858,859],{},"Implement exponential backoff:",[123,861,863],{"className":329,"code":862,"language":331,"meta":128,"style":128},"import time\nimport requests\n\ndef api_request_with_retry(url, headers, max_retries=3):\n    for attempt in range(max_retries):\n        response = requests.get(url, headers=headers)\n\n        if response.status_code == 429:\n            wait_time = 2 ** attempt  # 1, 2, 4 seconds\n            time.sleep(wait_time)\n            continue\n\n        return response\n\n    raise Exception(\"Max retries exceeded\")\n",[130,864,865,870,874,878,883,888,893,897,902,907,912,917,921,926,930],{"__ignoreMap":128},[133,866,867],{"class":135,"line":136},[133,868,869],{},"import time\n",[133,871,872],{"class":135,"line":142},[133,873,348],{},[133,875,876],{"class":135,"line":148},[133,877,152],{"emptyLinePlaceholder":151},[133,879,880],{"class":135,"line":155},[133,881,882],{},"def api_request_with_retry(url, headers, max_retries=3):\n",[133,884,885],{"class":135,"line":161},[133,886,887],{},"    for attempt in range(max_retries):\n",[133,889,890],{"class":135,"line":167},[133,891,892],{},"        response = requests.get(url, headers=headers)\n",[133,894,895],{"class":135,"line":173},[133,896,152],{"emptyLinePlaceholder":151},[133,898,899],{"class":135,"line":179},[133,900,901],{},"        if response.status_code == 429:\n",[133,903,904],{"class":135,"line":185},[133,905,906],{},"            wait_time = 2 ** attempt  # 1, 2, 4 seconds\n",[133,908,909],{"class":135,"line":190},[133,910,911],{},"            time.sleep(wait_time)\n",[133,913,914],{"class":135,"line":196},[133,915,916],{},"            continue\n",[133,918,919],{"class":135,"line":388},[133,920,152],{"emptyLinePlaceholder":151},[133,922,923],{"class":135,"line":394},[133,924,925],{},"        return response\n",[133,927,928],{"class":135,"line":400},[133,929,152],{"emptyLinePlaceholder":151},[133,931,932],{"class":135,"line":406},[133,933,934],{},"    raise Exception(\"Max retries exceeded\")\n",[93,936,938],{"id":937},"optimizing-api-usage","Optimizing API Usage",[18,940,941],{},[21,942,943],{},"1. Use page aggregation endpoints:",[18,945,946],{},"Instead of multiple calls:",[123,948,951],{"className":949,"code":950,"language":766},[764],"GET /company-profile?symbol=AAPL\nGET /ohlc?symbol=AAPL\nGET /technical-signals?symbol=AAPL\n",[130,952,950],{"__ignoreMap":128},[18,954,955],{},"Use one call:",[123,957,960],{"className":958,"code":959,"language":766},[764],"GET /company-info-page?symbol=AAPL\n",[130,961,959],{"__ignoreMap":128},[18,963,964],{},[21,965,966],{},"2. Cache responses:",[18,968,969],{},"Company profiles and historical data don't change frequently. Cache for 5-15 minutes.",[18,971,972],{},[21,973,974],{},"3. Batch your requests:",[18,976,977],{},"If checking multiple symbols, spread requests over time rather than bursting.",[26,979,981],{"id":980},"symbol-access-tiers","Symbol Access Tiers",[18,983,984],{},"Your subscription tier determines which symbols you can query:",[34,986,987,996],{},[37,988,989],{},[40,990,991,993],{},[43,992,707],{},[43,994,995],{},"Symbols Available",[53,997,998,1007,1016],{},[40,999,1000,1004],{},[58,1001,1002],{},[21,1003,722],{},[58,1005,1006],{},"Top 500 by average daily volume",[40,1008,1009,1013],{},[58,1010,1011],{},[21,1012,735],{},[58,1014,1015],{},"Top 6,000 by average daily volume",[40,1017,1018,1022],{},[58,1019,1020],{},[21,1021,748],{},[58,1023,1024],{},"All symbols (unlimited)",[18,1026,1027,1028,779],{},"Requesting a symbol outside your tier returns ",[130,1029,1030],{},"403 Forbidden",[123,1032,1034],{"className":782,"code":1033,"language":784,"meta":128,"style":128},"{\n  \"error\": \"Symbol access denied\",\n  \"code\": \"SYMBOL_TIER_RESTRICTED\",\n  \"details\": \"SMALLCAP is not available on the Free tier. Upgrade to Pro for access.\",\n  \"upgrade_url\": \"https://profitelligence.com/subscribe\"\n}\n",[130,1035,1036,1040,1059,1078,1097,1115],{"__ignoreMap":128},[133,1037,1038],{"class":135,"line":136},[133,1039,791],{"class":490},[133,1041,1042,1044,1046,1048,1050,1052,1055,1057],{"class":135,"line":142},[133,1043,506],{"class":490},[133,1045,799],{"class":798},[133,1047,497],{"class":490},[133,1049,779],{"class":490},[133,1051,491],{"class":490},[133,1053,1054],{"class":486},"Symbol access denied",[133,1056,497],{"class":490},[133,1058,813],{"class":490},[133,1060,1061,1063,1065,1067,1069,1071,1074,1076],{"class":135,"line":148},[133,1062,506],{"class":490},[133,1064,130],{"class":798},[133,1066,497],{"class":490},[133,1068,779],{"class":490},[133,1070,491],{"class":490},[133,1072,1073],{"class":486},"SYMBOL_TIER_RESTRICTED",[133,1075,497],{"class":490},[133,1077,813],{"class":490},[133,1079,1080,1082,1084,1086,1088,1090,1093,1095],{"class":135,"line":155},[133,1081,506],{"class":490},[133,1083,839],{"class":798},[133,1085,497],{"class":490},[133,1087,779],{"class":490},[133,1089,491],{"class":490},[133,1091,1092],{"class":486},"SMALLCAP is not available on the Free tier. Upgrade to Pro for access.",[133,1094,497],{"class":490},[133,1096,813],{"class":490},[133,1098,1099,1101,1104,1106,1108,1110,1113],{"class":135,"line":161},[133,1100,506],{"class":490},[133,1102,1103],{"class":798},"upgrade_url",[133,1105,497],{"class":490},[133,1107,779],{"class":490},[133,1109,491],{"class":490},[133,1111,1112],{"class":486},"https://profitelligence.com/subscribe",[133,1114,512],{"class":490},[133,1116,1117],{"class":135,"line":167},[133,1118,584],{"class":490},[26,1120,1122],{"id":1121},"error-responses","Error Responses",[93,1124,1126],{"id":1125},"authentication-errors","Authentication Errors",[18,1128,1129,1132],{},[21,1130,1131],{},"401 Unauthorized"," — Missing or invalid credentials:",[123,1134,1136],{"className":782,"code":1135,"language":784,"meta":128,"style":128},"{\n  \"error\": \"Authentication required\",\n  \"code\": \"AUTH_REQUIRED\",\n  \"details\": \"Include Authorization header with Bearer token or X-API-Key header\"\n}\n",[130,1137,1138,1142,1161,1180,1197],{"__ignoreMap":128},[133,1139,1140],{"class":135,"line":136},[133,1141,791],{"class":490},[133,1143,1144,1146,1148,1150,1152,1154,1157,1159],{"class":135,"line":142},[133,1145,506],{"class":490},[133,1147,799],{"class":798},[133,1149,497],{"class":490},[133,1151,779],{"class":490},[133,1153,491],{"class":490},[133,1155,1156],{"class":486},"Authentication required",[133,1158,497],{"class":490},[133,1160,813],{"class":490},[133,1162,1163,1165,1167,1169,1171,1173,1176,1178],{"class":135,"line":148},[133,1164,506],{"class":490},[133,1166,130],{"class":798},[133,1168,497],{"class":490},[133,1170,779],{"class":490},[133,1172,491],{"class":490},[133,1174,1175],{"class":486},"AUTH_REQUIRED",[133,1177,497],{"class":490},[133,1179,813],{"class":490},[133,1181,1182,1184,1186,1188,1190,1192,1195],{"class":135,"line":155},[133,1183,506],{"class":490},[133,1185,839],{"class":798},[133,1187,497],{"class":490},[133,1189,779],{"class":490},[133,1191,491],{"class":490},[133,1193,1194],{"class":486},"Include Authorization header with Bearer token or X-API-Key header",[133,1196,512],{"class":490},[133,1198,1199],{"class":135,"line":161},[133,1200,584],{"class":490},[18,1202,1203,1205],{},[21,1204,1131],{}," — Expired JWT:",[123,1207,1209],{"className":782,"code":1208,"language":784,"meta":128,"style":128},"{\n  \"error\": \"Token expired\",\n  \"code\": \"TOKEN_EXPIRED\",\n  \"details\": \"Firebase token has expired. Please refresh and retry.\"\n}\n",[130,1210,1211,1215,1234,1253,1270],{"__ignoreMap":128},[133,1212,1213],{"class":135,"line":136},[133,1214,791],{"class":490},[133,1216,1217,1219,1221,1223,1225,1227,1230,1232],{"class":135,"line":142},[133,1218,506],{"class":490},[133,1220,799],{"class":798},[133,1222,497],{"class":490},[133,1224,779],{"class":490},[133,1226,491],{"class":490},[133,1228,1229],{"class":486},"Token expired",[133,1231,497],{"class":490},[133,1233,813],{"class":490},[133,1235,1236,1238,1240,1242,1244,1246,1249,1251],{"class":135,"line":148},[133,1237,506],{"class":490},[133,1239,130],{"class":798},[133,1241,497],{"class":490},[133,1243,779],{"class":490},[133,1245,491],{"class":490},[133,1247,1248],{"class":486},"TOKEN_EXPIRED",[133,1250,497],{"class":490},[133,1252,813],{"class":490},[133,1254,1255,1257,1259,1261,1263,1265,1268],{"class":135,"line":155},[133,1256,506],{"class":490},[133,1258,839],{"class":798},[133,1260,497],{"class":490},[133,1262,779],{"class":490},[133,1264,491],{"class":490},[133,1266,1267],{"class":486},"Firebase token has expired. Please refresh and retry.",[133,1269,512],{"class":490},[133,1271,1272],{"class":135,"line":161},[133,1273,584],{"class":490},[18,1275,1276,1278],{},[21,1277,1131],{}," — Invalid API key:",[123,1280,1282],{"className":782,"code":1281,"language":784,"meta":128,"style":128},"{\n  \"error\": \"Invalid API key\",\n  \"code\": \"INVALID_API_KEY\",\n  \"details\": \"The provided API key is not valid or has been revoked\"\n}\n",[130,1283,1284,1288,1307,1326,1343],{"__ignoreMap":128},[133,1285,1286],{"class":135,"line":136},[133,1287,791],{"class":490},[133,1289,1290,1292,1294,1296,1298,1300,1303,1305],{"class":135,"line":142},[133,1291,506],{"class":490},[133,1293,799],{"class":798},[133,1295,497],{"class":490},[133,1297,779],{"class":490},[133,1299,491],{"class":490},[133,1301,1302],{"class":486},"Invalid API key",[133,1304,497],{"class":490},[133,1306,813],{"class":490},[133,1308,1309,1311,1313,1315,1317,1319,1322,1324],{"class":135,"line":148},[133,1310,506],{"class":490},[133,1312,130],{"class":798},[133,1314,497],{"class":490},[133,1316,779],{"class":490},[133,1318,491],{"class":490},[133,1320,1321],{"class":486},"INVALID_API_KEY",[133,1323,497],{"class":490},[133,1325,813],{"class":490},[133,1327,1328,1330,1332,1334,1336,1338,1341],{"class":135,"line":155},[133,1329,506],{"class":490},[133,1331,839],{"class":798},[133,1333,497],{"class":490},[133,1335,779],{"class":490},[133,1337,491],{"class":490},[133,1339,1340],{"class":486},"The provided API key is not valid or has been revoked",[133,1342,512],{"class":490},[133,1344,1345],{"class":135,"line":161},[133,1346,584],{"class":490},[93,1348,1350],{"id":1349},"authorization-errors","Authorization Errors",[18,1352,1353,1355],{},[21,1354,1030],{}," — Feature not available on tier:",[123,1357,1359],{"className":782,"code":1358,"language":784,"meta":128,"style":128},"{\n  \"error\": \"Feature access denied\",\n  \"code\": \"FEATURE_TIER_RESTRICTED\",\n  \"details\": \"Advanced analytics requires Pro subscription\",\n  \"upgrade_url\": \"https://profitelligence.com/subscribe\"\n}\n",[130,1360,1361,1365,1384,1403,1422,1438],{"__ignoreMap":128},[133,1362,1363],{"class":135,"line":136},[133,1364,791],{"class":490},[133,1366,1367,1369,1371,1373,1375,1377,1380,1382],{"class":135,"line":142},[133,1368,506],{"class":490},[133,1370,799],{"class":798},[133,1372,497],{"class":490},[133,1374,779],{"class":490},[133,1376,491],{"class":490},[133,1378,1379],{"class":486},"Feature access denied",[133,1381,497],{"class":490},[133,1383,813],{"class":490},[133,1385,1386,1388,1390,1392,1394,1396,1399,1401],{"class":135,"line":148},[133,1387,506],{"class":490},[133,1389,130],{"class":798},[133,1391,497],{"class":490},[133,1393,779],{"class":490},[133,1395,491],{"class":490},[133,1397,1398],{"class":486},"FEATURE_TIER_RESTRICTED",[133,1400,497],{"class":490},[133,1402,813],{"class":490},[133,1404,1405,1407,1409,1411,1413,1415,1418,1420],{"class":135,"line":155},[133,1406,506],{"class":490},[133,1408,839],{"class":798},[133,1410,497],{"class":490},[133,1412,779],{"class":490},[133,1414,491],{"class":490},[133,1416,1417],{"class":486},"Advanced analytics requires Pro subscription",[133,1419,497],{"class":490},[133,1421,813],{"class":490},[133,1423,1424,1426,1428,1430,1432,1434,1436],{"class":135,"line":161},[133,1425,506],{"class":490},[133,1427,1103],{"class":798},[133,1429,497],{"class":490},[133,1431,779],{"class":490},[133,1433,491],{"class":490},[133,1435,1112],{"class":486},[133,1437,512],{"class":490},[133,1439,1440],{"class":135,"line":167},[133,1441,584],{"class":490},[26,1443,1445],{"id":1444},"testing-authentication","Testing Authentication",[93,1447,1449],{"id":1448},"verify-jwt-setup","Verify JWT Setup",[123,1451,1453],{"className":473,"code":1452,"language":475,"meta":128,"style":128},"# Replace with your actual JWT token\ncurl -i -H \"Authorization: Bearer YOUR_JWT_TOKEN\" \\\n  \"https://apollo.profitelligence.com/v1/user-status\"\n",[130,1454,1455,1461,1479],{"__ignoreMap":128},[133,1456,1457],{"class":135,"line":136},[133,1458,1460],{"class":1459},"sHwdD","# Replace with your actual JWT token\n",[133,1462,1463,1465,1468,1470,1472,1475,1477],{"class":135,"line":142},[133,1464,483],{"class":482},[133,1466,1467],{"class":486}," -i",[133,1469,487],{"class":486},[133,1471,491],{"class":490},[133,1473,1474],{"class":486},"Authorization: Bearer YOUR_JWT_TOKEN",[133,1476,497],{"class":490},[133,1478,501],{"class":500},[133,1480,1481,1483,1486],{"class":135,"line":148},[133,1482,506],{"class":490},[133,1484,1485],{"class":486},"https://apollo.profitelligence.com/v1/user-status",[133,1487,512],{"class":490},[18,1489,1490],{},"Successful response includes your user info and tier:",[123,1492,1494],{"className":782,"code":1493,"language":784,"meta":128,"style":128},"{\n  \"user_id\": \"abc123\",\n  \"email\": \"user@example.com\",\n  \"subscription_tier\": \"pro\",\n  \"feature_version\": \"main\",\n  \"available_features\": [\"form4_light\", \"form4_medium\", \"analytics\"]\n}\n",[130,1495,1496,1500,1520,1540,1560,1580,1623],{"__ignoreMap":128},[133,1497,1498],{"class":135,"line":136},[133,1499,791],{"class":490},[133,1501,1502,1504,1507,1509,1511,1513,1516,1518],{"class":135,"line":142},[133,1503,506],{"class":490},[133,1505,1506],{"class":798},"user_id",[133,1508,497],{"class":490},[133,1510,779],{"class":490},[133,1512,491],{"class":490},[133,1514,1515],{"class":486},"abc123",[133,1517,497],{"class":490},[133,1519,813],{"class":490},[133,1521,1522,1524,1527,1529,1531,1533,1536,1538],{"class":135,"line":148},[133,1523,506],{"class":490},[133,1525,1526],{"class":798},"email",[133,1528,497],{"class":490},[133,1530,779],{"class":490},[133,1532,491],{"class":490},[133,1534,1535],{"class":486},"user@example.com",[133,1537,497],{"class":490},[133,1539,813],{"class":490},[133,1541,1542,1544,1547,1549,1551,1553,1556,1558],{"class":135,"line":155},[133,1543,506],{"class":490},[133,1545,1546],{"class":798},"subscription_tier",[133,1548,497],{"class":490},[133,1550,779],{"class":490},[133,1552,491],{"class":490},[133,1554,1555],{"class":486},"pro",[133,1557,497],{"class":490},[133,1559,813],{"class":490},[133,1561,1562,1564,1567,1569,1571,1573,1576,1578],{"class":135,"line":161},[133,1563,506],{"class":490},[133,1565,1566],{"class":798},"feature_version",[133,1568,497],{"class":490},[133,1570,779],{"class":490},[133,1572,491],{"class":490},[133,1574,1575],{"class":486},"main",[133,1577,497],{"class":490},[133,1579,813],{"class":490},[133,1581,1582,1584,1587,1589,1591,1594,1596,1599,1601,1604,1606,1609,1611,1613,1615,1618,1620],{"class":135,"line":167},[133,1583,506],{"class":490},[133,1585,1586],{"class":798},"available_features",[133,1588,497],{"class":490},[133,1590,779],{"class":490},[133,1592,1593],{"class":490}," [",[133,1595,497],{"class":490},[133,1597,1598],{"class":486},"form4_light",[133,1600,497],{"class":490},[133,1602,1603],{"class":490},",",[133,1605,491],{"class":490},[133,1607,1608],{"class":486},"form4_medium",[133,1610,497],{"class":490},[133,1612,1603],{"class":490},[133,1614,491],{"class":490},[133,1616,1617],{"class":486},"analytics",[133,1619,497],{"class":490},[133,1621,1622],{"class":490},"]\n",[133,1624,1625],{"class":135,"line":173},[133,1626,584],{"class":490},[93,1628,1630],{"id":1629},"verify-api-key-setup","Verify API Key Setup",[123,1632,1634],{"className":473,"code":1633,"language":475,"meta":128,"style":128},"curl -i -H \"X-API-Key: YOUR_API_KEY\" \\\n  \"https://apollo.profitelligence.com/v1/company-profile?symbol=AAPL\"\n",[130,1635,1636,1652],{"__ignoreMap":128},[133,1637,1638,1640,1642,1644,1646,1648,1650],{"class":135,"line":136},[133,1639,483],{"class":482},[133,1641,1467],{"class":486},[133,1643,487],{"class":486},[133,1645,491],{"class":490},[133,1647,494],{"class":486},[133,1649,497],{"class":490},[133,1651,501],{"class":500},[133,1653,1654,1656,1658],{"class":135,"line":142},[133,1655,506],{"class":490},[133,1657,509],{"class":486},[133,1659,512],{"class":490},[18,1661,1662,1663,1666],{},"A successful response returns company data. Check the ",[130,1664,1665],{},"X-RateLimit-*"," headers to confirm your tier limits.",[26,1668,1670],{"id":1669},"common-issues","Common Issues",[93,1672,1674],{"id":1673},"token-expired-errors","\"Token expired\" errors",[18,1676,1677,1678,1681],{},"Firebase tokens last 1 hour. Always call ",[130,1679,1680],{},"getIdToken()"," before API requests—the SDK handles refresh automatically.",[93,1683,1685],{"id":1684},"invalid-api-key-errors","\"Invalid API key\" errors",[662,1687,1688,1691,1694],{},[101,1689,1690],{},"Verify the key is copied correctly (no extra spaces)",[101,1692,1693],{},"Check the key hasn't been revoked",[101,1695,1696,1697,1700],{},"Ensure you're using the correct header name (",[130,1698,1699],{},"X-API-Key",")",[93,1702,1704],{"id":1703},"rate-limit-exceeded-unexpectedly","Rate limit exceeded unexpectedly",[662,1706,1707,1710,1713],{},[101,1708,1709],{},"Check if you have multiple services using the same key",[101,1711,1712],{},"Review your code for unnecessary duplicate requests",[101,1714,1715],{},"Consider upgrading your tier for higher limits",[26,1717,1719],{"id":1718},"next-steps","Next Steps",[18,1721,1722],{},"With authentication configured, explore the available endpoints:",[662,1724,1725,1733,1740],{},[101,1726,1727,1732],{},[1728,1729,1731],"a",{"href":1730},"/docs/api/endpoints/company-data","Company Data"," — Profiles, prices, signals",[101,1734,1735,1739],{},[1728,1736,1738],{"href":1737},"/docs/api/endpoints/form4-insider","Form 4 Insider"," — Insider trading data",[101,1741,1742,1746],{},[1728,1743,1745],{"href":1744},"/docs/api/endpoints/fred-economic","FRED Economic"," — Macro indicators",[1748,1749,1750],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":128,"searchDepth":142,"depth":142,"links":1752},[1753,1754,1760,1767,1772,1773,1777,1781,1786],{"id":28,"depth":142,"text":29},{"id":87,"depth":142,"text":88,"children":1755},[1756,1757,1758,1759],{"id":95,"depth":148,"text":96},{"id":115,"depth":148,"text":116},{"id":300,"depth":148,"text":301},{"id":325,"depth":148,"text":326},{"id":436,"depth":142,"text":437,"children":1761},[1762,1763,1764,1765,1766],{"id":443,"depth":148,"text":96},{"id":457,"depth":148,"text":116},{"id":515,"depth":148,"text":516},{"id":587,"depth":148,"text":326},{"id":654,"depth":148,"text":655},{"id":694,"depth":142,"text":695,"children":1768},[1769,1770,1771],{"id":756,"depth":148,"text":757},{"id":771,"depth":148,"text":772},{"id":937,"depth":148,"text":938},{"id":980,"depth":142,"text":981},{"id":1121,"depth":142,"text":1122,"children":1774},[1775,1776],{"id":1125,"depth":148,"text":1126},{"id":1349,"depth":148,"text":1350},{"id":1444,"depth":142,"text":1445,"children":1778},[1779,1780],{"id":1448,"depth":148,"text":1449},{"id":1629,"depth":148,"text":1630},{"id":1669,"depth":142,"text":1670,"children":1782},[1783,1784,1785],{"id":1673,"depth":148,"text":1674},{"id":1684,"depth":148,"text":1685},{"id":1703,"depth":148,"text":1704},{"id":1718,"depth":142,"text":1719},"api","Set up Firebase JWT or API key authentication to access the Profitelligence API","md","intermediate",{"prev":1792},"api/index","api/endpoints/company-data","/docs/api/authentication",[1792,1793],{"title":5,"description":1788},"docs/api/authentication",[1787,1799,1800,1801,1802],"authentication","jwt","api-key","security","KYm90AQRa5BFrITqQTiuTiGzFOZyrBBuyCNh4UTERAw",1785812714620]