API reference
Both endpoints are OpenAI-compatible, so any OpenAI SDK, LiteLLM, LangChain or plain HTTP client works. The endpoint is the same for everyone — only your key differs.
What you can ask for
dhandare-4-mini answers defined tasks rather than free-form prompts — that is what makes it deterministic. Pick a task, then send it the way any chat request is sent. There are two ways to name one:
- · put
task: <id>on its own line — unambiguous, and the recommended form for a programmatic integration; or - · say the action plainly, e.g. "narrate these signals", "reflect on this trade".
GET https://models.quantforge.co.in/v1/tasks returns this same list as
JSON — no key required, so you can read it before you subscribe.
| Task | What it does | Returns |
|---|---|---|
| narrate | Turn a list of scored signals into a per-signal note and one overall read. | strict JSON: {"signals": {name: note}, "overall": "..."} |
| reflect | Given a closed trade and how each signal was graded, write the outcome and the lesson. | strict JSON: {"outcome": "...", "learning": "..."} |
| debate | Argue both sides of an already-scored setup, then synthesise. | strict JSON: {"bullCase": "...", "bearCase": "...", "synthesis": "..."} |
| resume | Re-order and emphasise YOUR OWN resume against a job description. Never invents experience. | a tailored resume plus an explicit GAPS list |
Trading-signal narration task: narrate
Turn a list of scored signals into a per-signal note and one overall read.
Your message needs:
- · a line `Instrument: <SYMBOL>`
- · one or more signal lines shaped `- NAME: bullish|bearish|neutral NN/100`
Example
curl https://models.quantforge.co.in/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dhandare-4-mini",
"messages": [{"role": "user", "content": "task: narrate\nInstrument: TCS\n- RSI: bullish 61/100\n- MACD: bearish 30/100"}]
}'
Returns strict JSON: {"signals": {name: note}, "overall": "..."}
Also selected by: narrate, narration, explain these signals, describe these signals, write up these signals, signal commentary
The overall read is weighted by conviction, not by counting rows — five weak bullish signals do not outvote three strong bearish ones.
Post-trade reflection task: reflect
Given a closed trade and how each signal was graded, write the outcome and the lesson.
Your message needs:
- · a line `Trade: <SYMBOL> <SIDE> x<QTY>, entry <P>, exit <P>, net P&L <N> (WIN|LOSS|FLAT)`
- · signal lines shaped `- NAME: direction NN/100 (graded correct|wrong|neutral)`
Example
curl https://models.quantforge.co.in/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dhandare-4-mini",
"messages": [{"role": "user", "content": "task: reflect\nTrade: TCS BUY x50, entry 3900, exit 3960, net P&L 3000 (WIN)\n- RSI: bullish 61/100 (graded correct)\n- MACD: bearish 30/100 (graded wrong)"}]
}'
Returns strict JSON: {"outcome": "...", "learning": "..."}
Also selected by: reflect on, reflection, post-trade review, what did we learn, review this trade, post trade analysis
The per-signal grades are honoured verbatim — this task writes prose, it never re-grades a signal.
Bull-vs-bear debate task: debate
Argue both sides of an already-scored setup, then synthesise.
Your message needs:
- · a line `Instrument: <SYMBOL> (<TRADE TYPE>).` — note the bracketed type and the full stop
- · a line `Computed score: N/10, <figure> NN%, net direction <dir>.` where <figure> is either `probability` or `direction agreement` — whichever you send is the wording quoted back to you (use `n/a` in place of NN% if you have no figure)
- · signal lines shaped `- NAME: direction NN/100`
Example
curl https://models.quantforge.co.in/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dhandare-4-mini",
"messages": [{"role": "user", "content": "task: debate\nInstrument: NIFTY (Options).\nComputed score: 6.5/10, probability 74%, net direction bullish.\n- RSI: bullish 70/100\n- OI_PCR: bearish 55/100"}]
}'
Returns strict JSON: {"bullCase": "...", "bearCase": "...", "synthesis": "..."}
Also selected by: bull vs bear, bull and bear, debate, argue both sides, make the bull case, make the bear case
The score arrives already computed and is quoted, never recalculated — this task cannot move a number.
Resume tailoring task: resume
Re-order and emphasise YOUR OWN resume against a job description. Never invents experience.
Your message needs:
- · a `JOB DESCRIPTION:` block
- · your profile: HEADLINE / SKILLS / EXPERIENCE or PROJECTS sections
Example
curl https://models.quantforge.co.in/v1/chat/completions \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "dhandare-4-mini",
"messages": [{"role": "user", "content": "task: resume\nJOB DESCRIPTION:\nSenior Backend Engineer. Node.js and PostgreSQL required. Kubernetes preferred.\n\nSKILLS: Node.js, PostgreSQL, React\nEXPERIENCE: Built a webhook pipeline handling 1.2M events/day on Node.js + PostgreSQL."}]
}'
Returns a tailored resume plus an explicit GAPS list
Also selected by: tailor my resume, tailor my cv, resume for this job, match my resume
Requirements you have no evidence for are reported as GAPS, never written in. That is the point: a candidate caught inventing experience in an interview is worse served than one who arrives knowing the gap.
Chat completions — dhandare-4-mini
POST https://models.quantforge.co.in/v1/chat/completions
The standard OpenAI request shape. The message body is one of the tasks above.
The x-api-key header is
accepted too, for Anthropic-style clients.
A request that matches no task is answered with an explicit refusal listing the task ids — this model never invents prose to fill a gap. If a task is recognised but the body cannot be read, the reply names the task and shows a working example.
Skills — ready-made features on the real models
POST https://models.quantforge.co.in/v1/skills/<id> · GET https://models.quantforge.co.in/v1/skills (no key required)
One call per feature — no prompt writing. Every answer is JSON that matches the schema below
(the model is constrained by a grammar, so it cannot return anything else). Billed at the listed model's token
prices. Models start on demand: the first call after a quiet period waits while the model loads
(reported as dhandare.engine.cold_start).
| Skill | What it does | Model | Inputs |
|---|---|---|---|
| grammar | Corrects grammar, spelling and punctuation without changing the meaning, and lists each change. | dhandare-4-mini |
text |
| rewrite | Rewrites text in a chosen tone — formal, friendly, concise or persuasive — keeping every fact. | dhandare-4-mini |
texttone: formal | friendly | concise | persuasive |
| summarize | A short summary and up to five key points, using only what the text says. | dhandare-4-mini |
text |
| translate | Translates between Hindi and English, keeping names, numbers and formatting. | dhandare-3.1-pro |
texttarget: hindi | english |
| extract | Pulls the fields you define (as a JSON Schema) out of free text — invoices, emails, forms. | dhandare-4-mini |
textschema |
| classify | Picks the best label from the list you give — support tickets, feedback, intents. | dhandare-4-mini |
textlabels |
| resume | Turns a candidate's own details into a structured resume aimed at a job description — no invented facts. | dhandare-3.1-pro |
candidatejob_description (optional) |
curl https://models.quantforge.co.in/v1/skills/grammar -H "Authorization: Bearer $DHANDARE_KEY" -H "Content-Type: application/json" -d '{"input": {"text": "he go to office yesterday and forget his bag"}}'
# → {"skill": "grammar", "model": "dhandare-4-mini",
# "output": {"corrected": "He went to the office yesterday and forgot his bag.", "changes": [...]},
# "usage": {...}, "dhandare": {"engine": {"cold_start": false, ...}}}
Task catalogue — JSON
GET https://models.quantforge.co.in/v1/tasks
The same list this page shows, machine-readable, no key required.
GET https://models.quantforge.co.in/v1/tasks/<id> returns one task.
curl https://models.quantforge.co.in/v1/tasks
Embeddings — dhandare-embed-1
POST https://embeddings.quantforge.co.in/v1/embeddings
curl https://embeddings.quantforge.co.in/v1/embeddings \
-H "Authorization: Bearer YOUR_EMBED_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "dhandare-embed-1", "input": "text to embed"}'
Returns 384-dimensional vectors, L2-normalised.
input accepts a string or an array of strings.
Usage and billing in the response
"usage": {
"prompt_tokens": 812,
"completion_tokens": 143,
"total_tokens": 955,
"prompt_tokens_details": { "cached_tokens": 640 }
}
Repeating the same system prompt within 5 minutes bills those tokens at the cheaper cached rate. These are exactly the numbers debited from your wallet.
Errors
| Status | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Key is wrong or was revoked by regeneration. |
| 401 | wrong_product_key | You used the other product's key. |
| 402 | insufficient_balance | No credit left for this model — recharge, or take a plan, in the console. |
| 403 | account_disabled | Account disabled by an administrator. |
| 404 | model_not_found | Unknown model id — see GET /v1/models. |
| 429 | rate_limit_exceeded | Too many requests for this key. Honour the Retry-After header. |
| 429 | concurrency_limit_exceeded | Too many requests in flight for this key at once. |
| 400 | unsupported_dimensions | Embeddings are 384-dimensional and cannot be resized. |
A throttled (429) request is never billed — the limit is applied before any metering. Rate limits are enforced per API key.
Client compatibility
| Parameter | Behaviour |
|---|---|
| stream |
Supported. stream:true returns server-sent events ending in
data: [DONE], so the standard SDKs work unchanged. The answer arrives in a
single chunk — this engine computes a complete result rather than token-by-token, and
chunking it artificially would only add latency.
|
| stream_options.include_usage | Supported — appends the usage-only chunk before [DONE]. |
| temperature, top_p, presence_penalty, frequency_penalty, seed | Accepted and ignored, by design. The engine is deterministic — the same input always yields the same output — so there is no sampling for these to steer. They are accepted so existing client code needs no changes. |
| max_tokens | Accepted and ignored. Answers are strict JSON for the structured task shapes, and truncating them mid-document would hand you unparseable output — so responses are always returned whole. |
| model |
Validated. Use dhandare-4-mini, or pin a build with a dated alias such
as dhandare-4-mini-2026-08. Responses carry
system_fingerprint, which changes when the engine build changes.
|
| dimensions (embeddings) | Accepted only at the native width of 384; any other value is a 400 rather than a silently different vector. Size your vector column for 384 dimensions. |
| encoding_format (embeddings) | Supported: float (default) or base64 (little-endian float32). |
What this model is — and is not
dhandare-4-mini is a deterministic work model, not a general LLM. It serves the defined tasks above — trading-signal narration, post-trade reflection, bull-vs-bear debate and resume tailoring — and returns the same output for the same input, every time, with no GPU and no third-party API behind it. Prompts outside those shapes get an explicit "unsupported task" reply: this model never invents prose to look clever.
That is the trade. It will not write you a poem or hold an open-ended conversation. In exchange,
the same request gives the same bytes tomorrow — which is what makes it safe to put in a
pipeline, and why system_fingerprint is a promise rather than
decoration.