Developer Portal

Faraid.AI Public API — Sharia inheritance calculation, multi-jurisdiction wills, and webhook-driven integrations for legal-tech systems, Islamic banks, and diaspora institutions.

⚡ Quickstart

Three steps to your first Faraid calculation via API:

  1. Sign in to faraid.ai → Lawyer Dashboard → 🔑 API Anahtarları
  2. Click + Sandbox and copy your key (starts with fk_sand_).
  3. Make your first call:
# Quick Faraid calc — wife + 2 sons + 1 daughter, Hanafi madhab
curl -X POST https://api.faraid.ai/api/hesapla \
  -H "Authorization: Bearer fk_sand_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "mezhep": "hanefi",
    "olen_cinsiyet": "erkek",
    "es_listesi": [{"ad": "Ayşe"}],
    "ogul_listesi": [{"ad":"Ahmet"},{"ad":"Mehmet"}],
    "kiz_listesi":  [{"ad":"Fatma"}],
    "toplam_mal":   100000,
    "dil": "en"
  }'
import requests

API_KEY = "fk_sand_YOUR_KEY_HERE"
BASE    = "https://api.faraid.ai"

payload = {
    "mezhep": "hanefi",
    "olen_cinsiyet": "erkek",
    "es_listesi": [{"ad": "Ayşe"}],
    "ogul_listesi": [{"ad": "Ahmet"}, {"ad": "Mehmet"}],
    "kiz_listesi":  [{"ad": "Fatma"}],
    "toplam_mal":   100000,
    "dil": "en",
}
r = requests.post(
    f"{BASE}/api/hesapla",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json=payload, timeout=30,
)
r.raise_for_status()
result = r.json()
print(result["pay_dagitimi"])
#  Ayşe: 1/8 (12.50%)
#  Ahmet: 7/20 (35.00%)
#  Mehmet: 7/20 (35.00%)
#  Fatma: 7/40 (17.50%)
const API_KEY = "fk_sand_YOUR_KEY_HERE";
const BASE    = "https://api.faraid.ai";

const payload = {
  mezhep:        "hanefi",
  olen_cinsiyet: "erkek",
  es_listesi:    [{ ad: "Ayşe" }],
  ogul_listesi:  [{ ad: "Ahmet" }, { ad: "Mehmet" }],
  kiz_listesi:   [{ ad: "Fatma" }],
  toplam_mal:    100000,
  dil:           "en",
};

