Grandice API
An authenticated, provider-grade API for privately hosted models and local-first sensitive-data protection.
https://llm.grand-ice.com/v1The API uses familiar chat-completion request formats, while inference runs on Grandice-owned infrastructure. Use a Grandice gll-… key.
Quickstart
Make your first request using the smart model alias.
curl https://llm.grand-ice.com/v1/chat/completions \
-H "Authorization: Bearer $GRANDICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "smart",
"messages": [
{"role": "user", "content": "Explain private AI in one sentence."}
]
}'
import os
import httpx
response = httpx.post(
"https://llm.grand-ice.com/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['GRANDICE_API_KEY']}"},
json={
"model": "smart",
"messages": [
{"role": "user", "content": "Explain private AI in one sentence."}
],
},
timeout=120,
)
response.raise_for_status()
print(response.json()["choices"][0]["message"]["content"])
const response = await fetch(
"https://llm.grand-ice.com/v1/chat/completions",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.GRANDICE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "smart",
messages: [
{ role: "user", content: "Explain private AI in one sentence." },
],
}),
},
);
if (!response.ok) {
throw new Error(`Grandice request failed: ${response.status}`);
}
const data = await response.json();
console.log(data.choices[0].message.content);
Authentication
Every /v1 request requires a Grandice API key in the standard bearer header.
Authorization: Bearer gll-your-application-keyNever embed a key in frontend JavaScript, mobile binaries or a public repository.
Separate keys make limits, access, usage and revocation manageable.
Protect sensitive data before inference
Privacy Shield detects and transforms sensitive values in prompts and structured data. The same versioned policies power client SDKs, a local OpenAI-compatible sidecar and authenticated hosted utilities.
Client SDK and sidecar protection runs in your environment, so original values do not reach Grandice. Hosted privacy receives original content in memory and is therefore zero-retention—not zero-transfer.
Unsupported bodies, remote media, unsafe streaming and incomplete multimedia coverage are rejected instead of forwarded unprotected.
Receipts report policy versions, processing location and entity counts without returning original sensitive values.
Choose where protection runs
clientPython or TypeScript SDKTokenization and the reversible vault remain inside the application process. Best for applications you control.
ZERO TRANSFERsidecarLocal compatibility proxyExisting OpenAI-compatible applications point to 127.0.0.1:8090/v1. Best when changing application code is difficult.
hostedGateway privacy middlewareGrandice masks the request before model inference and masks the response before returning it. Original input reaches gateway memory.
ZERO RETENTIONApply hosted privacy to an existing model request without a separate preprocessing call:
POST /v1/chat/completions
Authorization: Bearer gll-...
X-Grandice-Privacy-Mode: hosted
X-Grandice-Privacy-Policy: financial-strict-v1
Content-Type: application/json
stream: true. A protected token can span stream chunks, so returning an incompletely inspected stream would break the privacy contract.Privacy endpoints
These routes require a normal Grandice API key and share its request-per-minute limit.
/v1/privacy/capabilitiesReport installed structured-data and local multimedia capabilities.
/v1/privacy/policiesList versioned policies and enabled entity categories.
/v1/privacy/detectReturn finding locations and categories without transforming the input.
/v1/privacy/redactIrreversibly mask detected values.
/v1/privacy/tokenizeReplace repeated values with consistent ephemeral placeholders. The hosted service does not retain a restoration map.
/v1/privacy/media/redactLocal sidecar multimedia route. The hosted route currently refuses disk-backed media processing.
{
"policy": "financial-strict-v1",
"data": {
"prompt": "Email alice@example.com about account 87432291."
}
}
{
"data": {
"prompt": "Email a***@example.com about ******* ****2291."
},
"findings": [
{
"entity_type": "EMAIL_ADDRESS",
"path": "$.prompt",
"start": 6,
"end": 23,
"confidence": 0.98,
"detector": "pattern:email_address"
}
],
"receipt": {
"processing_location": "hosted",
"policy": "financial-strict-v1",
"raw_content_transferred": true,
"content_retained": false
}
}
general-v1, strict-v1, financial-strict-v1 and legal-strict-v1.Client SDKs and local sidecar
The Python client creates a request-scoped local vault, sends only tokenized JSON and safely restores user-visible response text.
from grandice_privacy import GrandicePrivacyClient
with GrandicePrivacyClient(
base_url="https://llm.grand-ice.com/v1",
api_key="gll-...",
policy="financial-strict-v1",
) as client:
response = client.post(
"/chat/completions",
json={
"model": "smart",
"messages": [{
"role": "user",
"content": "Email alice@example.com about account 87432291."
}],
},
)
TypeScript applications can wrap fetch with createPrivacyFetch. Binary and unsupported request body types are refused rather than sent unchanged.
import { createPrivacyFetch } from "@grandice/privacy";
const privacyFetch = createPrivacyFetch({
policy: "financial-strict-v1",
});
For an existing application, start the sidecar and change only the base URL:
.\scripts\start-privacy-sidecar.ps1 `
-Upstream "https://llm.grand-ice.com" `
-Policy "financial-strict-v1"
# Application base URL
http://127.0.0.1:8090/v1
content, text and output_text. Tokens inside tool calls and function arguments remain protected to prevent secret injection into executable operations.Images, audio and video
The sidecar pipeline strips metadata; redacts OCR-matched text, faces, QR codes and barcodes; mutes sensitive speech intervals using local transcription; and processes every video frame plus its audio track.
content_base64string · requiredBase64 content or a matching data URL.
media_typestring · requiredSupported image, audio or video MIME type.
policystring · optionalDefaults to the sidecar policy.
POST http://127.0.0.1:8090/v1/privacy/media/redact
Content-Type: application/json
{
"media_type": "image/png",
"policy": "strict-v1",
"content_base64": "iVBORw0KGgo..."
}
- Remote media URLs are refused because they cannot be sanitized before retrieval.
- Strict image and video processing requires local OCR, face, QR and barcode detectors.
- Audio and video require FFmpeg, FFprobe and a preinstalled local Whisper model.
- The processor never downloads a speech model while handling a request.
OCR, speech recognition and visual detectors can miss content. High-risk financial and legal material requires human review and representative accuracy evaluations.
Deterministic financial analysis APIs
The first domain release performs exact decimal calculations from caller-cited inputs. It does not rely on model arithmetic and does not produce personalized buy, sell, product or allocation recommendations.
/v1/financial/portfolio/analyzeWeights, asset/sector/country allocation, HHI, effective positions, concentration and diversification flags.
/v1/financial/risk-assessmentTransparent weighted scoring across bounded, non-identifying risk dimensions.
/v1/financial/company/analyzeHistorical growth, margins, net debt, leverage and valuation multiples when supported by supplied inputs.
{
"metadata": {
"as_of": "2026-09-14",
"sources": [{
"source_id": "custodian",
"citation": "Caller-supplied custodian record",
"as_of": "2026-09-14"
}]
},
"reporting_currency": "USD",
"positions": [{
"instrument_id": "FUND-A",
"market_value": "75000.00",
"asset_class": "Equity",
"sector": "Diversified",
"country": "US",
"source_id": "custodian"
}]
}
- Send monetary values as decimal strings; binary floating-point values are rejected.
- Every fact-bearing record must reference caller-provided source metadata and an as-of date.
- After authentication, quota and size checks, configured detectors scan raw JSON before schema validation.
- The residual check is best-effort policy coverage—not proof that no personal data exists.
- Responses include assumptions, limitations, warnings, methodology version and
professional_review_required: true. - Audit storage contains run metadata only—not request or response bodies.
Managed domain agents
Grandice agents are constrained, typed workflows rather than unrestricted autonomous chat. Each definition declares internal capabilities, privacy policy, caller-source requirements, execution deadline and professional-review boundary.
/v1/agentsList available agent definitions and guardrail metadata.
/v1/agents/runsValidate typed inputs and execute a registered workflow.
/v1/domain/runs/{request_id}Retrieve body-free audit metadata for a run created by the same API key.
{
"agent": "financial.risk-assessment.v1",
"inputs": {
"metadata": {
"as_of": "2026-09-14",
"sources": [{
"source_id": "questionnaire",
"citation": "Caller-supplied questionnaire",
"as_of": "2026-09-14"
}]
},
"profile": {
"source_id": "questionnaire",
"loss_tolerance": 3,
"time_horizon": 4,
"financial_stability": 3,
"liquidity_flexibility": 2,
"investment_knowledge": 3
}
}
}
market.evidence-analyst.v1, and market.competitive-landscape.v1.Legal Contract Intelligence APIs
Deterministic commercial-contract clause extraction, playbook issue spotting and original-to-revised comparison. Contract text remains inert data: these workflows do not invoke an LLM, browse, execute embedded instructions or modify documents.
/v1/legal/contracts/reviewClassify clauses, bind exact source spans, apply explainable fixed rules and evaluate a bounded literal-only playbook.
/v1/legal/contracts/compareReport added, removed, modified, unchanged or ambiguous clauses and supported risk deltas.
- Each document is capped at 200,000 characters; extracted clauses, findings and changes are separately bounded.
- Evidence includes document/source IDs, Unicode code-point coordinates and SHA-256 bindings for documents, spans and excerpts.
- Comparison uses exact hashes and bounded token similarity—never unbounded all-pairs semantic matching.
- Playbooks accept typed clause categories and literal phrases, not regex, prompts, URLs, code or tools.
- Privacy Shield can tokenize locally before transfer; the gateway then applies a
legal-strict-v1residual scan before validation. - Outputs are issue-spotting artifacts, not legal advice, and always require qualified legal review.
Contract text cannot select an agent, alter a playbook, call a tool, browse, change severity or approve an outcome. The current implementation contains no model or network call in legal analysis.
Market Research Intelligence APIs
Deterministic analysis of caller-provided, dated market evidence. The initial workflows calculate exact metric changes, source and observation recency, declared source-ID concentration, contradictions, research gaps, and non-ranking competitive comparisons.
/v1/market/research/analyzeAnalyze evidence coverage, exact trends, disagreements, contradictions, reversals, recency, and declared research gaps.
/v1/market/competitive-landscape/compareCompare entities only when metric, unit, currency, scale, period, fiscal calendar, and accounting basis align.
- Sources, citation labels, publication dates, and source identities are caller provided and unverified.
- Evidence bindings include statement, canonical-record, source, and analysis-manifest digests.
- Coverage measures supplied evidence coverage—not confidence, accuracy, quality, independence, or truth.
- Same-period disputed metric values remain unresolved and are excluded from trend arithmetic.
- No browsing, live retrieval, currency conversion, normalization, forecasting, ranking, or recommendation occurs.
- Market analysis runs in capacity-limited child processes that are terminated on deadline.
Grandice does not call metrics comparable because their names look similar. Every declared dimension and period boundary must match; unknown, missing, disputed, or misaligned evidence remains incomparable.
Available model aliases
Use stable aliases in application code. Grandice can upgrade the underlying model without requiring a client deployment.
smartQwen 3.5 · 9BBest overall quality. Chat, reasoning, code, vision and tools.
fastQwen 3.5 · 4BLower latency for routine chat, vision and tool workflows.
chatQwen 3 · 8BGeneral-purpose conversation, structured output and tools.
codeQwen 2.5 Coder · 7BCode generation, explanation, review and completion.
visionQwen 2.5 VL · 7BImage analysis, screenshots, OCR and visual questions.
embedNomic Embed TextVector embeddings for retrieval and semantic search.
"reasoning_effort": "medium" when deliberate reasoning is needed./v1/modelsList models
Returns models available to the current key, including capability metadata and friendly aliases.
{
"object": "list",
"data": [
{
"id": "smart",
"object": "model",
"owned_by": "grandice",
"aliases_to": "qwen3.5:9b",
"info": {
"meta": {
"capabilities": {
"builtin_tools": true,
"vision": true,
"reasoning": true
}
}
}
}
]
}
/v1/chat/completionsChat completions
Generates a response from a conversation. Supports system prompts, multi-turn messages, JSON output, reasoning, tools and images when supported by the selected model.
modelstring · requiredA model alias such as smart, fast or code.
messagesarray · requiredConversation messages with system, user, assistant or tool roles.
streamboolean · optionalSet to true to receive server-sent events.
temperaturenumber · optionalSampling temperature. Lower values are more deterministic.
max_tokensinteger · optionalMaximum number of generated output tokens.
reasoning_effortstring · optionalUse none, low, medium or high on reasoning models.
{
"model": "smart",
"messages": [
{"role": "system", "content": "Be concise and accurate."},
{"role": "user", "content": "What is retrieval-augmented generation?"}
],
"temperature": 0.2
}
Streaming
Set "stream": true. The response uses text/event-stream, with each event prefixed by data: and terminated by [DONE].
const stream = await client.chat.completions.create({
model: "fast",
messages: [{ role: "user", content: "Write a product tagline." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Vision requests
Use smart, fast or vision. Supply an HTTPS image URL or a base64 data URL.
{
"model": "vision",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Extract the text and summarize this image."},
{
"type": "image_url",
"image_url": {"url": "data:image/jpeg;base64,BASE64_IMAGE"}
}
]
}]
}
vision model does not support tool calling. Use smart when a workflow requires both images and tools.Tool calling
Describe functions in tools. The model may return tool_calls; execute those functions in your application and send the result back with role tool.
{
"model": "smart",
"messages": [{"role": "user", "content": "What is the weather in Boston?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
}],
"tool_choice": "auto"
}
/v1/embeddingsEmbeddings
Converts text into vectors for semantic search, clustering and retrieval-augmented generation.
{
"model": "embed",
"input": [
"Grandice runs models on private infrastructure.",
"Applications connect through an authenticated API."
]
}
/v1/completionsLegacy text completions
Accepts a plain prompt and returns generated text. New integrations should prefer chat completions.
{
"model": "code",
"prompt": "Write a Python function that validates an email address.",
"max_tokens": 300
}
/statusService status
Returns the calling application name, request limit, installed models and current aliases. Requires a standard API key.
GET /health is an unauthenticated liveness check that returns only gateway and Ollama availability.
HTTP errors
400Bad requestMalformed JSON or invalid request fields.401UnauthorizedMissing, invalid or revoked API key.403ForbiddenThe key is not permitted to use the requested model.429Rate limitedThe key exceeded its requests-per-minute allowance.502Model unavailableThe gateway could not reach the local inference service.Rate limits and timeouts
Limits are assigned per API key and measured in requests per minute. A 429 response means the current window is full.
- Use streaming for long user-facing generations.
- Configure client timeouts up to 600 seconds for cold model loads and complex reasoning.
- Retry transient
429and502responses with exponential backoff and jitter. - Do not automatically retry authentication or permission errors.
Admin API
Administrative routes use the separate ADMIN_TOKEN, not an application’s gll-… key. Never distribute this token to clients.
/admin/keysCreate a key with a name, RPM limit and optional model allowlist.
/admin/keysList key metadata and revocation state. Raw secrets are never returned.
/admin/keys/{key_id}Revoke a key immediately.
/admin/usage?days=7Summarize requests, tokens, latency and errors by application and model.