Dokaz Industries

Five small APIs that do one thing well.

Invoice PDFs from JSON. Email verification with real MX checks. Website intelligence. Text AI. QR codes. All on Cloudflare's edge, all with a free tier, no card to start.

Try one right now

curl "https://api.dokaz.net/v1/email/verify?email=someone@gmial.com"
curl "https://api.dokaz.net/v1/qr?data=https://dokaz.net&format=svg" -o qr.svg
curl "https://api.dokaz.net/v1/invoice/sample" -o sample.pdf
curl "https://api.dokaz.net/v1/site/intel?url=https://example.com"

Free tier: 100 calls per day per IP, no key. Paid keys go in the X-Api-Key header.

Products

Invoice PDF

Turn a JSON payload into a clean, professional invoice, estimate or receipt PDF in under a millisecond. Totals, tax and discounts are computed server-side; multi-page output for up to 60 line items.

POST /v1/invoice/pdf — Render an invoice/estimate/receipt as a PDF (application/pdf, Content-Disposition: attachment). Required: number, date (YYYY-MM-DD), from.name, to.name, items[] (description, qty, unit_price). Optional: kind, due, currency (USD/EUR/GBP/CAD/AUD), per-line or global tax_rate (%), discount (amount), notes, terms, paid, logo_text. total = subtotal + tax - discount. Max 60 items.

Request

{
  "kind": "invoice",
  "number": "INV-2026-0142",
  "date": "2026-09-06",
  "due": "2026-10-06",
  "currency": "USD",
  "logo_text": "NORTHWIND",
  "from": {
    "name": "Northwind Studio LLC",
    "address": [
      "1200 Market Street, Suite 410",
      "San Francisco, CA 94102"
    ],
    "email": "billing@northwind.studio",
    "phone": "+1 (415) 555-0142"
  },
  "to": {
    "name": "Acme Robotics Inc.",
    "address": "42 Foundry Lane\nAustin, TX 78701",
    "email": "ap@acme-robotics.com"
  },
  "items": [
    {
      "description": "Brand identity design",
      "qty": 1,
      "unit_price": 2400
    },
    {
      "description": "Product UI design – 6 screens",
      "qty": 6,
      "unit_price": 350
    },
    {
      "description": "Hosting & domain setup",
      "qty": 1,
      "unit_price": 150,
      "tax_rate": 0
    }
  ],
  "tax_rate": 8.25,
  "discount": 200,
  "notes": "Thank you for your business.",
  "terms": "Payment due within 30 days.",
  "paid": false
}

Response

<binary PDF, ~6 KB; header %PDF-1.4>
POST /v1/invoice/preview — Same body as /pdf; returns the computed totals and per-line amounts as JSON so you can check the math before rendering.

Request

{
  "kind": "invoice",
  "number": "INV-2026-0142",
  "date": "2026-09-06",
  "due": "2026-10-06",
  "currency": "USD",
  "logo_text": "NORTHWIND",
  "from": {
    "name": "Northwind Studio LLC",
    "address": [
      "1200 Market Street, Suite 410",
      "San Francisco, CA 94102"
    ],
    "email": "billing@northwind.studio",
    "phone": "+1 (415) 555-0142"
  },
  "to": {
    "name": "Acme Robotics Inc.",
    "address": "42 Foundry Lane\nAustin, TX 78701",
    "email": "ap@acme-robotics.com"
  },
  "items": [
    {
      "description": "Brand identity design",
      "qty": 1,
      "unit_price": 2400
    },
    {
      "description": "Product UI design – 6 screens",
      "qty": 6,
      "unit_price": 350
    },
    {
      "description": "Hosting & domain setup",
      "qty": 1,
      "unit_price": 150,
      "tax_rate": 0
    }
  ],
  "tax_rate": 8.25,
  "discount": 200,
  "notes": "Thank you for your business.",
  "terms": "Payment due within 30 days.",
  "paid": false
}

Response

{
  "subtotal": 4650,
  "tax": 371.25,
  "discount": 200,
  "total": 4821.25,
  "currency": "USD",
  "line_items": [
    {
      "description": "Brand identity design",
      "qty": 1,
      "unit_price": 2400,
      "tax_rate": 8.25,
      "amount": 2400,
      "tax": 198
    },
    {
      "description": "Product UI design – 6 screens",
      "qty": 6,
      "unit_price": 350,
      "tax_rate": 8.25,
      "amount": 2100,
      "tax": 173.25
    },
    {
      "description": "Hosting & domain setup",
      "qty": 1,
      "unit_price": 150,
      "tax_rate": 0,
      "amount": 150,
      "tax": 0
    }
  ]
}
GET /v1/invoice/sample — A sample invoice PDF rendered from built-in demo data (inline, opens in the browser).