const r = await fetch(`${BASE}/api/hesapla`, {
  method:  "POST",
  headers: {
    "Authorization": `Bearer ${API_KEY}`,
    "Content-Type":  "application/json",
  },
  body: JSON.stringify(payload),
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
const result = await r.json();
console.log(result.pay_dagitimi);

🔐 Authentication

All API requests use Bearer token in the Authorization header:

Authorization: Bearer fk_live_AbCdEf1234567890XyZ

🧪 Sandbox vs Live

💡 Always test against sandbox first. Switch to live only after end-to-end verification.

🎯 Scopes

Each API key has a comma-separated scopes attribute:

ScopeWhat it allows
faraid:calculatePOST /api/hesapla, /api/what-if
wills:writePOST /api/wills/save (will generation)
documents:readGET /api/wills/version/{id}
documents:downloadGET /api/wills/version/{id}/download
lawyer:readGET /api/lawyer/clients (B2B)
*Full access — use sparingly.

⏱ Rate Limits

⚠ Error Handling

Standard HTTP codes:

📡 Endpoints

Calculate Inheritance

POST/api/hesapla

Compute Faraid shares with 4-madhab algorithm. Returns shares as fractions + percentages + amounts (if toplam_mal provided).

Body parameters (key ones — full schema: /api/docs):

⚠ Common pitfall — bequest semantics: The legacy schema requires vasiyet_var=evet as an explicit activator. Sending only vasiyet_tutari=60000 without this flag will result in the bequest being silently dropped (heirs will get the gross estate, not gross − bequest). The web UI normalizes this automatically via _normalize_field_aliases(); API consumers must set it manually. A v3 of the API will deprecate this flag — until then, treat it as required when sending bequests.

What-If Simulation

POST/api/what-if

Run multiple counterfactual scenarios in parallel. Returns side-by-side comparison.

curl -X POST https://api.faraid.ai/api/what-if \
  -H "Authorization: Bearer fk_sand_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "baseline": { /* same as /api/hesapla payload */ },
    "scenarios": ["remove_child","spouse_dies","change_madhab"]
  }'
r = requests.post("https://api.faraid.ai/api/what-if",
    headers={"Authorization": f"Bearer {KEY}"},
    json={
        "baseline": payload,
        "scenarios": ["remove_child", "spouse_dies", "change_madhab"],
    })
for s in r.json()["scenarios"]:
    print(s["key"], s["diffs"])

Save Will Draft

POST/api/wills/save

Create a new will draft (v1) or new version of existing group. Requires wills:write scope.

List Calculation History

GET/api/history/list?limit=50

Lawyer: List Clients

GET/api/lawyer/clients?status=active

Requires lawyer:read scope and Lawyer plan.

🔔 Webhooks

Receive real-time notifications via HTTPS POST + HMAC-SHA256 signature.

Setup + Signature Verification

Configure webhook endpoints in Dashboard → 🔔 Webhook'lar.

Each request includes:

import hmac, hashlib
from flask import request, jsonify

SECRET = "YOUR_WEBHOOK_SECRET"  # shown ONCE when endpoint created

def verify_signature(payload: bytes, signature: str) -> bool:
    expected = "sha256=" + hmac.new(SECRET.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

@app.route("/faraid-webhook", methods=["POST"])
def handle():
    sig = request.headers.get("X-Faraid-Signature", "")
    if not verify_signature(request.data, sig):
        return jsonify(error="invalid signature"), 401

    event_type = request.headers["X-Faraid-Event"]
    data       = request.json
    # Idempotency: store X-Faraid-Delivery-ID to dedupe retries
    return jsonify(received=True), 200
const crypto  = require("crypto");
const express = require("express");
const SECRET  = process.env.FARAID_WEBHOOK_SECRET;

function verifySignature(rawBody, signature) {
  const expected = "sha256=" +
    crypto.createHmac("sha256", SECRET).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

const app = express();
app.post("/faraid-webhook",
  express.raw({ type: "application/json" }),  // raw body for signature
  (req, res) => {
    const sig = req.headers["x-faraid-signature"];
    if (!verifySignature(req.body, sig)) return res.status(401).json({ error: "bad sig" });

    const eventType = req.headers["x-faraid-event"];
    const data      = JSON.parse(req.body.toString());
    // Idempotency: dedupe by req.headers["x-faraid-delivery-id"]
    res.json({ received: true });
  });
app.listen(3000);
Always verify signatures. Without verification, attackers can spoof Faraid.AI deliveries.

Available Events

calculation.completed

Fired when a Faraid calculation is successfully completed (including via Dashboard UI).

{
  "event": "calculation.completed",
  "ts": "2026-05-20T22:14:33Z",
  "data": {
    "calc_id": 8421,
    "user_id": 12,
    "lawyer_client_id": 5,
    "mezhep": "hanefi",
    "net_tereke": 95328.0,
    "mirasci_count": 7,
    "had_civil_law_conflict": false
  }
}

will.generated

Will draft was generated/saved (v1 or new version).

{
  "event": "will.generated",
  "ts": "2026-05-20T22:18:11Z",
  "data": {
    "will_id": 42, "group_id": "abc123", "version_no": 2,
    "country": "TR", "scenario": "pre_death",
    "user_id": 12, "title": "Ahmet Yıldız — Vasiyetname"
  }
}

civil_law.conflict

Civil-law optimizer detected a conflict (e.g. German Pflichtteil vs Faraid). Useful for triggering attorney review workflows.

{
  "event": "civil_law.conflict",
  "ts": "2026-05-20T22:20:02Z",
  "data": {
    "calc_id": 8421, "country": "DE",
    "conflict_type": "pflichtteil_violation",
    "affected_heirs": ["Sarah", "Anna"],
    "recommendation": "lawyer_review_required"
  }
}

🐍 Python — minimum SDK snippet

Drop-in client (no external deps beyond requests):

import requests
from typing import Optional

class FaraidClient:
    def __init__(self, api_key: str, base_url: str = "https://api.faraid.ai"):
        self.s = requests.Session()
        self.s.headers.update({"Authorization": f"Bearer {api_key}"})
        self.base = base_url.rstrip("/")

    def calculate(self, **fields) -> dict:
        r = self.s.post(f"{self.base}/api/hesapla", json=fields, timeout=30)
        r.raise_for_status()
        return r.json()

    def what_if(self, baseline: dict, scenarios: list) -> dict:
        r = self.s.post(f"{self.base}/api/what-if",
                        json={"baseline": baseline, "scenarios": scenarios}, timeout=60)
        r.raise_for_status()
        return r.json()

    def save_will(self, country: str, title: str, content_text: str,
                  group_id: Optional[str] = None) -> dict:
        r = self.s.post(f"{self.base}/api/wills/save", json={
            "country": country, "title": title,
            "content_text": content_text, "group_id": group_id,
        }, timeout=20)
        r.raise_for_status()
        return r.json()

# Usage
client = FaraidClient("fk_live_xxxxxxxx")
result = client.calculate(mezhep="hanefi", olen_cinsiyet="erkek",
                          es_listesi=[{"ad":"Ayşe"}], toplam_mal=100000)

🟢 Node.js — minimum SDK

// requires Node 18+ (native fetch)
export class FaraidClient {
  constructor(apiKey, baseUrl = "https://api.faraid.ai") {
    this.apiKey = apiKey;
    this.base = baseUrl.replace(/\/$/, "");
  }

  async _post(path, body) {
    const r = await fetch(`${this.base}${path}`, {
      method: "POST",
      headers: { "Authorization": `Bearer ${this.apiKey}`,
                 "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (!r.ok) throw new Error(`HTTP ${r.status}: ${await r.text()}`);
    return r.json();
  }

  calculate(fields) { return this._post("/api/hesapla", fields); }
  whatIf(baseline, scenarios) {
    return this._post("/api/what-if", { baseline, scenarios });
  }
  saveWill(opts) { return this._post("/api/wills/save", opts); }
}

📑 cURL recipes

# Environment
export FARAID_KEY="fk_live_xxxxxxxxxxxxxxxxx"

# 1) Simple calc — fractions only (no money)
curl -X POST https://api.faraid.ai/api/hesapla \
  -H "Authorization: Bearer $FARAID_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mezhep":"hanefi","olen_cinsiyet":"erkek","ogul_adedi":2}'

# 2) Generate Turkish will draft (after calc)
curl -X POST https://api.faraid.ai/api/wills/save \
  -H "Authorization: Bearer $FARAID_KEY" \
  -d '{"country":"TR","title":"Test","content_text":"VASİYETNAME..."}'

# 3) Check usage / quota
curl https://api.faraid.ai/api/billing/subscription \
  -H "Authorization: Bearer $FARAID_KEY"

# 4) List webhook endpoints
curl https://api.faraid.ai/api/webhooks/endpoints \
  -H "Authorization: Bearer $FARAID_KEY"