Developers

API & MCP

Connect your applications with the REST API, or your AI assistant (Claude, Copilot, Cursor and other MCP clients) with the MCP server. Both run on the same governed path as the app: your organization’s data only, read-only SQL, your licence and roles, audit and rate limits.

Your data only

Every call is limited to your organization. Keys never reach another tenant’s data.

Read-only answers

Questions run as read-only SQL with row caps; the answer includes the SQL that ran.

Bring your own assistant

Use the AI tools your team already has; inferonIQ supplies governed answers.

Base URL: https://app.inferoniq.com (cloud) or your self-hosted URL

Auth: x-api-key: ik_live_… (MCP also accepts Authorization: Bearer ik_live_…)

Content-Type: application/json (file uploads: multipart/form-data)

Quick start

  1. 1. Create a key. An administrator opens Settings → API Keys, names the key, ticks only the access it needs, picks an expiry and clicks Generate Key. Copy it: it is shown once.
  2. 2. Store it as a secret. Use your secret manager or environment variables. Never put it in browser code or a repository.
  3. 3. Call the API or connect an MCP client (examples below).
curl https://app.inferoniq.com/api/query \
  -H "x-api-key: ik_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "How many open orders were created last month?"}'

Authentication & keys

inferonIQ uses API keys for machine access. There is no client ID / client secret exchange and no access or refresh tokens to manage: send the key on every request. Keys are stored only as a one-way hash, so a lost key cannot be recovered — rotate it instead.

ScopeAllows
viewRead data, list sources and tables (GET requests; MCP list_sources / describe_tables)
run_queriesAsk questions (POST /api/query; MCP ask)
exportCSV exports
upload_docsUpload documents
edit_rulesChange rules and configuration a power user may change
deleteDelete records a power user may delete
  • A key never has more access than a power user: it cannot manage users, settings or other keys.
  • A key with only view/export is read-only: any write is refused (MCP excepted, where each tool checks its scope).
  • Keys reach only the modules your plan includes, like a signed-in user.
  • Expiry: 30, 90 or 365 days, or none. Rotate issues a new key with the same access and stops the old one immediately. Revoke stops a key on its next request.
  • A key stops working if the administrator who created it is removed or disabled. Use a dedicated integration account for long-lived keys.

MCP server

Endpoint https://app.inferoniq.com/api/mcp — Streamable HTTP, protocol versions 2025-06-18, 2025-03-26 and 2024-11-05. Your assistant’s model does the conversation; inferonIQ answers through these read-only tools:

ToolScopeReturns
list_sourcesviewYour connected databases and files: id, name, type, status, table count. No connection credentials.
describe_tablesviewQueryable tables with description and business domain; pass table for its columns. limit (≤200) / offset paging, next_offset.
askrun_queriesPlain-English question → answer, SQL, columns, rows (≤200), table_markdown (first 10 rows, ready to show in chat), confidence, tables used. Read-only; declines rather than guessing.

Claude Code

claude mcp add --transport http inferoniq https://app.inferoniq.com/api/mcp \
  --header "x-api-key: ik_live_YOUR_KEY"

VS Code (GitHub Copilot)

// .vscode/mcp.json
{
  "inputs": [
    { "type": "promptString", "id": "inferoniq-key", "description": "inferonIQ API key", "password": true }
  ],
  "servers": {
    "inferoniq": {
      "type": "http",
      "url": "https://app.inferoniq.com/api/mcp",
      "headers": { "x-api-key": "${input:inferoniq-key}" }
    }
  }
}

Cursor

// ~/.cursor/mcp.json
{
  "mcpServers": {
    "inferoniq": {
      "url": "https://app.inferoniq.com/api/mcp",
      "headers": { "x-api-key": "ik_live_YOUR_KEY" }
    }
  }
}

Claude Desktop

// claude_desktop_config.json — bridges to the remote server with mcp-remote
{
  "mcpServers": {
    "inferoniq": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://app.inferoniq.com/api/mcp", "--header", "Authorization:${AUTH}"],
      "env": { "AUTH": "Bearer ik_live_YOUR_KEY" }
    }
  }
}

Assistants that only connect through an OAuth sign-in (for example web-based connector directories) are not supported yet.

Ask from Microsoft Teams or Slack

People can ask inferonIQ questions where they already work. The answer is computed by inferonIQ (same governed, read-only path as the app); the chat app only carries the question and shows the result.

Microsoft Teams (with Microsoft Copilot Studio)