Request

Response

<binary PDF, Content-Disposition: inline; filename="invoice-INV-2026-0142.pdf">

Email Verify

Syntax, MX via DNS-over-HTTPS, disposable-domain list, role accounts, typo suggestions — scored 0-100.

GET /v1/email/verify — Verify one address: syntax, MX (DNS-over-HTTPS, with A/AAAA implicit-MX fallback), disposable domain, role account, free provider, typo suggestion, gibberish local part. Returns a 0-100 score; `valid` is syntax AND MX AND not disposable.

Request

GET https://api.dokaz.net/v1/email/verify?email=jane.doe%2Bnews%40gmail.com

Response

{
  "email": "jane.doe+news@gmail.com",
  "normalized": "janedoe@gmail.com",
  "valid": true,
  "score": 100,
  "checks": {
    "syntax": true,
    "domain_has_mx": true,
    "mx_hosts": [
      "gmail-smtp-in.l.google.com",
      "alt1.gmail-smtp-in.l.google.com"
    ],
    "disposable": false,
    "role_account": false,
    "free_provider": true,
    "typo_suggestion": null,
    "gibberish_local": false
  },
  "reason": "ok"
}
POST /v1/email/verify — Same as GET, with a JSON body.

Request

POST https://api.dokaz.net/v1/email/verify
content-type: application/json

{ "email": "sales@gmial.com" }

Response

{
  "email": "sales@gmial.com",
  "normalized": "sales@gmial.com",
  "valid": false,
  "score": 0,
  "checks": {
    "syntax": true,
    "domain_has_mx": false,
    "mx_hosts": [],
    "disposable": false,
    "role_account": true,
    "free_provider": false,
    "typo_suggestion": "gmail.com",
    "gibberish_local": false
  },
  "reason": "domain has no MX or A/AAAA records; role account; did you mean gmail.com?"
}
POST /v1/email/verify/batch — Verify up to 50 addresses concurrently (one DNS lookup per unique domain, at most 45 DNS queries per batch; past that, domain_has_mx is null and reason says "dns budget exhausted"). Results come back in request order. Counts as one API call.

Request

POST https://api.dokaz.net/v1/email/verify/batch
content-type: application/json

{ "emails": ["jane@example.org", "bob@mailinator.com"] }

Response

{
  "count": 2,
  "results": [
    {
      "email": "jane@example.org",
      "valid": false,
      "score": 30,
      "reason": "domain has no MX or A/AAAA records",
      "checks": {
        "...": "..."
      }
    },
    {
      "email": "bob@mailinator.com",
      "valid": false,
      "score": 40,
      "reason": "disposable domain",
      "checks": {
        "...": "..."
      }
    }
  ]
}

Site Intel

URL → title/OG, tech stack, contact emails/phones, socials, analytics, and locked-SaaS platform detection.

GET /v1/site/intel — Fetch a public web page (http/https, up to 3 redirects, first 512 KB; `truncated` says whether more was cut) and return title/meta/OpenGraph, tech stack, locked vertical-SaaS platform (Shopmonkey, Tekmetric, Jobber, Toast, Vagaro, Mindbody, Square Online, ...; only on a positive marker), contact emails/phones, social profiles, link counts, analytics tags, schema.org types and server headers.

Request

GET https://api.dokaz.net/v1/site/intel?url=https%3A%2F%2Frainierplumbing.com

Response

{
  "url": "https://rainierplumbing.com",
  "final_url": "https://www.rainierplumbing.com/",
  "status": 200,
  "redirect_chain": [
    "https://rainierplumbing.com/",
    "https://www.rainierplumbing.com/"
  ],
  "truncated": false,
  "title": "Rainier Plumbing & Heating | Tacoma Plumber",
  "description": "Licensed plumber serving Tacoma and Pierce County. 24/7 emergency service.",
  "canonical": "https://www.rainierplumbing.com/",
  "language": "en-US",
  "favicon": "https://www.rainierplumbing.com/wp-content/uploads/favicon.png",
  "og": {
    "title": "Rainier Plumbing & Heating",
    "description": null,
    "image": "https://www.rainierplumbing.com/wp-content/uploads/van.jpg",
    "type": "website",
    "site_name": "Rainier Plumbing"
  },
  "twitter_card": "summary_large_image",
  "generator": "WordPress 6.5.2",
  "tech": [
    "WordPress",
    "Elementor",
    "jQuery",
    "Google Fonts",
    "reCAPTCHA",
    "Cloudflare"
  ],
  "locked_platform": null,
  "contacts": {
    "emails": [
      "office@rainierplumbing.com"
    ],
    "phones": [
      "+12535550142"
    ],
    "addresses_hint": [
      "1420 Pacific Ave, Tacoma, WA, 98402"
    ]
  },
  "socials": {
    "facebook": "https://www.facebook.com/rainierplumbing",
    "instagram": null,
    "linkedin": null,
    "twitter": null,
    "youtube": null,
    "tiktok": null,
    "yelp": "https://www.yelp.com/biz/rainier-plumbing-tacoma"
  },
  "links": {
    "internal": 42,
    "external": 6
  },
  "has_forms": true,
  "has_analytics": [
    "ga4"
  ],
  "schema_org_types": [
    "Plumber",
    "PostalAddress"
  ],
  "headers": {
    "server": "cloudflare",
    "x_powered_by": null,
    "cf_ray_present": true
  },
  "fetched_at": "2026-09-07T06:12:44.000Z"
}
POST /v1/site/intel — Same as GET, with a JSON body. A scheme-less "example.com" is treated as https://example.com.

