Developer docs

Quickstart

Ahel is the ground-truth layer for AI agents: hand it a company, person, email, phone, domain, or wallet and get back a verified entity with sourced receipts. One key works across REST, MCP, and the SDK. Base URL https://api.ahel.ai/v1. Every result carries its source and confidence.

1 · Get a key and make your first call

Create a key in the dashboard at /app/connect. Keys look like ahel_… and are shown once at creation — store the full value securely. Send it as a bearer token (or an X-API-Key header) on every request. New accounts start with free credits, so this works out of the box.

POST /v1/search/{type} — find an entity by email

curl https://api.ahel.ai/v1/search/email \
  -H "Authorization: Bearer ahel_…" \
  -H "Content-Type: application/json" \
  -d '{ "query": "satoshi@example.com" }'

Search returns a { meta, payload: { findings: [] } } envelope. Each finding is one source’s record, carrying its source, a confidence (0–1), a match_quality, an optional evidence url, and its data.

Response

{
  "meta": { "count": 3, "duration_ms": 1840 },
  "payload": {
    "findings": [
      {
        "platform": "companies register",
        "source": "ee business register",
        "confidence": 0.97,
        "match_quality": "exact",
        "url": "https://ariregister.rik.ee/…",
        "anchors": { "email": "satoshi@example.com" },
        "data": { "name": "…", "reg_code": "…" }
      }
    ]
  }
}

Three ways in

REST

Plain HTTPS against https://api.ahel.ai/v1 with your ahel_ key as a bearer token. The full endpoint reference is below — nothing to install.

MCP

Point any MCP-capable agent (Claude, your own runtime) at https://mcp.ahel.ai. It speaks the Model Context Protocol over a keyless OAuth handshake — the agent authorizes once and the self-describing hero tools (find, resolve, connect, verify, verify_company, lookup, invoke_provider, capabilities) appear automatically.

Claude / MCP client config

{
  "mcpServers": {
    "ahel": { "url": "https://mcp.ahel.ai" }
  }
}

SDK

A typed TypeScript client wraps the same REST surface. Construct it once with your key and call the verbs directly.

TypeScript

import { createClient } from "@ahel-technologies/arkenstone-sdk";

const ahel = createClient({ apiKey: process.env.AHEL_API_KEY }); // ahel_…

const { payload } = await ahel.search("company", "Wise", { country: "GB" });

2 · Endpoint reference

Every path below is relative to https://api.ahel.ai/v1 and authenticated by your ahel_ key. POST bodies are JSON.

MethodPathBodyCredits
POST/v1/search/{type}

Fan out across every source for a type (email · phone · username · domain · ip · name · company · crypto …) and return the raw per-source findings.

{ query }1
POST/v1/resolve

Hand one identifier and get back the single unified entity Ahel assembled across sources — merged anchors + attributes + observation history.

{ type, value }1
POST/v1/verify

Check one factual claim against multiple live primary sources. Returns a verdict (supported / refuted / inconclusive), an agreement score, an answer, and per-source receipts.

{ claim, country? }10
POST/v1/verify/company

Single compound company check: registry records (EE / DK / FI / NO + Wikidata) and sanctions screening, every finding carrying its source register.

{ value, country? }5
POST/v1/graph/expand

The Connect verb: give a seed entity, get the entities connected to it — filed officers, owners, beneficial owners, ownership graph (single-hop, stateless).

{ seed: { type, value }, country?, max_connections? }2
POST/v1/providers/{name}/invoke

Hit ONE source precisely (≈10× faster than a fan-out) with managed auth + metering. Forwarding your own connected key is free; an Ahel-hosted call is 1.

provider-specific, e.g. { query, country }0–1
GET/v1/providers

The live source catalogue — what an agent can verify against. Metadata, not a verification call.

free
GET/v1/credits

Your current credit balance and plan. Check it before a metered call, or use it as a budget guard in client code.

free
GET/v1/openapi

The machine-readable OpenAPI 3 document for this surface.

free

resolve, verify, verify/company and graph/expand return their own purpose-built envelope rather than the findings shape. A verify response, for example:

POST /v1/verify — response

{
  "claim": "The James Webb Space Telescope launched in December 2021",
  "verdict": "supported",
  "agreement": 1.0,
  "answer": "Yes, JWST launched on December 25, 2021.",
  "sources_checked": 9,
  "receipts": [
    { "provider": "live web",  "stance": "supports", "confidence": 0.92,
      "url": "https://…" },
    { "provider": "wikipedia", "stance": "supports", "confidence": 0.85,
      "url": "https://en.wikipedia.org/wiki/James_Webb_Space_Telescope" }
  ]
}

3 · Authentication

Every REST call needs your ahel_ key, sent either as a bearer token or an X-API-Key header. The full secret is shown once at creation and stored only as a hash — if you lose it, mint a new one. Revoking a key takes effect immediately.

Both header forms are accepted

-H "Authorization: Bearer ahel_…"
# or
-H "X-API-Key: ahel_…"
  • 401 invalid_api_key — the key is missing, malformed, revoked, or unknown (or the account is suspended).
  • 402 insufficient_credits — authenticated, but out of credits; the body carries your balance.
  • 429 rate_limited — too many requests for your plan; respect the Retry-After header.

MCP clients skip all of this — they authorize through the OAuth handshake at https://mcp.ahel.ai instead of carrying a key.

4 · Credits and metering

Calls are metered in prepaid credits, debited up front and automatically refunded if the call fails (reserve- then-settle). A type fan-out or a cold resolve is 1 credit; a single source invoked through one of your own connected keys is free. Read-only metadata (/providers, /credits, /openapi) never costs anything.

  • Search / resolve — 1 credit each.
  • Provider invoke — 0 with your own connected key, 1 when Ahel hosts the source.
  • Graph expand — 2 credits.
  • Company check — 5 credits (registries + sanctions in one call).
  • Claim verification — 10 credits (one claim across several live sources, verdict + receipts).

Check a balance any time, and top up or see the full breakdown on the pricing page.

GET /v1/credits — response

{ "payload": { "balance": 187, "plan": "free" } }

5 · Errors

Errors come back as JSON with an error code (and often a detail or balance) at the matching HTTP status.

StatuserrorWhen
400missing_query · unknown_search_type · missing_inputMalformed request: no query, an unknown search/resolve type, or a missing required field.
401invalid_api_keyMissing, malformed, revoked, or unknown key (or a suspended account). Check the Authorization header.
402insufficient_creditsOut of credits. The body carries your current balance; top up at /pricing.
403provider_not_enabled_for_accountOn /providers/{name}/invoke: that source isn't switched on under Sources for this account.
404unknown_providerNo source with that name exists on the public catalogue.
422needs_credentialA bring-your-own-key source was invoked without a connected credential. The body names the credentialType to add.
429rate_limitedPer-account rate limit exceeded. The body + Retry-After header tell you how long to wait.
502engine_errorAn upstream source failed. The reserved credit is automatically refunded.

402 — out of credits

{ "error": "insufficient_credits", "balance": 0 }

429 — rate limited

{
  "error": "rate_limited",
  "detail": "Rate limit exceeded for the Free plan (30 requests/min). Retry in ~2s or upgrade your plan.",
  "limit": 30,
  "plan": "free",
  "retry_after_seconds": 2
}

Get a key at /app/connect · machine-readable spec at https://api.ahel.ai/v1/openapi · questions to [email protected].