{
  "openapi": "3.0.3",
  "info": {
    "title": "Dokaz Industries API",
    "version": "1.0.0",
    "description": "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.\nEmail Verify: Syntax, MX via DNS-over-HTTPS, disposable-domain list, role accounts, typo suggestions — scored 0-100.\nSite Intel: URL → title/OG, tech stack, contact emails/phones, socials, analytics, and locked-SaaS platform detection.\nText AI: Summarize, classify, extract, rewrite and score sentiment/keywords with an LLM. JSON in, JSON out.\nQR 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."
  },
  "servers": [
    {
      "url": "https://api.dokaz.net"
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    }
  },
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/v1/invoice/pdf": {
      "post": {
        "tags": [
          "Invoice PDF"
        ],
        "summary": "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.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "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
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": "<binary PDF, ~6 KB; header %PDF-1.4>"
              }
            }
          }
        }
      }
    },
    "/v1/invoice/preview": {
      "post": {
        "tags": [
          "Invoice PDF"
        ],
        "summary": "Same body as /pdf; returns the computed totals and per-line amounts as JSON so you can check the math before rendering.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "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
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/invoice/sample": {
      "get": {
        "tags": [
          "Invoice PDF"
        ],
        "summary": "A sample invoice PDF rendered from built-in demo data (inline, opens in the browser).",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": "<binary PDF, Content-Disposition: inline; filename=\"invoice-INV-2026-0142.pdf\">"
              }
            }
          }
        }
      }
    },
    "/v1/email/verify": {
      "get": {
        "tags": [
          "Email Verify"
        ],
        "summary": "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.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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": {
        "tags": [
          "Email Verify"
        ],
        "summary": "Same as GET, with a JSON body.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": "POST https://api.dokaz.net/v1/email/verify\ncontent-type: application/json\n\n{ \"email\": \"sales@gmial.com\" }"
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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?"
                }
              }
            }
          }
        }
      }
    },
    "/v1/email/verify/batch": {
      "post": {
        "tags": [
          "Email Verify"
        ],
        "summary": "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.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": "POST https://api.dokaz.net/v1/email/verify/batch\ncontent-type: application/json\n\n{ \"emails\": [\"jane@example.org\", \"bob@mailinator.com\"] }"
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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": {
                        "...": "..."
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/site/intel": {
      "get": {
        "tags": [
          "Site Intel"
        ],
        "summary": "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.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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": {
        "tags": [
          "Site Intel"
        ],
        "summary": "Same as GET, with a JSON body. A scheme-less \"example.com\" is treated as https://example.com.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": "POST https://api.dokaz.net/v1/site/intel\ncontent-type: application/json\n\n{ \"url\": \"rainierplumbing.com\" }"
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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"
                }
              }
            }
          }
        }
      }
    },
    "/v1/text/summarize": {
      "post": {
        "tags": [
          "Text AI"
        ],
        "summary": "Summarize text in N sentences, as a paragraph or bullets.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "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"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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"
                }
              }
            }
          }
        }
      }
    },
    "/v1/text/sentiment": {
      "post": {
        "tags": [
          "Text AI"
        ],
        "summary": "Sentiment label with a signed score (-1..1) and confidence (0..1). Scores the first 2000 characters.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "text": "Setup took two minutes and it just worked. Support answered within the hour."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "label": "positive",
                  "score": 0.9982,
                  "confidence": 0.9991,
                  "model": "@cf/huggingface/distilbert-sst-2-int8"
                }
              }
            }
          }
        }
      }
    },
    "/v1/text/keywords": {
      "post": {
        "tags": [
          "Text AI"
        ],
        "summary": "Weighted keywords and key phrases (5..30, default 10). Falls back to a term-frequency ranking (model \"fallback\") if the LLM output is unusable.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "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
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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"
                }
              }
            }
          }
        }
      }
    },
    "/v1/text/classify": {
      "post": {
        "tags": [
          "Text AI"
        ],
        "summary": "Zero-shot classification into your own labels (2..20) with a probability per label.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "text": "My card was charged twice for the same order, please refund one.",
                "labels": [
                  "billing",
                  "bug report",
                  "feature request",
                  "other"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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"
                }
              }
            }
          }
        }
      }
    },
    "/v1/text/extract": {
      "post": {
        "tags": [
          "Text AI"
        ],
        "summary": "Structured extraction: name the fields you want (1..20) and get a JSON object back, null where absent.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "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"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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"
                }
              }
            }
          }
        }
      }
    },
    "/v1/text/rewrite": {
      "post": {
        "tags": [
          "Text AI"
        ],
        "summary": "Rewrite in a tone: professional, casual, concise, friendly or formal. Facts are preserved.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": {
                "text": "hey so the thing is broken again, can u fix it today?? kinda urgent",
                "tone": "professional"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "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"
                }
              }
            }
          }
        }
      }
    },
    "/v1/qr": {
      "get": {
        "tags": [
          "QR Code API"
        ],
        "summary": "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.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": "<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": {
        "tags": [
          "QR Code API"
        ],
        "summary": "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.",
        "requestBody": {
          "content": {
            "application/json": {
              "example": "POST /v1/qr\n{\"data\":\"HELLO WORLD\",\"ec\":\"M\",\"format\":\"json\"}"
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": "{\"version\":1,\"ec\":\"M\",\"mode\":\"alphanumeric\",\"mask\":2,\"modules\":21,\"matrix\":[\"111111100101001111111\",\"100000101010101000001\",…]}"
              }
            }
          }
        }
      }
    },
    "/v1/qr/wifi": {
      "get": {
        "tags": [
          "QR Code API"
        ],
        "summary": "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).",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": "(image/png, 300×300; payload WIFI:T:WPA;S:Cafe Guest;P:latte123;;)"
              }
            }
          }
        }
      }
    },
    "/v1/qr/vcard": {
      "get": {
        "tags": [
          "QR Code API"
        ],
        "summary": "QR code holding a vCard 3.0 contact. Params: name (required), phone, email, org, url, plus any render params.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": "(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)"
              }
            }
          }
        }
      }
    }
  }
}