Request

POST https://api.dokaz.net/v1/site/intel
content-type: application/json

{ "url": "rainierplumbing.com" }

Response

{
  "url": "https://rainierplumbing.com",
  "final_url": "https://www.rainierplumbing.com/",
  "status": 200,
  "redirect_chain": [
    "https://rainierplumbing.com/",
    "https://www.rainierplumbing.com/"
  ],
  "truncated": false,
  "title": "Rainier Plumbing & Heating | Tacoma Plumber",
  "description": "Licensed plumber serving Tacoma and Pierce County. 24/7 emergency service.",
  "canonical": "https://www.rainierplumbing.com/",
  "language": "en-US",
  "favicon": "https://www.rainierplumbing.com/wp-content/uploads/favicon.png",
  "og": {
    "title": "Rainier Plumbing & Heating",
    "description": null,
    "image": "https://www.rainierplumbing.com/wp-content/uploads/van.jpg",
    "type": "website",
    "site_name": "Rainier Plumbing"
  },
  "twitter_card": "summary_large_image",
  "generator": "WordPress 6.5.2",
  "tech": [
    "WordPress",
    "Elementor",
    "jQuery",
    "Google Fonts",
    "reCAPTCHA",
    "Cloudflare"
  ],
  "locked_platform": null,
  "contacts": {
    "emails": [
      "office@rainierplumbing.com"
    ],
    "phones": [
      "+12535550142"
    ],
    "addresses_hint": [
      "1420 Pacific Ave, Tacoma, WA, 98402"
    ]
  },
  "socials": {
    "facebook": "https://www.facebook.com/rainierplumbing",
    "instagram": null,
    "linkedin": null,
    "twitter": null,
    "youtube": null,
    "tiktok": null,
    "yelp": "https://www.yelp.com/biz/rainier-plumbing-tacoma"
  },
  "links": {
    "internal": 42,
    "external": 6
  },
  "has_forms": true,
  "has_analytics": [
    "ga4"
  ],
  "schema_org_types": [
    "Plumber",
    "PostalAddress"
  ],
  "headers": {
    "server": "cloudflare",
    "x_powered_by": null,
    "cf_ray_present": true
  },
  "fetched_at": "2026-09-07T06:12:44.000Z"
}

Text AI

Summarize, classify, extract, rewrite and score sentiment/keywords with an LLM. JSON in, JSON out.

POST /v1/text/summarize — Summarize text in N sentences, as a paragraph or bullets.

Request

{"text":"Cloudflare Workers run JavaScript at the edge in 300+ cities. They start in under 5ms and scale to zero, so you only pay for requests. D1 adds a SQLite database and Workers AI adds inference, all on the same free tier.","sentences":2,"style":"bullets"}

Response

{
  "summary": "- Cloudflare Workers run edge JavaScript in 300+ cities with sub-5ms cold starts and pay-per-request pricing.\n- D1 (SQLite) and Workers AI (inference) sit on the same free tier.",
  "sentences": 2,
  "input_chars": 213,
  "model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
}
POST /v1/text/sentiment — Sentiment label with a signed score (-1..1) and confidence (0..1). Scores the first 2000 characters.

Request

{"text":"Setup took two minutes and it just worked. Support answered within the hour."}

Response

{
  "label": "positive",
  "score": 0.9982,
  "confidence": 0.9991,
  "model": "@cf/huggingface/distilbert-sst-2-int8"
}
POST /v1/text/keywords — Weighted keywords and key phrases (5..30, default 10). Falls back to a term-frequency ranking (model "fallback") if the LLM output is unusable.

Request

{"text":"Our invoice PDF API turns JSON into a clean one-page invoice or estimate. No template editor, no library, under one millisecond of CPU.","max":5}

Response

