{"openapi":"3.1.0","info":{"title":"ENTON API","version":"1.0.0","description":"The public ENTON API. Authenticate with an API key from https://enton.ai/developer as a bearer token. Human-readable reference: https://enton.ai/docs. Generated from lib/docs/api-reference.ts."},"servers":[{"url":"https://enton.ai/api/v1"}],"externalDocs":{"url":"https://enton.ai/docs"},"security":[{"bearerAuth":[]}],"tags":[{"name":"AI","description":"Natural-language queries."},{"name":"Trading","description":"Trading cards and order placement."},{"name":"Discovery","description":"Search financial API endpoints."},{"name":"OAuth","description":"Broker and payment connections."},{"name":"Meta","description":"Health and this document."}],"paths":{"/ai/query":{"post":{"operationId":"aiQuery","summary":"Ask a question","description":"Send a question in plain English. The query engine decides which data sources to call, retrieves the data and writes an answer. Integrations you have connected to your ENTON account (API keys and OAuth brokers) are passed to the engine as context.\n\nNotes:\n- answer is an object, not a string. The text is in answer.summary.\n- With \"stream\": true the API returns the same JSON document with Content-Type: text/event-stream and status 200, even when the query failed. Leave stream false.\n- Answers can take several seconds. Set a client timeout of at least 60 seconds.","tags":["AI"],"externalDocs":{"url":"https://enton.ai/docs/ai-query#ai-query"},"x-required-scope":"ai:query","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"The question, up to 2,000 characters.","maxLength":2000},"stream":{"type":"boolean","description":"Leave false. Streaming is not implemented; see the notes below.","default":false},"mode":{"type":"string","description":"Accepted and echoed back in metadata.mode. It does not currently change how the query is answered.","default":"vector-db"}},"required":["query"]},"examples":{"ask-about-a-stock":{"summary":"Ask about a stock","value":{"query":"What is Tesla doing today? Show news and price."}}}}}},"responses":{"200":{"description":"The answer, with any structured data the engine retrieved.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"answer":{"type":"object","properties":{"summary":{"type":"string","description":"The answer as text."},"__textResponse":{"type":"string","description":"The answer text as the engine produced it. Usually equal to summary."},"conversationOnly":{"type":"boolean","description":"True when the engine answered without retrieving data, for example when it needs a clarification."},"displayData":{"type":"object","additionalProperties":true,"description":"Structured data behind the answer (quotes, bars, news). Absent when none was retrieved."}},"additionalProperties":true,"description":"The engine result. Read answer.summary for the text."},"metadata":{"type":"object","properties":{"responseTime":{"type":"integer","description":"Milliseconds this request took, measured by the API."},"cacheHit":{"type":"boolean","description":"Reserved. Currently always false."},"providersUsed":{"type":"array","items":{"type":"string"},"description":"Reserved. Currently always empty."},"mode":{"type":"string","description":"The mode you sent, or \"vector-db\"."},"tokensUsed":{"type":"integer","description":"Reserved. Currently always 0."}},"description":"Request metadata."},"query":{"type":"string","description":"Your question, echoed."}},"required":["answer","metadata","query"]},"examples":{"default":{"summary":"Ask a question","value":{"answer":{"summary":"Apple (AAPL) last traded at ...","__textResponse":"Apple (AAPL) last traded at ...","conversationOnly":false,"displayData":{"type":"quote","symbol":"AAPL"}},"metadata":{"responseTime":2140,"cacheHit":false,"providersUsed":[],"mode":"vector-db","tokensUsed":0},"query":"What is the AAPL price?"}}}}}},"400":{"description":"- query is missing or empty. (\"Missing required field: query\")\n- query is over 2,000 characters. (\"Query too long. Maximum length is 2000 characters\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"- The key has neither \"ai:query\" nor \"*\". (\"Insufficient permissions. Required scope: ai:query\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"- The engine failed, or the body was not valid JSON. An engine error can also arrive with its own message. (\"Failed to process query. Please try again.\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/trading/cards":{"post":{"operationId":"tradingCards","summary":"Generate trading cards","description":"Returns up to `count` trading cards. Each card has a symbol, a BUY or SELL recommendation, a confidence score, price levels, up to three news items and technical indicators. Cards come from the same generator as the Terminal stock deck, without your portfolio as context.\n\nNotes:\n- count is an upper bound. Symbols with no actionable setup are left out rather than returned with empty levels, so a response can hold fewer cards than you asked for, occasionally none. An empty cards array is a valid response.\n- Fields a provider did not supply are left out, never zero-filled. Treat a missing field as unknown. The exceptions are recommendation and confidence, which have the defaults described above.\n- Cards are analysis, not advice, and they are not orders. To trade, use trade execution.\n\nKnown issue: Requests that pass the API-key checks currently fail with 401. This endpoint forwards to an internal route that expects a signed-in session, and the forwarded request does not carry one. The failed call still counts against your rate limit and monthly quota. This page will say so when it is fixed.","tags":["Trading"],"externalDocs":{"url":"https://enton.ai/docs/trading-intelligence#trading-cards"},"x-required-scope":"trading:cards","x-known-issue":"Requests that pass the API-key checks currently fail with 401. This endpoint forwards to an internal route that expects a signed-in session, and the forwarded request does not carry one. The failed call still counts against your rate limit and monthly quota. This page will say so when it is fixed.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer","description":"Most cards to return, 1 to 20. Fewer may come back; see the notes.","default":10,"minimum":1,"maximum":20},"riskTolerance":{"type":"string","description":"Validated and echoed in metadata.riskTolerance. The generator does not currently read it.","enum":["low","medium","high"],"default":"medium"},"buyingPower":{"type":"number","description":"Capital available, 0 to 10,000,000. Validated, then forwarded; the generator does not currently read it.","minimum":0,"maximum":10000000},"excludeSectors":{"type":"array","items":{"type":"string"},"description":"Forwarded; the generator does not currently read it.","default":[]},"preferredSectors":{"type":"array","items":{"type":"string"},"description":"Forwarded; the generator does not currently read it.","default":[]}}},"examples":{"five-cards":{"summary":"Five cards","value":{"count":5,"riskTolerance":"medium","buyingPower":10000}}}}}},"responses":{"200":{"description":"The cards and request metadata.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"cards":{"type":"array","items":{"type":"object","properties":{"symbol":{"type":"string","description":"Ticker."},"companyName":{"type":"string","description":"Company name."},"recommendation":{"type":"string","description":"\"BUY\" or \"SELL\". \"HOLD\" only when the generator returned no direction."},"confidence":{"type":"number","description":"A 0 to 1 signal score from the technical inputs on the card. It is not a calibrated probability and has no floor: values below 0.4 are normal and mean the setup is weak. 0.5 when the generator returned none. Do not size positions from it."},"currentPrice":{"type":"number","description":"Last price."},"targetPrice":{"type":"number","description":"Suggested target."},"stopLoss":{"type":"number","description":"Suggested stop."},"takeProfit":{"type":"number","description":"Suggested take-profit."},"priceChange":{"type":"number","description":"Change on the day."},"priceChangePercent":{"type":"number","description":"Change on the day, in percent."},"analysis":{"type":"string","description":"The written reasoning for the card."},"sentiment":{"type":"string","description":"News sentiment, when available."},"news":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string","description":"Headline."},"summary":{"type":"string","description":"Summary, when the source provides one."},"source":{"type":"string","description":"Publisher or data provider."},"publishedAt":{"type":"string","description":"Publication time as the provider reports it."},"url":{"type":"string","description":"Link to the article.","format":"uri"}}},"description":"Up to three recent items."},"technicalIndicators":{"type":"object","additionalProperties":true,"description":"Indicators the card was built from, such as rsi, macd, movingAverage50, movingAverage200 and volume."},"cardType":{"type":"string","description":"Card kind. \"standard\" unless the generator says otherwise."},"generatedAt":{"type":"string","description":"When the card was built.","format":"date-time"}}},"description":"Zero or more cards."},"metadata":{"type":"object","properties":{"totalCards":{"type":"integer","description":"Number of cards returned."},"responseTime":{"type":"integer","description":"Milliseconds this request took, measured by the API."},"cacheHit":{"type":"boolean","description":"Whether the generator served the deck from cache."},"providersUsed":{"type":"array","items":{"type":"string"},"description":"Data providers the generator reported."},"riskTolerance":{"type":"string","description":"The value you sent."},"environment":{"type":"string","description":"The key's environment.","enum":["live","test"]}},"description":"Request metadata."}},"required":["cards","metadata"]},"examples":{"default":{"summary":"Generate trading cards","value":{"cards":[{"symbol":"AAPL","companyName":"Apple Inc.","recommendation":"BUY","confidence":0.62,"currentPrice":175.43,"targetPrice":184.2,"stopLoss":171.1,"takeProfit":184.2,"analysis":"...","news":[{"title":"...","source":"...","publishedAt":"...","url":"https://example.com/article"}],"technicalIndicators":{"rsi":58.1},"cardType":"standard","generatedAt":"2026-10-23T14:02:11.093Z"}],"metadata":{"totalCards":1,"responseTime":3120,"cacheHit":false,"providersUsed":[],"riskTolerance":"medium","environment":"live"}}}}}}},"400":{"description":"- count is outside 1 to 20. (\"Invalid count. Must be between 1 and 20\")\n- riskTolerance is another value. (\"Invalid riskTolerance. Must be \"low\", \"medium\", or \"high\"\")\n- buyingPower is outside the range. (\"Invalid buyingPower. Must be between 0 and 10,000,000\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"- The key has neither \"trading:cards\" nor \"*\". (\"Insufficient permissions. Required scope: trading:cards\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"- The generator failed, or the body was not valid JSON. (\"Failed to generate trading cards. Please try again.\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/trading/execute":{"post":{"operationId":"tradeExecute","summary":"Prepare or execute a trade","description":"Two calls place one order. The first, with \"action\": \"prepare\", validates the order and returns a confirmation token without placing anything. The second, with \"action\": \"execute\" and that token, sends the order to your connected broker. Orders always go to the live account.\n\nRequires:\n- A live key. Test keys get 403.\n- A Partner plan on the account. Any other plan gets 403.\n- A broker connected to your ENTON account (Alpaca, through OAuth).\n\nNotes:\n- A confirmation token is signed, expires 5 minutes after prepare, and is accepted only for the account it was issued to.\n- Execute places a real order on your live brokerage account. Prepare places nothing.\n\nKnown issue: Requests that pass the API-key checks currently fail with 401. This endpoint forwards to an internal route that expects a signed-in session, and the forwarded request does not carry one. The failed call still counts against your rate limit and monthly quota. This page will say so when it is fixed.","tags":["Trading"],"externalDocs":{"url":"https://enton.ai/docs/trade-execution#trade-execute"},"x-required-scope":"trading:execute","x-known-issue":"Requests that pass the API-key checks currently fail with 401. This endpoint forwards to an internal route that expects a signed-in session, and the forwarded request does not carry one. The failed call still counts against your rate limit and monthly quota. This page will say so when it is fixed.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","description":"Which step this call is.","enum":["prepare","execute"]},"symbol":{"type":"string","description":"Prepare only, required. Ticker, for example \"AAPL\". Upper-cased for you."},"side":{"type":"string","description":"Prepare only, required.","enum":["buy","sell"]},"quantity":{"type":"number","description":"Prepare only, required. Shares, more than 0 and at most 10,000.","maximum":10000,"exclusiveMinimum":0},"orderType":{"type":"string","description":"Prepare only.","enum":["market","limit"],"default":"market"},"limitPrice":{"type":"number","description":"Prepare only. Required when orderType is \"limit\"."},"protection":{"type":"object","properties":{"stopLoss":{"type":"number","description":"0.01 (1%) to 0.50 (50%).","default":0.05,"minimum":0.01,"maximum":0.5},"takeProfit":{"type":"number","description":"0.01 (1%) to 1.00 (100%).","default":0.1,"minimum":0.01,"maximum":1}},"description":"Prepare only. Stop-loss and take-profit distances as fractions of the entry price."},"confirmationToken":{"type":"string","description":"Execute only, required. The token from prepare. It expires 5 minutes after it was issued."}},"required":["action"]},"examples":{"step-1-prepare":{"summary":"Step 1: prepare","value":{"action":"prepare","symbol":"AAPL","side":"buy","quantity":10,"orderType":"market","protection":{"stopLoss":0.05,"takeProfit":0.1}}},"step-2-execute":{"summary":"Step 2: execute","value":{"action":"execute","confirmationToken":"<token from step 1>"}}}}}},"responses":{"200":{"description":"The prepared order and its confirmation token. Nothing has been sent to the broker. The broker order, as the broker reported it.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"oneOf":[{"title":"prepare","description":"The prepared order and its confirmation token. Nothing has been sent to the broker.","type":"object","properties":{"action":{"type":"string","description":"\"prepare\".","enum":["prepare"]},"preparedOrder":{"type":"object","properties":{"symbol":{"type":"string","description":"Ticker."},"side":{"type":"string","description":"\"buy\" or \"sell\"."},"quantity":{"type":"number","description":"Shares."},"orderType":{"type":"string","description":"\"market\" or \"limit\"."},"limitPrice":{"type":"number","description":"Limit price, for limit orders."},"estimatedCost":{"type":"number","description":"Quantity times the reference price."},"protectionOrders":{"type":"object","properties":{"stopLoss":{"type":"number","description":"Stop price."},"takeProfit":{"type":"number","description":"Take-profit price."},"stopLossPercent":{"type":"number","description":"The fraction you sent, or 0.05."},"takeProfitPercent":{"type":"number","description":"The fraction you sent, or 0.10."}},"description":"Protective levels."},"confirmationToken":{"type":"string","description":"Pass this to execute."},"expiresAt":{"type":"string","description":"When the token stops working.","format":"date-time"},"message":{"type":"string","description":"Status text."}},"description":"The order as it will be placed."}},"required":["action","preparedOrder"]},{"title":"execute","description":"The broker order, as the broker reported it.","type":"object","properties":{"action":{"type":"string","description":"\"execute\".","enum":["execute"]},"success":{"type":"boolean","description":"Whether the broker accepted the order."},"order":{"type":"object","properties":{"orderId":{"type":"string","description":"The broker's order id."},"symbol":{"type":"string","description":"Ticker."},"side":{"type":"string","description":"\"buy\" or \"sell\"."},"quantity":{"type":"number","description":"Shares ordered."},"orderType":{"type":"string","description":"Order type."},"status":{"type":"string","description":"Broker status, for example \"accepted\" or \"filled\"."},"filledPrice":{"type":"number","description":"Average fill price, once filled."},"filledQuantity":{"type":"number","description":"Shares filled so far."},"submittedAt":{"type":"string","description":"Submission time."},"filledAt":{"type":"string","description":"Fill time, once filled."}},"description":"The order."},"protectionOrders":{"type":"object","additionalProperties":true,"description":"Status of the stop-loss and take-profit orders. Each is { \"status\": \"pending\" } until the broker reports otherwise."},"message":{"type":"string","description":"Status text."},"metadata":{"type":"object","properties":{"responseTime":{"type":"integer","description":"Milliseconds this request took, measured by the API."},"environment":{"type":"string","description":"Always \"live\".","enum":["live"]}},"description":"Request metadata."}},"required":["action","success","order","message","metadata"]}]},"examples":{"prepare":{"summary":"prepare","value":{"action":"prepare","preparedOrder":{"symbol":"AAPL","side":"buy","quantity":10,"orderType":"market","estimatedCost":1754.3,"protectionOrders":{"stopLoss":166.66,"takeProfit":192.97,"stopLossPercent":0.05,"takeProfitPercent":0.1},"confirmationToken":"<confirmation token>","expiresAt":"2026-10-23T14:07:11.000Z","message":"Order prepared successfully"}}},"execute":{"summary":"execute","value":{"action":"execute","success":true,"order":{"orderId":"<broker order id>","symbol":"AAPL","side":"buy","quantity":10,"orderType":"market","status":"accepted","submittedAt":"2026-10-23T14:03:02.000Z"},"protectionOrders":{"stopLoss":{"status":"pending"},"takeProfit":{"status":"pending"}},"message":"Order executed successfully","metadata":{"responseTime":1820,"environment":"live"}}}}}}},"400":{"description":"- action is missing or another value. (\"Invalid action. Must be \"prepare\" or \"execute\"\")\n- Prepare without one of them. (\"Missing required fields: symbol, side, quantity\")\n- side is another value. (\"Invalid side. Must be \"buy\" or \"sell\"\")\n- quantity is 0 or less, or over 10,000. (\"Invalid quantity. Must be between 1 and 10,000\")\n- orderType is another value. (\"Invalid orderType. Must be \"market\" or \"limit\"\")\n- orderType is \"limit\" without limitPrice. (\"Limit price is required for limit orders\")\n- protection.stopLoss is out of range. (\"Stop loss percentage must be between 0.01 (1%) and 0.50 (50%)\")\n- protection.takeProfit is out of range. (\"Take profit percentage must be between 0.01 (1%) and 1.00 (100%)\")\n- Execute without a token. (\"Missing confirmationToken. First call with action:\"prepare\" to get a token.\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"- The key is a test key. (\"Test API keys cannot execute real trades. Use a live API key for trading.\")\n- The account is not on the Partner plan. (\"Live trading requires a Partner subscription ($99/mo). Upgrade at enton.ai/pricing.\")\n- The key has neither \"trading:execute\" nor \"*\". (\"Insufficient permissions. Required scope: trading:execute\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"- Anything unexpected, including a body that is not valid JSON. (\"Failed to process trade. Please try again.\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/discover":{"post":{"operationId":"discoverEndpoints","summary":"Search endpoints","description":"Describe what you need in plain English and get the closest matches from ENTON's index of financial API endpoints. The query is embedded and compared against the index by vector similarity, highest score first.","tags":["Discovery"],"externalDocs":{"url":"https://enton.ai/docs/api-discovery#discover-endpoints"},"x-required-scope":"api:discover","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string","description":"What you want to do, up to 500 characters.","maxLength":500},"topK":{"type":"integer","description":"Number of matches to return, 1 to 50.","default":10,"minimum":1,"maximum":50},"minScore":{"type":"number","description":"Validated and echoed. Matches are not currently filtered by it; filter on score yourself.","default":0.7,"minimum":0,"maximum":1}},"required":["query"]},"examples":{"find-historical-prices":{"summary":"Find historical prices","value":{"query":"get historical stock prices","topK":5}}}}}},"responses":{"200":{"description":"Matching endpoints, highest score first.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"endpoints":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string","description":"Provider id, for example \"alpaca\"."},"providerName":{"type":"string","description":"Display name, or the id."},"path":{"type":"string","description":"The provider's endpoint path."},"method":{"type":"string","description":"HTTP method. \"GET\" when the index has none."},"description":{"type":"string","description":"What the endpoint does."},"score":{"type":"number","description":"Similarity, 0 to 1."},"relevance":{"type":"string","description":"high above 0.9, medium above 0.7, low otherwise.","enum":["high","medium","low"]},"available":{"type":"boolean","description":"True when you have connected this provider to your ENTON account, or when you have connected none at all."},"requiresAuth":{"type":"boolean","description":"Currently always true."},"authType":{"type":"string","description":"How the provider authenticates: \"apiKey\" or \"oauth\"."},"documentation":{"type":"string","description":"Link to the provider's docs, when indexed."},"exampleRequest":{"type":"object","additionalProperties":true,"description":"Example request, when indexed."},"exampleResponse":{"type":"object","additionalProperties":true,"description":"Example response, when indexed."},"requiredParams":{"type":"array","items":{"type":"string"},"description":"Required parameters, when indexed."},"optionalParams":{"type":"array","items":{"type":"string"},"description":"Optional parameters, when indexed."},"rateLimit":{"type":"string","description":"Provider rate limit, or \"Unknown\"."},"categories":{"type":"array","items":{"type":"string"},"description":"Currently always empty."},"tags":{"type":"array","items":{"type":"string"},"description":"Currently always empty."}}},"description":"Matches."},"metadata":{"type":"object","properties":{"totalFound":{"type":"integer","description":"Number of matches returned."},"query":{"type":"string","description":"Your query."},"topK":{"type":"integer","description":"The topK used."},"minScore":{"type":"number","description":"The minScore you sent."},"responseTime":{"type":"integer","description":"Milliseconds this request took, measured by the API."},"searchMethod":{"type":"string","description":"\"semantic\"."},"providersSearched":{"type":"array","items":{"type":"string"},"description":"Providers that appear in the matches."}},"description":"Request metadata."}},"required":["endpoints","metadata"]},"examples":{"default":{"summary":"Search endpoints","value":{"endpoints":[{"provider":"alpaca","providerName":"alpaca","path":"/v2/stocks/{symbol}/bars","method":"GET","description":"...","score":0.91,"relevance":"high","available":true,"requiresAuth":true,"authType":"oauth","requiredParams":[],"optionalParams":[],"rateLimit":"Unknown","categories":[],"tags":[]}],"metadata":{"totalFound":1,"query":"historical stock prices","topK":5,"minScore":0.7,"responseTime":640,"searchMethod":"semantic","providersSearched":["alpaca"]}}}}}}},"400":{"description":"- query is missing or empty. (\"Missing required field: query\")\n- query is over 500 characters. (\"Query too long. Maximum length is 500 characters\")\n- topK is out of range. (\"Invalid topK. Must be between 1 and 50\")\n- minScore is out of range. (\"Invalid minScore. Must be between 0 and 1\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"- The key has neither \"api:discover\" nor \"*\". (\"Insufficient permissions. Required scope: api:discover\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"- The search failed, or the body was not valid JSON. (\"Failed to discover APIs. Please try again.\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listDiscoveryProviders","summary":"List discovery providers","description":"A fixed list of the data providers discovery describes, with how each one authenticates. Needs a valid key; no scope is checked.","tags":["Discovery"],"externalDocs":{"url":"https://enton.ai/docs/api-discovery#list-discovery-providers"},"responses":{"200":{"description":"The providers.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"providers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Provider id."},"displayName":{"type":"string","description":"Display name."},"description":{"type":"string","description":"What it offers."},"categories":{"type":"array","items":{"type":"string"},"description":"Data categories."},"authRequired":{"type":"boolean","description":"Whether you must connect it yourself."},"authType":{"type":"string","description":"\"oauth\" or \"apiKey\"."}}},"description":"Providers."},"totalProviders":{"type":"integer","description":"Length of providers."}},"required":["providers","totalProviders"]},"examples":{"default":{"summary":"List discovery providers","value":{"providers":[{"name":"alpaca","displayName":"Alpaca","description":"Stock and crypto trading","categories":["trading","stocks","crypto"],"authRequired":true,"authType":"oauth"},{"name":"finnhub","displayName":"Finnhub","description":"Market data and news","categories":["market-data","news","fundamentals"],"authRequired":false,"authType":"apiKey"}],"totalProviders":5}}}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/oauth/providers":{"get":{"operationId":"listOAuthProviders","summary":"List providers","description":"The OAuth providers ENTON lists, each with whether your account has connected it.\n\nNotes:\n- The list still includes Plaid, which ENTON removed in June 2026. GET /oauth/plaid returns 400. Only alpaca and paypal can be connected.","tags":["OAuth"],"externalDocs":{"url":"https://enton.ai/docs/oauth-service#list-oauth-providers"},"x-required-scope":"oauth:read","responses":{"200":{"description":"Providers and connection counts.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"providers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Provider id."},"name":{"type":"string","description":"Display name."},"description":{"type":"string","description":"What it offers."},"categories":{"type":"array","items":{"type":"string"},"description":"Categories."},"features":{"type":"array","items":{"type":"string"},"description":"Feature list."},"authType":{"type":"string","description":"\"oauth\"."},"authUrl":{"type":"string","description":"The path that starts the connection."},"requiredScopes":{"type":"array","items":{"type":"string"},"description":"The provider's own scopes."},"connected":{"type":"boolean","description":"Whether your account has a token or OAuth key for it."},"lastConnected":{"type":["string","null"],"description":"When it was connected, or null.","format":"date-time"}}},"description":"Providers."},"totalProviders":{"type":"integer","description":"Length of providers."},"connectedProviders":{"type":"integer","description":"How many are connected."},"availableProviders":{"type":"integer","description":"How many are not."}},"required":["providers","totalProviders","connectedProviders","availableProviders"]},"examples":{"default":{"summary":"List providers","value":{"providers":[{"id":"alpaca","name":"Alpaca","description":"Stock and crypto trading with commission-free access","categories":["trading","stocks","crypto"],"features":["Real-time market data","Commission-free trading","Paper trading environment","Extended hours trading"],"authType":"oauth","authUrl":"/api/v1/oauth/alpaca","requiredScopes":["account:read","trading","data"],"connected":true,"lastConnected":"2026-09-14T17:20:05.000Z"}],"totalProviders":3,"connectedProviders":1,"availableProviders":2}}}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"- The key has neither \"oauth:read\" nor \"*\". (\"Insufficient permissions. Required scope: oauth:read\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"- The lookup failed. (\"Failed to list OAuth providers.\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/oauth/{provider}":{"get":{"operationId":"startOAuth","summary":"Start a connection","description":"Starts the provider's OAuth flow for the account that owns the key. On success the response is a redirect to the provider's authorization page. After the user approves, the provider calls back to ENTON, which exchanges the code and stores the tokens, encrypted, against the account.\n\nNotes:\n- The call needs your API key in the Authorization header, so make it from your server and send the user to the Location it returns. A plain browser link cannot add the header.\n\nKnown issue: Requests that pass the API-key checks currently fail with 401. This endpoint forwards to an internal route that expects a signed-in session, and the forwarded request does not carry one. The failed call still counts against your rate limit and monthly quota. This page will say so when it is fixed.","tags":["OAuth"],"externalDocs":{"url":"https://enton.ai/docs/oauth-service#start-oauth"},"x-required-scope":"oauth:connect","x-known-issue":"Requests that pass the API-key checks currently fail with 401. This endpoint forwards to an internal route that expects a signed-in session, and the forwarded request does not carry one. The failed call still counts against your rate limit and monthly quota. This page will say so when it is fixed.","parameters":[{"name":"provider","in":"path","required":true,"description":"Provider id. \"coinbase\" returns 410.","schema":{"type":"string","enum":["alpaca","paypal"]}},{"name":"redirect","in":"query","required":false,"description":"Where to send the user afterwards. redirect_uri is accepted as an alias.","schema":{"type":"string"}},{"name":"state","in":"query","required":false,"description":"Opaque value passed through to the flow.","schema":{"type":"string"}}],"responses":{"307":{"description":"A redirect to the provider's authorization page (Location header). If the provider returns no URL, a 200 JSON body with provider, authorizationUrl, state and message instead.","headers":{"Location":{"description":"The provider's authorization URL.","schema":{"type":"string","format":"uri"}}}},"400":{"description":"- provider is not alpaca or paypal. (\"Invalid provider. Supported providers: alpaca, paypal\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"- The key has neither \"oauth:connect\" nor \"*\". (\"Insufficient permissions. Required scope: oauth:connect\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"- provider is coinbase. (\"Coinbase integration is currently disabled\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"- Starting the flow failed. The message names the provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/oauth/{provider}/status":{"get":{"operationId":"oauthStatus","summary":"Check a connection","description":"Whether the account that owns the key has connected the provider, and whether its tokens have expired.\n\nNotes:\n- Alpaca stores one token per environment you authorized (paper and live), so accounts can be 2 for one Alpaca login.","tags":["OAuth"],"externalDocs":{"url":"https://enton.ai/docs/oauth-service#oauth-status"},"x-required-scope":"oauth:read","parameters":[{"name":"provider","in":"path","required":true,"description":"Provider id. \"coinbase\" returns 410.","schema":{"type":"string","enum":["alpaca","paypal"]}}],"responses":{"200":{"description":"Connection status.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"}},"content":{"application/json":{"schema":{"type":"object","properties":{"connected":{"type":"boolean","description":"Whether any token or OAuth key exists for the provider."},"provider":{"type":"string","description":"The provider you asked about."},"status":{"type":"string","description":"\"expired\" when every stored token is past its expiry.","enum":["active","expired","disconnected"]},"accounts":{"type":"integer","description":"Stored tokens plus OAuth keys."},"activeAccounts":{"type":"integer","description":"Tokens that have not expired."},"lastConnected":{"type":["string","null"],"description":"Newest connection time, or null.","format":"date-time"},"needsRefresh":{"type":"boolean","description":"True when connected but every token has expired. Reconnect."},"connections":{"type":"object","properties":{"oauthTokens":{"type":"integer","description":"OAuth tokens stored."},"oauthApiKeys":{"type":"integer","description":"OAuth-backed keys stored."}},"description":"Counts by kind."}},"required":["connected","provider","status","accounts","activeAccounts","lastConnected","needsRefresh","connections"]},"examples":{"default":{"summary":"Check a connection","value":{"connected":true,"provider":"alpaca","status":"active","accounts":2,"activeAccounts":2,"lastConnected":"2026-09-14T17:20:05.000Z","needsRefresh":false,"connections":{"oauthTokens":2,"oauthApiKeys":0}}}}}}},"400":{"description":"- provider is not alpaca or paypal. (\"Invalid provider. Supported providers: alpaca, paypal\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"- No Authorization header. (\"Missing Authorization header. Include \"Authorization: Bearer enton_live_xxx\" or \"Authorization: Bearer enton_test_xxx\"\")\n- The header does not start with \"Bearer \". (\"Invalid Authorization format. Use \"Bearer enton_live_xxx\" or \"Bearer enton_test_xxx\"\")\n- The token does not start with \"enton_\". (\"Invalid API key format. Keys must start with \"enton_live_\" or \"enton_test_\"\")\n- No active key matches. (\"Invalid or inactive API key\")\n- The account that owns the key has no active Trader or Partner plan (a trial counts). (\"Active subscription required. Please upgrade your plan at https://enton.ai/pricing\")\n- The key has used its monthly quota. Quotas reset at 00:00 UTC on the first of the month. (\"Monthly quota exceeded. Please upgrade your plan or wait until next month.\")\n- The key lookup itself failed. (\"Internal server error during authentication\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"- The key has neither \"oauth:read\" nor \"*\". (\"Insufficient permissions. Required scope: oauth:read\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"- provider is coinbase. (\"Coinbase integration is currently disabled\")","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"- The key made its per-minute limit of requests in the last 60 seconds. Sent with Retry-After: 60. (\"Rate limit exceeded. Please wait before making more requests.\")","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"- The lookup failed. The message names the provider.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/health":{"get":{"operationId":"health","summary":"Health check","description":"Reports whether the API is up and can reach its database. No key needed; it does not count against any limit.","tags":["Meta"],"externalDocs":{"url":"https://enton.ai/docs/health#health"},"security":[],"responses":{"200":{"description":"Healthy (200) or degraded (503, database unreachable). Both use this shape.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"\"degraded\" when the database check failed.","enum":["healthy","degraded"]},"timestamp":{"type":"string","description":"Server time.","format":"date-time"},"version":{"type":"string","description":"Server API version."},"environment":{"type":"string","description":"Server environment, \"production\" on enton.ai."},"services":{"type":"object","properties":{"database":{"type":"string","description":"Database reachability.","enum":["operational","down"]},"api":{"type":"string","description":"Always \"operational\" when this responds.","enum":["operational"]}},"description":"Per-service status."},"endpoints":{"type":"object","additionalProperties":true,"description":"Paths of the main endpoints."},"documentation":{"type":"string","description":"Link to these docs.","format":"uri"},"developer":{"type":"string","description":"Link to the developer portal.","format":"uri"}},"required":["status","timestamp","version","environment","services","endpoints","documentation","developer"]},"examples":{"default":{"summary":"Health check","value":{"status":"healthy","timestamp":"2026-10-23T14:02:11.093Z","version":"v1.0.0","environment":"production","services":{"database":"operational","api":"operational"},"endpoints":{"ai":"/api/v1/ai/query","trading":"/api/v1/trading/cards","execute":"/api/v1/trading/execute","discovery":"/api/v1/discover","oauth":"/api/v1/oauth/[provider]"},"documentation":"https://enton.ai/docs","developer":"https://enton.ai/developer"}}}}}},"503":{"description":"- The database is unreachable (status \"degraded\"), or the check itself failed (status \"error\", with message and error fields).","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}}}},"/openapi.json":{"get":{"operationId":"openapi","summary":"OpenAPI document","description":"This API described as OpenAPI 3.1, built from the same source as these pages. Import it into Postman, Insomnia or a client generator. No key needed.","tags":["Meta"],"externalDocs":{"url":"https://enton.ai/docs/health#openapi"},"security":[],"responses":{"200":{"description":"An OpenAPI 3.1 document.","content":{"application/json":{"schema":{"type":"object","properties":{"openapi":{"type":"string","description":"\"3.1.0\"."},"info":{"type":"object","additionalProperties":true,"description":"Title and version."},"servers":{"type":"array","items":{"type":"object"},"description":"Base URL."},"paths":{"type":"object","additionalProperties":true,"description":"Every public endpoint."},"components":{"type":"object","additionalProperties":true,"description":"Shared schemas, responses and the bearer scheme."}},"required":["openapi","info","servers","paths","components"]},"examples":{"default":{"summary":"OpenAPI document","value":{"openapi":"3.1.0","info":{"title":"ENTON API","version":"1.0.0"},"servers":[{"url":"https://enton.ai/api/v1"}],"paths":{},"components":{}}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"An ENTON API key: enton_live_... or enton_test_..."}},"headers":{"X-RateLimit-Limit":{"description":"Requests per minute allowed for this key.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests left in the current 60-second window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"ISO 8601 time 60 seconds after this request.","schema":{"type":"string"}},"X-API-Key-Name":{"description":"The name you gave the key. Sent on successful authentication only.","schema":{"type":"string"}},"X-API-Key-Tier":{"description":"The plan the key was created under. Sent on successful authentication only.","schema":{"type":"string"}},"Retry-After":{"description":"Seconds to wait. Sent with 429 only, always 60.","schema":{"type":"integer"}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable message. Match on the status code, not on this text."},"status":{"type":"integer","description":"The HTTP status code, repeated."},"timestamp":{"type":"string","description":"When the error was produced.","format":"date-time"}},"required":["error","status","timestamp"],"examples":[{"error":"Insufficient permissions. Required scope: ai:query","status":403,"timestamp":"2026-10-23T14:02:11.093Z"}]}}}}