Developer docs

Hanova AI APIs & MCP

Run Hanova AI's research-writing workflow from your own code, or connect it to ChatGPT or Claude over MCP and let the assistant drive it: create projects, run the ten steps, read and refine the output, ask the research assistant and export the paper.

Overview

  • Base URL: https://hanovaai.com/api/v1
  • Format: JSON in and out (file downloads and uploads excepted), UTF-8, ISO 8601 timestamps in UTC.
  • Same rules as the website: every call acts as your account, uses your credits and follows your account's limits. Papers come only from the literature step; the API can't invent citations either.
  • Machine-readable spec: OpenAPI 3.1 (use it to generate a client) and the interactive reference.

Quick start

1. Create a key on Credits & usage → API keys. It starts with hk_live_ and is shown once.

2. Check it works:

export HANOVA_API_KEY="hk_live_..."
curl https://hanovaai.com/api/v1/me -H "Authorization: Bearer $HANOVA_API_KEY"
{
  "account_type": "payg",
  "credits": 412.5,
  "email": "you@university.edu",
  "limits": { "export": true, "qualities": ["low", "moderate", "premium"], "steps": "all", ... }
}

Authentication

Send your key on every request as a bearer token:

Authorization: Bearer hk_live_...
  • Keys act as your account, so treat them like a password. Create one per app or device so you can revoke it on its own.
  • Only a fingerprint of each key is stored; a lost key can't be shown again, so create a new one and revoke the old.
  • The API never uses your website login cookie, and buying credits is only possible on the website.

Credits & limits

The API uses the same pay-as-you-go credits as the website (1 credit = ₹1). Each action is charged what it actually uses; GET /projects/{id} returns credit_estimates, the typical credits for one run of each step on the project's quality level. A run needs at least that many credits to start.

Free accounts (no credit pack bought yet) can run the research steps only (topic, literature, analysis), on Fast or Balanced quality, with 3 chat messages and no downloads. Your first pack unlocks everything. See Pricing.

Errors

Errors always have the same shape, with a stable code to branch on and a message you can show to people:

{ "error": { "code": "insufficient_credits",
             "message": "This needs about 124 credits and you have 10. Buy credits on the Pricing page ...",
             "details": { "credits_needed": 124, "credits": 10 } } }
HTTPcodeMeaning
400invalid_requestMissing or invalid input; the message says what to fix.
401unauthorizedMissing, unknown or revoked API key.
402insufficient_creditsNot enough credits for this run; details has credits_needed and credits.
402feature_lockedA step, Premium quality, downloads or web search that unlocks with any credit pack.
404not_foundNo such project, step or endpoint (or not yours).
409conflictE.g. the step is already running, or there is nothing to export yet.
429rate_limitedToo many requests; wait for the Retry-After header.
500/502server_errorSomething failed on our side or at the AI provider; retry. Quote X-Request-Id to support.

Rate limits

Each key can make 120 requests per minute. Over the limit you get 429 rate_limited with a Retry-After header in seconds. Polling a running step every 3–5 seconds is plenty. Every response carries an X-Request-Id; include it when you contact support.

Write a paper: a walkthrough

The ten steps run in order: topic → literature → analysis → methodology → outline → writing → polish → figures → review → final. Running a step is asynchronous: POST …/run returns 202 at once; poll …/status until it is ready, read it with GET …/steps/{key}, then approve it and move on.

Python

import os, time, requests

API = "https://hanovaai.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['HANOVA_API_KEY']}"}

def call(method, path, **kw):
    r = requests.request(method, API + path, headers=H, timeout=60, **kw)
    if r.status_code == 429:                      # rate limited: wait and retry
        time.sleep(int(r.headers.get("Retry-After", 5))); return call(method, path, **kw)
    if r.status_code >= 400:
        raise RuntimeError(r.json()["error"])
    return r.json() if "json" in r.headers.get("Content-Type", "") else r.content

def run(pid, key, inputs=None):
    call("POST", f"/projects/{pid}/steps/{key}/run", json={"inputs": inputs or {}})
    while (s := call("GET", f"/projects/{pid}/steps/{key}/status"))["status"] == "running":
        time.sleep(4)
    if s["status"] == "error":
        raise RuntimeError(s["error"])
    call("POST", f"/projects/{pid}/steps/{key}/approve")
    return call("GET", f"/projects/{pid}/steps/{key}")

project = call("POST", "/projects", json={
    "name": "Rutting prediction with ML",
    "goal": "How accurately can machine-learning models predict rut depth in asphalt pavements?",
    "paper_type": "journal-imrad", "citation_style": "apa7", "quality": "moderate"})
pid = project["id"]
print("Estimated credits per step:", project["credit_estimates"])

run(pid, "topic")
run(pid, "literature", {"filters": {"year_from": 2018, "min_citations": 5, "max_results": 40}})
papers = call("GET", f"/projects/{pid}/literature")["data"]
print(len(papers), "papers found;", sum(p["selected"] for p in papers), "selected")

for key in ["analysis", "methodology", "outline", "writing", "polish", "figures", "review", "final"]:
    step = run(pid, key)
    print(f"{key}: {step['words']} words")

open("paper.docx", "wb").write(call("GET", f"/projects/{pid}/export", params={"format": "docx"}))

Refine a passage

curl -X POST https://hanovaai.com/api/v1/projects/$PID/steps/writing/refine \
  -H "Authorization: Bearer $HANOVA_API_KEY" -H "Content-Type: application/json" \
  -d '{"instruction": "Make this more concise", "selection": "Rutting remains a leading cause of ..."}'

Ask the assistant

curl -X POST https://hanovaai.com/api/v1/chat -H "Authorization: Bearer $HANOVA_API_KEY" -H "Content-Type: application/json" \
  -d '{"message": "Which of my papers used LTPP data?", "project_id": "'$PID'", "library": true}'