{
  "keywords": [
    {
      "term": "invoice pdf api",
      "weight": 0.95
    },
    {
      "term": "json",
      "weight": 0.8
    },
    {
      "term": "estimate",
      "weight": 0.7
    },
    {
      "term": "one-page invoice",
      "weight": 0.65
    },
    {
      "term": "cpu",
      "weight": 0.4
    }
  ],
  "model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
}
POST /v1/text/classify — Zero-shot classification into your own labels (2..20) with a probability per label.

Request

{"text":"My card was charged twice for the same order, please refund one.","labels":["billing","bug report","feature request","other"]}

Response

{
  "label": "billing",
  "scores": {
    "billing": 0.91,
    "bug report": 0.06,
    "feature request": 0.01,
    "other": 0.02
  },
  "model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
}
POST /v1/text/extract — Structured extraction: name the fields you want (1..20) and get a JSON object back, null where absent.

Request

{"text":"Hi, this is Dana Whitfield from Northwind Traders. Call me at (555) 010-2233 or dana@northwind.example to book the 14 March demo.","fields":["name","company","phone","email","date","budget"]}

Response

{
  "data": {
    "name": "Dana Whitfield",
    "company": "Northwind Traders",
    "phone": "(555) 010-2233",
    "email": "dana@northwind.example",
    "date": "14 March",
    "budget": null
  },
  "model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
}
POST /v1/text/rewrite — Rewrite in a tone: professional, casual, concise, friendly or formal. Facts are preserved.

Request

{"text":"hey so the thing is broken again, can u fix it today?? kinda urgent","tone":"professional"}

Response

{
  "text": "Hello, the issue has reoccurred. Could you please address it today? It is fairly urgent.",
  "model": "@cf/meta/llama-3.3-70b-instruct-fp8-fast"
}

QR Code API

Generate QR codes as SVG or PNG (or the raw module matrix) — URLs, text, Wi‑Fi credentials and vCards. Versions 1–40, all EC levels, custom colours, rounded modules.

GET /v1/qr — Render a QR code. Params: data (required, ≤2953 bytes), format=svg|png (default svg), size=64..2048 px (default 512), margin=0..10 modules (default 4), ec=L|M|Q|H (default M), fg/bg hex colours, rounded=0|1. Responds with the image and a one-year cache header; x-qr-version and x-qr-modules headers describe the symbol.

Request

GET /v1/qr?data=https%3A%2F%2Fdokaz.net&format=svg&size=256&ec=Q&fg=%23112233

Response

<svg xmlns="http://www.w3.org/2000/svg" width="256" height="256" viewBox="0 0 33 33" shape-rendering="crispEdges"><rect width="33" height="33" fill="#ffffff"/><path fill="#112233" d="M4 4h7v1h-7z…"/></svg>
POST /v1/qr — Same parameters as GET, as a JSON body. format="json" returns the raw module matrix (rows of 1/0) so you can render it yourself.

Request

POST /v1/qr
{"data":"HELLO WORLD","ec":"M","format":"json"}

Response

{"version":1,"ec":"M","mode":"alphanumeric","mask":2,"modules":21,"matrix":["111111100101001111111","100000101010101000001",…]}
GET /v1/qr/wifi — QR code that joins a Wi‑Fi network when scanned. Params: ssid (required), password, type=WPA|WEP|nopass (default WPA), hidden=0|1, plus any render params (format, size, ec, fg, bg, margin, rounded).

Request

GET /v1/qr/wifi?ssid=Cafe%20Guest&password=latte123&type=WPA&format=png&size=300

Response

(image/png, 300×300; payload WIFI:T:WPA;S:Cafe Guest;P:latte123;;)
GET /v1/qr/vcard — QR code holding a vCard 3.0 contact. Params: name (required), phone, email, org, url, plus any render params.

Request

GET /v1/qr/vcard?name=Ada%20Lovelace&phone=%2B44%2020%207946%200958&email=ada%40example.com&org=Analytical%20Engines&url=https%3A%2F%2Fexample.com

Response

(image/svg+xml; payload BEGIN:VCARD VERSION:3.0 N:Lovelace;Ada;;; FN:Ada Lovelace ORG:Analytical Engines TEL;TYPE=CELL:+44 20 7946 0958 EMAIL;TYPE=INTERNET:ada@example.com URL:https://example.com END:VCARD)

Pricing

Free

$0
  • 100 calls / day
  • Every product
  • No card, no key
Just call it

Starter

$9/mo
  • 10,000 calls / month
  • Every product
  • Key issued instantly
Get Starter

Pro

$29/mo
  • 100,000 calls / month
  • Every product
  • Priority routing
Get Pro

Business

$79/mo
  • 500,000 calls / month
  • Every product
  • Email support
Get Business

Cancel any time from your Stripe receipt. Also available on the RapidAPI hub. Quotas are monthly, counted per key; usage is in every response's x-quota-used header.