This is the shortest path from nothing to a working call. It takes about five minutes.
1. Get an API key#
Sign in at oden-api.com/app and generate a key from the dashboard. Every account starts on the free tier: 1,000 searches a month, no credit card. Keys look like oden_live_….
Keep the key server-side. Anyone who has it can spend your quota, so put it in an environment variable rather than in your source code:
export ODEN_KEY="oden_live_your_key_here"
Storing keys in .env files#
For local development across Node.js, Python, or Go projects, store your secret in a local .env file placed in your project root:
# .env file (ensure this is added to .gitignore)
ODEN_KEY=oden_live_your_secret_key_here
ODEN_API_BASE=https://api.oden-api.com
Load it in Python with python-dotenv (load_dotenv()) or in Node.js 20+ natively using node --env-file=.env app.js.
2. Make your first call#
Send a query to POST /search. That is the whole API.
curl https://api.oden-api.com/search \
-H "Authorization: Bearer $ODEN_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "What are the symptoms of vitamin D deficiency?"}'
Windows PowerShell#
On Windows PowerShell, the native curl alias often mangles inner quotation marks in JSON payloads. Use Invoke-RestMethod with native hash tables to avoid escaping issues:
$headers = @{
"Authorization" = "Bearer $env:ODEN_KEY"
"Content-Type" = "application/json"
}
$body = @{
query = "What are the symptoms of vitamin D deficiency?"
answer = $true
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri "https://api.oden-api.com/search" -Method Post -Headers $headers -Body $body
Write-Output $response.results.answer
$response.results.citations | ForEach-Object { Write-Output "- $($_.title) ($($_.url))" }
Python (requests)#
The same call in Python (standard library plus requests):
import os, requests
resp = requests.post(
"https://api.oden-api.com/search",
headers={"Authorization": f"Bearer {os.environ['ODEN_KEY']}"},
json={"query": "What are the symptoms of vitamin D deficiency?", "answer": True},
timeout=30,
)
resp.raise_for_status()
data = resp.json()
print(data["results"]["answer"])
for c in data["results"]["citations"]:
print(f"- {c['title']} ({c['url']})")
JavaScript / Node.js#
In JavaScript / Node (18+, built-in fetch):
const resp = await fetch("https://api.oden-api.com/search", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.ODEN_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query: "What are the symptoms of vitamin D deficiency?", answer: true }),
});
if (!resp.ok) throw new Error(`ODEN ${resp.status}`);
const data = await resp.json();
console.log(data.results.answer);
TypeScript#
In TypeScript, with full static typing for the API contract:
interface OdenCitation { title: string; url: string; score: number; snippet?: string }
interface OdenResponse {
query: string;
trace_id: string;
cached: boolean;
results: { answer?: string; citations: OdenCitation[] };
}
async function search(query: string): Promise<OdenResponse> {
const resp = await fetch("https://api.oden-api.com/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ODEN_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ query }),
});
if (!resp.ok) throw new Error(`ODEN request failed: ${resp.status}`);
return resp.json() as Promise<OdenResponse>;
}
3. Read the response#
You get the synthesized answer and the ranked sources in one clean JSON object:
{
"query": "What are the symptoms of vitamin D deficiency?",
"trace_id": "oden-mquycpae-p3thrk",
"cached": false,
"results": {
"answer": "Low vitamin D can cause muscle weakness, bone pain and fatigue, and in severe cases rickets in children or osteomalacia in adults. Mild deficiency is often symptom-free and found only through a blood test.",
"citations": [
{ "title": "Vitamin D deficiency — 1177 Vårdguiden", "url": "https://www.1177.se/...", "score": 0.912 }
]
}
}
results.answer— the synthesized answer, rendered in the same natural language as your query.results.citations— the ranked source list, highestscorefirst (from 0.0 to 1.0).trace_id— unique diagnostic identifier; include it when diagnosing edge cases or reporting issues.cached— booleantruewhen the query was served from edge cache in tens of milliseconds.
Production checklist#
Before deploying your integration into user-facing production workflows:
- Configure explicit timeouts: Set network timeouts between 15 and 30 seconds to handle network latency gracefully.
- Implement retry backoff: Catch HTTP 429 status codes and apply exponential backoff with jitter. Do not retry HTTP 403 — that means the monthly quota is spent and will not clear until the next month.
- Log trace identifiers: Capture the
trace_idheader on every outbound request to assist with audit logging and latency monitoring. - Prune citations by score: Discard citations with confidence scores below 0.60 to maintain high context precision.
Next steps#
- Tune the call with the search parameters —
answer,depthandinclude_snippets. - Understand answers and citations in depth.
- Handle rate limits and errors before you go to production.
- Wire ODEN into a RAG pipeline or OpenAI function calling.