For organizations licensed for Copilot Studio. No code and no app-store listing: the agent is published to your own tenant.

  1. Before you start: a work or school Microsoft account (personal outlook.com accounts cannot use Copilot Studio) and a Copilot Studio environment with credits — every message, in testing and in Teams, uses them.
  2. In inferonIQ, an administrator creates a key for the team that will use the agent (Settings → API Keys): tick only Read and Run queries, choose an expiry.
  3. In Copilot Studio, create an agent (for example “inferonIQ Finance”) and add instructions: “For any question about our business data, call the inferonIQ ask tool. Show its answer and table_markdown as returned; quote numbers exactly. If inferonIQ cannot answer, say so; never answer data questions from your own knowledge or the web.”
  4. Under Knowledge, remove “Search all websites” so answers come only from inferonIQ.
  5. Under Tools select + → Model Context Protocol. Server URL https://app.inferoniq.com/api/mcp (or your self-hosted URL). Authentication: API key, type Header, header name x-api-key. Create a new connection with the key and Add to agent; three tools appear (list_sources, describe_tables, ask).
  6. Test in Preview with questions you can check in inferonIQ, plus one your data cannot answer (the agent must say so, not guess).
  7. Channels → Microsoft Teams → Publish, then open it with “Open in Teams”. Your Teams administrator approves the agent for the people who should use it.

Slack

  • An AI assistant your team already uses in Slack that supports remote MCP servers connects with the same URL and key as above.
  • Or your developers add a small Slack app that calls the REST API, for example a /ask command:
// Slack slash command /ask, built with Bolt for JavaScript (runs on your server)
app.command('/ask', async ({ command, ack, respond }) => {
  await ack()                                   // Slack needs a reply within 3 seconds
  const res = await fetch('https://app.inferoniq.com/api/query', {
    method: 'POST',
    headers: { 'x-api-key': process.env.INFERONIQ_API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query: command.text }),
    signal: AbortSignal.timeout(60_000),
  })
  const body = await res.json()
  if (!res.ok || body.error) return respond(`inferonIQ could not answer: ${body.message ?? body.error}`)
  await respond(`*${command.text}*\n${body.answer}\n_${body.rowCount} rows · tables: ${(body.tablesUsed ?? []).join(', ')}_`)
})

Before you roll out

  • Everyone using one agent or bot shares its key’s access. Create one key and one agent per team (for example AP, Finance) so each group sees only what its key allows.
  • The chat assistant writes the final message. The result includes the SQL and the tables used so answers can be checked; open the question in inferonIQ for the full result.
  • Answers are stored in your Teams or Slack history. Do not use these channels for patient-level or other regulated detail; ask for counts and totals instead.
  • An inferonIQ app for Teams and Slack with per-person sign-in is available on request.

Rate limits, paging & errors

  • 600 requests per minute per key. Over the limit you get 429 with Retry-After (seconds). An MCP ask counts as two requests.
  • Monthly question and document allowances follow your plan (pricing).
  • Paging: lists take limit and offset (or a cursor where noted) and return the next position. Questions return up to 200 rows plus the total row count — narrow the question for more detail.
  • Requests can take up to 60 seconds for complex questions; set client timeouts accordingly.
StatusMeaning
400Invalid request body or parameters
401Missing, unknown, revoked or expired key — or the key’s creator was removed or disabled
403Key lacks the scope, the key is read-only and the call writes, or your plan does not include that module
429Rate limit exceeded — wait the seconds in the Retry-After header
5xxServer error — retry with backoff; contact support with the time and request

MCP Server

One endpoint for MCP clients (Claude, Copilot, Cursor and others). JSON-RPC 2.0 over Streamable HTTP; responses are returned on the POST.

POST/api/mcp

MCP JSON-RPC endpoint

Methods: initialize, ping, tools/list, tools/call. Tools: list_sources, describe_tables, ask. Requires an API key; GET returns 405 (no server-initiated stream).

Response Example:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{ \"answer\": \"…\", \"sql\": \"SELECT …\", \"rows\": [ … ] }"
      }
    ],
    "structuredContent": {
      "answer": "…",
      "sql": "SELECT COUNT(*) …",
      "columns": [
        "count"
      ],
      "rows": [
        {
          "count": 412
        }
      ],
      "row_count": 1,
      "rows_truncated": false,
      "confidence": 0.93,
      "tables_used": [
        "orders"
      ],
      "query_id": "…"
    }
  }
}

API Keys

Create and manage keys (administrators, signed in to the app). Keys cannot manage keys, users or settings.

GET/api/api-keys

List keys

Name, 12-character prefix, status, scopes, created, last used and expiry. Never the key itself.

POST/api/api-keys

Create key

Returns the key once. Omit permissions for full key access.

Request Body:

namestringrequired— Label, e.g. "Reporting service"
permissionsstring[]— view, run_queries, export, upload_docs, edit_rules, delete — or ["*"]
expiresInDaysinteger— 1–730; omit for no expiry

Response Example:

