Quickstart

Make your first ODEN API call in five minutes. Get a key, send a query, and read the synthesized answer and citations — in curl, Python, JavaScript and TypeScript.

Documentation2 min readUpdated 2026-07-30

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, highest score first (from 0.0 to 1.0).
  • trace_id — unique diagnostic identifier; include it when diagnosing edge cases or reporting issues.
  • cached — boolean true when 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_id header 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#