Fiscaliq Developer API

Programmatic access to UK crypto and traditional tax engines, reconciliation, and historical GBP pricing.

Overview

Base URL: https://www.fiscaliq.co/api/v1

All calculation endpoints accept JSON POST bodies and return JSON. Authenticated endpoints require a Bearer API key generated from Settings → API access.

Authentication

Send your API key in the Authorization header:

Authorization: Bearer fiq_a1b2c3d4…

Keys are shown once at creation. Only a SHA-256 hash is stored server-side.

Rate limits

Daily quotas apply per account (shared by all of your keys), follow your current plan, and reset at midnight UTC. Response headers include X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After when limited.

Plan tierRequests / day
free100
individual1,000
service_provider10,000
developer modeUnlimited

Endpoints

GET/api/v1/tax-paramsPublic

Current UK tax parameters (no authentication).

Request

// No body

Response

{
  "taxYear": "2026/27",
  "annualExemptAmount": 3000,
  "basicRateCgtPct": 18,
  "higherRateCgtPct": 24,
  "personalAllowance": 12570
}
POST/api/v1/calculate/uk-cryptoAuth required

Run the UK crypto CGT engine (S.104 pooling, same-day and 30-day matching). Max 10,000 transactions. NOTE taxableNonSavingsIncome (formerly totalEarnedIncome, still accepted) is taxable non-savings income AFTER the personal allowance, not gross salary: the example below is a 45,000 salary, which is 32,430 once the 12,570 allowance is taken off. Sending gross stacks gains too high in the band and overstates CGT.

Request

{
  "transactions": [ /* CryptoTransaction[] */ ],
  "taxYear": "2026/27",
  /* Taxable non-savings income AFTER the personal allowance (45,000 salary - 12,570 PA).
     Previously spelled "totalEarnedIncome", which is still accepted. */
  "taxableNonSavingsIncome": 32430,
  /* Taxable savings + dividends: these fill the CGT basic-rate band too (TCGA 1992 s.1I). */
  "otherTaxableIncome": 0,
  /* personalAllowance - unusedPersonalAllowance. Omit and the engine assumes the
     allowance was fully used, charging crypto income that should sit inside it. */
  "personalAllowanceUsedByOtherIncome": 12570,
  /* Adjusted net income EXCLUDING crypto (ITA 2007 s.58). Drives the s.35 taper. */
  "adjustedNetIncome": 45000,
  "broughtForwardLosses": 0,
  "tradingAllowanceUsed": false
}

Response

{ /* UKCryptoResult */ }
POST/api/v1/calculate/uk-traditionalAuth required

Run the UK traditional income tax engine.

Request

{
  "employment": 45000,
  "selfEmployment": 0,
  "rental": 0,
  "dividends": 3000,
  "savingsInterest": 500,
  "pensionContributions": 1000,
  "studentLoanPlan": "none"
}

Response

{ /* UKTraditionalResult */ }
POST/api/v1/reconcileAuth required

Run the 7-pass reconciliation engine and return a summary. confidence is an integer score from 0 to 100.

Request

{
  "transactions": [ /* CryptoTransaction[] */ ]
}

Response

{
  "confidence": 92,
  "criticalCount": 0,
  "warningCount": 2,
  "pricingFlagCount": 0,
  "transferCandidates": 1,
  "missingCostBasis": 0
}
POST/api/v1/importAuth required

Import transactions from a file. Send multipart/form-data with a file field (plus optional client_id, locale UK|US, use_ai_parse, currency GBP|USD|AUD|AED|PKR for valuing Kraken swaps, default your account jurisdiction), or JSON with raw CSV as below. Max 10MB and 30 imports per hour per key. A file already imported for the same client (or your personal workspace) is skipped as a duplicate. client_id must be one of your own clients.

Request

{
  "csv": "date,type,asset,amount,total_value\n2024-05-01,BUY,BTC,1,30000",
  "filename": "trades.csv",
  "client_id": null,
  "locale": "UK"
}

Response

{
  "ok": true,
  "duplicate": false,
  "fileId": "3f0c…",
  "rowsImported": 1,
  "duplicates": 0,
  "warnings": [],
  "format": "<detected format>",
  "parseConfidence": 0.9,
  "clientId": null
}
POST/api/v1/price/historical-gbpAuth required

Bulk historical unit prices, in GBP by default. Optional currency: GBP, USD, AUD, AED or PKR (gbpPrice is null for non-GBP requests; use price). Max 100 pairs per request.

Request

{
  "pairs": [
    { "asset": "BTC", "date": "2024-06-01" },
    { "asset": "ETH", "date": "2024-06-01" }
  ],
  "currency": "GBP"
}

Response

{
  "pairs": [
    {
      "asset": "BTC",
      "date": "2024-06-01",
      "currency": "GBP",
      "price": 51234.5,
      "gbpPrice": 51234.5,
      "source": "binance_klines",
      "confidence": 0.95
    }
  ]
}

Code examples: UK crypto

JavaScript (fetch)

const res = await fetch("https://www.fiscaliq.co/api/v1/calculate/uk-crypto", {
  method: "POST",
  headers: {
    "Authorization": "Bearer fiq_YOUR_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    transactions: [/* ... */],
    taxYear: "2026/27",
    // Taxable non-savings income AFTER the personal allowance, not gross salary.
    taxableNonSavingsIncome: 32430,
    otherTaxableIncome: 0,
    personalAllowanceUsedByOtherIncome: 12570,
    adjustedNetIncome: 45000,
    broughtForwardLosses: 0,
    tradingAllowanceUsed: false,
  }),
});
const result = await res.json();

Python (requests)

import requests

resp = requests.post(
    "https://www.fiscaliq.co/api/v1/calculate/uk-crypto",
    headers={
        "Authorization": "Bearer fiq_YOUR_KEY",
        "Content-Type": "application/json",
    },
    json={
        "transactions": [],  # your CryptoTransaction rows
        "taxYear": "2026/27",
        # Taxable non-savings income AFTER the personal allowance, not gross salary.
        "taxableNonSavingsIncome": 32430,
        "otherTaxableIncome": 0,
        "personalAllowanceUsedByOtherIncome": 12570,
        "adjustedNetIncome": 45000,
        "broughtForwardLosses": 0,
        "tradingAllowanceUsed": False,
    },
    timeout=120,
)
resp.raise_for_status()
result = resp.json()

Error codes

  • 400: Invalid request body or limits exceeded (transaction count, pair count).
  • 401: Missing, invalid, or revoked API key.
  • 403: Processing is restricted for this account (privacy request in effect).
  • 404: The client_iddoesn't belong to your account.
  • 413: File larger than 10MB.
  • 422: The file was read but no transactions could be imported.
  • 429: Daily request limit (shared by all of your keys) or hourly import limit exceeded. Check Retry-After.
  • 500: Engine or server error.
  • 503: The service is temporarily unavailable.