{
  "key": "ik_live_…",
  "id": "…",
  "prefix": "ik_live_a1b2",
  "permissions": [
    "view",
    "run_queries"
  ],
  "expires_at": "2027-01-08T00:00:00Z"
}
PATCH/api/api-keys?id={id}

Rotate key

Body { "action": "rotate" }. Issues a new key with the same scopes and expiry and revokes the old one immediately.

DELETE/api/api-keys?id={id}

Revoke key

The key stops working on its next request.

NL2SQL Query

Execute natural language questions against connected databases.

POST/api/query

Execute natural language query

Translates natural language to SQL, executes it read-only, returns structured results with business insights. Requires the run_queries scope.

Request Body:

querystringrequired— Natural language question
connectionIdstring (UUID)— Target connection
streamboolean— Enable SSE streaming

Response Example:

{
  "answer": "412 open orders were created last month.",
  "sql": "SELECT COUNT(*) ...",
  "data": [
    {
      "count": 412
    }
  ],
  "columns": [
    "count"
  ],
  "rowCount": 1,
  "confidence": 0.94,
  "tablesUsed": [
    "orders"
  ],
  "queryId": "…"
}

Documents

Upload, classify, and extract data from invoices, contracts, and receipts.

POST/api/documents/upload-url

Get presigned upload URL (large files)

For files > 4MB. Returns a signed URL to upload directly to storage. After uploading, call POST /api/documents with the storagePath.

Request Body:

fileNamestringrequired— Original file name
fileSizenumberrequired— File size in bytes
mimeTypestring— MIME type (optional)

Response Example:

{
  "uploadUrl": "https://storage...",
  "storagePath": "customer_id/file.pdf",
  "expiresIn": 600
}
POST/api/documents

Upload & process document

Two modes: (1) multipart/form-data with file for direct upload (≤ 4MB), (2) application/json with storagePath for presigned uploads (up to 50MB). Returns classification + extraction preview.

Request Body:

fileFile (multipart)— Direct upload mode
storagePathstring— Presigned upload mode — path from upload-url response

Response Example:

{
  "id": "doc-uuid",
  "type": "invoice",
  "extractedFields": {
    "vendor": "Acme",
    "total": 14805
  }
}
GET/api/documents

List documents

Paginated list of uploaded documents with metadata and extraction status.

Query Params:

typestring — Filter by document type
limitnumber — Page size (default 50)

Connections

Manage database and storage connections.

GET/api/connections

List connections

Returns all configured database and storage connections for your tenant.

POST/api/connections

Create connection

Add a new database or storage connection with encrypted credentials.

Request Body:

namestringrequired— Display name
typestringrequired— "postgres" | "snowflake" | "bigquery" | "oracle" | "mysql" | "sqlserver"
hoststringrequired— Database host
portnumber— Port (auto-detected by type)
databasestringrequired— Database name
usernamestringrequired— Auth username
passwordstringrequired— Auth password (encrypted at rest)
POST/api/connections/test

Test connection

Validates connectivity and credentials without saving.

3-Way Matching

Invoice ↔ Purchase Order ↔ Goods Receipt reconciliation.

POST/api/invoices/match

Run 3-Way Match

Executes the 7-phase matching pipeline on an uploaded invoice.

Request Body:

documentIdstring (UUID)required— Invoice document ID

Response Example:

{
  "matchResult": "3-way",
  "confidence": 0.97,
  "exceptions": [],
  "autoApproved": true
}
GET/api/invoices/matches

List match results

Paginated list of all match results with exception details.

Contracts

Contract intelligence — clause extraction and compliance monitoring.

POST/api/contracts/analyze

Analyze contract

AI extracts clauses, pricing terms, SLA targets, renewal dates, and obligations.

Request Body:

documentIdstring (UUID)required— Contract document ID
GET/api/contracts

List contracts

All analyzed contracts with metadata, risk scores, and expiry dates.

License

License validation and usage information.

GET/api/license

Get license status

Returns current license plan, limits, usage counters, and expiry.

Response Example:

{
  "plan": "business",
  "status": "active",
  "expiresAt": "2027-01-01",
  "usage": {
    "queries": 1250,
    "limit": 25000
  }
}
POST/api/license/activate

Activate license key

Activate a new Ed25519-signed license key (BYOC deployments).

Request Body:

keystringrequired— License key string

Health

Platform health and connectivity checks.

GET/api/health

Health check

Returns platform status, database connectivity, and version info. No auth required.

Response Example:

{
  "status": "healthy",
  "version": "3.7.0",
  "database": "connected"
}

Rate Limits & Usage

Rate limits are per-customer, enforced at the license level:

PlanQueries/moDocuments/moConnections
Trial100501
Team5,0002,0005
Business25,00010,00020
EnterpriseUnlimitedUnlimitedUnlimited

Exceeding limits returns 429 Too Many Requests with a Retry-After header.