Endpoints

Full request and response schemas are in the interactive reference.

MethodPathWhat it does
GET/meYour account, credits and limits
GET/usageCredit history
GET/projectsList projects
POST/projectsCreate a project
GET/projects/{id}Project, step statuses, credit estimates
PATCH/projects/{id}Change citation style, quality or paper type
DELETE/projects/{id}Delete a project
POST/projects/{id}/steps/{key}/runRun a step (async, 202)
GET/projects/{id}/steps/{key}/statusProgress of a step
GET/projects/{id}/steps/{key}Read a step (Markdown + data)
PATCH/projects/{id}/steps/{key}Edit a step or approve it
POST/projects/{id}/steps/{key}/approveApprove a step
POST/projects/{id}/steps/{key}/refineRewrite a passage with an instruction
GET/projects/{id}/literaturePapers found
POST/projects/{id}/literature/selectSelect or deselect papers
GET/projects/{id}/export?format=docxDownload (docx, pdf, tex, md, html, txt)
POST/chatAsk the research assistant
GET/libraryYour documents
POST/libraryUpload a document (multipart)
GET/stepsThe ten steps (public)
GET/citation-stylesThe 21 styles (public)
GET/paper-typesPaper types (public)

MCP: connect ChatGPT and Claude

Hanova AI runs an MCP server at https://hanovaai.com/mcp (Streamable HTTP). Add it to your AI assistant once, and you can work on your research from the chat: “Start a review paper on rutting prediction, run the literature search and tell me the research gap.”

  • ChatGPT and claude.ai connect by signing in: you approve the connection on a Hanova AI page, and no key is needed.
  • Claude Code and other MCP clients can sign in the same way, or send an API key.
  • The assistant works as your account: it uses your credits and follows your account's limits, exactly like the website.

ChatGPT

Custom connectors need a ChatGPT plan that offers developer mode or custom apps. Menu names can differ slightly between versions.

  1. In ChatGPT, open Settings → Apps & Connectors → Advanced settings and turn on Developer mode.
  2. Back in Apps & Connectors, choose Create.
  3. Fill in: Name Hanova AI, MCP server URL https://hanovaai.com/mcp, Authentication OAuth. Then select Create.
  4. Sign in to Hanova AI when the window opens and select Allow access.
  5. In a new chat, open the + menu and turn on Hanova AI (in developer mode). Then ask, for example: “List my Hanova AI projects.”

ChatGPT asks you to confirm before running a tool that changes something, such as starting a step.

Claude (claude.ai and Claude Desktop)

  1. Open Settings → Connectors and choose Add custom connector.
  2. Name it Hanova AI and enter the URL https://hanovaai.com/mcp. Then select Add.
  3. Select Connect, sign in to Hanova AI and select Allow access.
  4. In a chat, turn on Hanova AI from the tools menu. Connectors you add on claude.ai also appear in Claude Desktop.

On Team and Enterprise plans, an owner may need to add the connector for the organisation first.

Claude Code

Add the server, then run /mcp inside Claude Code and choose Hanova AI to sign in:

claude mcp add --transport http hanova https://hanovaai.com/mcp

Or skip the sign-in and use an API key:

claude mcp add --transport http hanova https://hanovaai.com/mcp \
  --header "Authorization: Bearer hk_live_..."

Other MCP clients

Any client that supports remote MCP servers with OAuth can connect to https://hanovaai.com/mcp and sign in. A client that can only run local servers can use the standard mcp-remote bridge (needs Node.js) with an API key:

{
  "mcpServers": {
    "hanova": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://hanovaai.com/mcp",
               "--header", "Authorization: Bearer ${HANOVA_API_KEY}"],
      "env": { "HANOVA_API_KEY": "hk_live_..." }
    }
  }
}

Tools

ToolWhat it does
searchFind projects and library documents by keyword
fetchRead a project or document from search in full
get_accountCredits, account type and limits
list_projectsYour projects
create_projectStart a project
get_projectStep statuses and credit estimates
run_stepStart a step (uses credits)
get_step_statusIs it ready yet?
get_stepRead a step
update_stepEdit or approve a step
refine_stepRewrite a passage with an instruction
list_literaturePapers found
select_literatureChoose papers
ask_assistantThe research assistant, with sources
list_libraryYour documents
export_paperThe finished paper as Markdown, LaTeX, HTML or text
list_citation_stylesStyle keys
list_paper_typesPaper types
get_usageCredit history

Tools that only read are marked read-only. The others are marked as changing something, so the assistant asks before running them. No tool can delete a project, buy credits or change your account.

How the sign-in works

For developers building a client: standard OAuth 2.1 with PKCE (S256) and dynamic client registration. Discovery is at https://hanovaai.com/.well-known/oauth-protected-resource and https://hanovaai.com/.well-known/oauth-authorization-server. Access tokens last one hour and are bound to https://hanovaai.com/mcp. Refresh tokens rotate on every use. You can see connected apps under Credits & usage → Connected apps, and disconnecting one revokes all its tokens at once.

Security

  • Keep keys out of source control and client-side code; load them from an environment variable or a secret manager.
  • Use one key per app or device, and revoke any key you no longer use (or think was exposed) on Credits & usage. Disconnect ChatGPT or Claude there too, under Connected apps.
  • All traffic is HTTPS. Keys are stored only as fingerprints, and every request is checked against your account's ownership and limits.
  • Found a security issue? Email hanova.ai.research@gmail.com.

Versioning

This is version 1 (/api/v1). New endpoints and new fields can be added at any time, so ignore fields you don't know. Anything that would break existing code will come as /api/v2, with notice.