BizNode handles — the universal AI service primitive
A handle is a named, pay-per-call AI service.
Every handle has a clickable URL:
https://app.1bz.biz/h/<bot>-<handle>.
That URL works in any DM, post, email, SMS, QR code — no per-platform SDK to install.
Billing is on-chain DZIT (a gas credit), paid per call, split 70/20/10 between provider, referrer, platform.
30-second quickstart
List every public handle in the network — no auth, no key, one curl:
curl -s "https://biznode.1bz.biz/api_public.php?action=handles&limit=20" \
| python -m json.tool | head
Open any handle directly by dropping its slug into the URL bar:
open https://app.1bz.biz/h/biznode_bot-askai
open https://app.1bz.biz/h/biznode_bot-ping
No SDK. No platform registration. Share these URLs anywhere — Slack, Discord, WhatsApp, LinkedIn, email — they just work.
Tutorial — share a service in 3 minutes
There is no special bot infrastructure to set up. Any service in the BizNode network is reachable through a single Telegram deep link of the form
https://t.me/biznode_bot?start=<subdomain>_<handle>.
Click → mother bot routes → first 2-10 invocations free → DZIT charged after.
We will walk through the FV (KYC verification) subdomain end-to-end.
1. Pick a service
Browse the public catalog at app.1bz.biz/handles. For this tutorial we use FV (face & voice verification). The handles available on FV today:
verify_kyc— full KYC pass: ID document + selfie + livenessface_match— compare two faces, return a similarity scoreaskai_fv— ask the FV knowledge base any KYC / compliance question
2. Build the deep link
The pattern is always the same:
https://t.me/biznode_bot?start=<subdomain>_<handle>
For FV, you have two useful entry points:
# Subdomain landing — opens FV's full handle catalog
https://t.me/biznode_bot?start=fv_main
# Specific handle — jumps straight into KYC
https://t.me/biznode_bot?start=fv_verify_kyc
That URL is the integration. No SDK, no webhook to register, no per-platform adapter.
3. Pin it somewhere
Drop the URL into any channel where your customer already is:
Telegram channel description / pinned message
Verify any customer in 30 seconds — KYC, face match, ID extract.
First 2 invocations free, then 5 DZIT each.
👉 https://t.me/biznode_bot?start=fv_main
WhatsApp / Instagram / Facebook DM — paste the same URL. Telegram's mobile deep link opens the app directly:
https://t.me/biznode_bot?start=fv_verify_kyc
Sister-site CTA button — drop one line of HTML into any landing page:
<a href="https://t.me/biznode_bot?start=fv_main" class="cta">
Verify customer →
</a>
QR code — generate a QR of the URL with any free generator (qr-code-generator.com, qrcode-monkey.com, etc.) and print it on a business card, poster, or product packaging:
QR encodes: https://t.me/biznode_bot?start=fv_main
Camera scan → Telegram opens → handle fires
4. What the user sees
- Click the link → Telegram opens with a Start button on
@biznode_bot. - First time only: the bot asks for an email, sends a 6-digit code, the user pastes the code back, account is verified.
- The bot runs the handle (
verify_kyc) and returns the result in the same chat — no app switch, no separate website. - A footer line tells the user the cost:
Cost: FREE (1 use left)while inside the free quota, thenCost: 5.0 DZITon paid invocations.
5. What you (the operator) see
- Email + Telegram notification:
Handle Invokedfollowed byPayment Released, both stamped with a workflow ID (WFID) for reconciliation. - Free-quota usage is tracked per (user, bot, handle) — once a user exhausts their free calls, every subsequent invocation is paid.
- Paid invocations split DZIT 70% provider / 20% referrer / 10% platform, settled on Polygon and visible in your DZIT transaction history.
Common variations
- Verified vs unverified users: every link works the same — a verified user invokes the handle immediately, an unverified user gets the email-OTP gate first and then the handle auto-fires on success.
- Multiple subdomains in one channel: pin all 9 ready-made cards from the reference list
docs/BIZNODE_DEEP_LINK_CARDS.md(FV, DX, UBC, Fax, CopyGuard, IPVault, DZIT, SmartPDF, BizChannel) — one card per service, copy-paste ready. - Track which channel a user came from: append
&utm_source=<channel>after the start payload, e.g.?start=fv_main&utm_source=instagram_bio. Telegram passes the parameter through to the bot's payload parser so you can attribute conversions.
The handle URL pattern
Every public handle has a stable, shareable URL:
https://app.1bz.biz/h/<bot-name>-<handle-name>
You can also use the UUID if you already have it:
https://app.1bz.biz/h/<handle-uuid>
Pasted URLs auto-render a per-handle preview card in Facebook, LinkedIn, Slack, Discord and WhatsApp. Clicks land on the handle's form; first-time users sign in with an email magic link (30-min expiry), then invoke.
If the URL is issued from a BizNode Telegram bot (e.g. a button from @biznode_bot), it carries a signed chat_id param. Clicks skip email login — the user's Telegram identity is auto-recognised.
API endpoints
| Method | Endpoint | Auth | Purpose |
|---|---|---|---|
| GET | biznode.1bz.biz/api_public.php?action=handles |
none | Public handle catalog. Filter with &industry=, &q=, &bot_id=, &limit=. |
| GET | biznode.1bz.biz/api_public.php?action=bots |
none | Public bot directory. |
| POST | app.1bz.biz/api/app/auth/request |
none | Send a magic-link email for web login. Body: {"email":"…"}. |
| POST | app.1bz.biz/api/app/auth/verify |
none | Exchange magic-link token for a JWT. Body: {"email":"…","token":"…"}. |
| GET | app.1bz.biz/api/app/me |
JWT bearer | Current user: email, balance, tier, bot_id. |
| GET | app.1bz.biz/api/app/handles |
JWT bearer | Catalog with JWT context. Filter with ?node=, ?bot_name=, ?industry=. |
| POST | app.1bz.biz/api/app/invoke |
JWT bearer | Invoke a handle. Body: {"handle_id":"…","input_data":{…}}. Deducts DZIT (or consumes free quota), returns {ok, result, balance, wfid, telegram_pushed}. |
Authentication
Today, authenticated endpoints require a user JWT obtained via the magic-link flow. Two-step:
# 1. Request magic link — user receives email with a one-time click URL
curl -s -X POST https://app.1bz.biz/api/app/auth/request \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com"}'
# 2. User clicks the email link → your frontend extracts ?token &email,
# posts to verify and receives a JWT (sub=email, 14-day HS256)
curl -s -X POST https://app.1bz.biz/api/app/auth/verify \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","token":"<from URL>"}'
# -> {"ok":true,"token":"eyJ..."}
API keys (server-to-server): coming soon. For now, obtain a user JWT and reuse it for 14 days.
Telegram users — in-chat email OTP: if a user opens a handle via t.me/biznode_bot?start=<subdomain>_<handle> and their chat_id is not yet linked to an email, @biznode_bot asks for their email in-chat, emails a one-time code, the user replies with the code, and the original handle auto-fires with the result returned to the same chat. No channel-switch, no magic link. Verified users skip this entirely.
Integrate with Slack
Slash command /biznode <handle> replies with a Block Kit button that opens the handle on BizNode. No backend state needed — the URL IS the integration.
from slack_bolt import App
import os, urllib.parse
app = App(token=os.environ["SLACK_BOT_TOKEN"],
signing_secret=os.environ["SLACK_SIGNING_SECRET"])
@app.command("/biznode")
def biznode_cmd(ack, command, respond):
ack()
text = (command.get("text") or "").strip() or "askai"
# text is the handle slug, e.g. "biznode_bot-askai" or just "askai"
if "-" not in text:
text = f"biznode_bot-{text}"
url = f"https://app.1bz.biz/h/{urllib.parse.quote(text)}"
respond(blocks=[
{"type": "section",
"text": {"type": "mrkdwn",
"text": f"Run *{text}* on BizNode (pay-per-call with DZIT):"}},
{"type": "actions", "elements": [
{"type": "button", "url": url,
"text": {"type": "plain_text", "text": "Open handle \u2197"},
"style": "primary"}]}])
if __name__ == "__main__":
app.start(int(os.environ.get("PORT", 3000)))
Integrate with Discord
Slash command /biznode posts a message with a link button (button style 5).
import discord, os
from discord import app_commands
from discord.ui import View, Button
intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)
@tree.command(name="biznode", description="Invoke a BizNode handle")
@app_commands.describe(handle="Handle slug, e.g. biznode_bot-askai")
async def biznode(interaction: discord.Interaction, handle: str = "askai"):
slug = handle if "-" in handle else f"biznode_bot-{handle}"
url = f"https://app.1bz.biz/h/{slug}"
view = View()
view.add_item(Button(label="Open handle", url=url, style=discord.ButtonStyle.link))
await interaction.response.send_message(
f"Run **{slug}** on BizNode (pay-per-call with DZIT):",
view=view, ephemeral=True)
@client.event
async def on_ready():
await tree.sync()
client.run(os.environ["DISCORD_BOT_TOKEN"])
Integrate with WhatsApp Business
Send an interactive CTA URL button via Meta Cloud API. Requires a WABA phone number ID + access token.
import os, requests
PHONE_ID = os.environ["WA_PHONE_NUMBER_ID"]
TOKEN = os.environ["WA_ACCESS_TOKEN"]
def send_handle_button(to_phone_e164: str, handle_slug: str = "biznode_bot-askai"):
url = f"https://graph.facebook.com/v19.0/{PHONE_ID}/messages"
body = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": to_phone_e164,
"type": "interactive",
"interactive": {
"type": "cta_url",
"body": {"text": f"Run *{handle_slug}* on BizNode. Pay-per-call with DZIT."},
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Open handle",
"url": f"https://app.1bz.biz/h/{handle_slug}"}}}}
r = requests.post(url, json=body,
headers={"Authorization": f"Bearer {TOKEN}"}, timeout=15)
r.raise_for_status()
return r.json()
Integrate with Node / Express
A webhook that emails a customer a personalised BizNode handle link — works with any mail provider that accepts HTML:
import express from "express";
import nodemailer from "nodemailer";
const app = express();
app.use(express.json());
const transport = nodemailer.createTransport({
host: process.env.SMTP_HOST, port: 587,
auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS }});
app.post("/lead", async (req, res) => {
const { email, handle = "biznode_bot-askai" } = req.body;
const url = `https://app.1bz.biz/h/${encodeURIComponent(handle)}`;
await transport.sendMail({
from: process.env.SMTP_USER, to: email,
subject: "Try our AI service — first 10 calls free",
html: `<p>Run <b>${handle}</b> on BizNode:</p>
<p><a href="${url}" style="background:#0ea5e9;color:#fff;
padding:10px 18px;border-radius:8px;text-decoration:none">
Open handle \u2197</a></p>`});
res.json({ ok: true });
});
app.listen(3000);
Vanilla Python — list handles from the catalog
import requests
CATALOG = "https://biznode.1bz.biz/api_public.php"
def list_handles(query=None, industry=None, limit=50):
params = {"action": "handles", "limit": limit}
if query: params["q"] = query
if industry: params["industry"] = industry
return requests.get(CATALOG, params=params, timeout=15).json()
for h in list_handles(query="ai", limit=20):
slug = f"{h['bot_name'].lstrip('@')}-{h['handle_name']}"
print(f"{slug:40s} {h['dzit_cost']:>5.2f} DZIT "
f"https://app.1bz.biz/h/{slug}")
Pricing & DZIT
DZIT is BizNode's on-chain pay-per-call credit (Polygon). Every handle sets its own dzit_cost. Each successful invocation deducts from the caller's balance and splits:
- 70% → the handle's provider (bot owner)
- 20% → the referrer (e.g. the site/app that sent the user)
- 10% → the BizNode platform
Free tier: public handles may declare a free_quota. Each user gets that many free calls per bot + handle before DZIT charging kicks in. Example: askai is 10 free calls per user per bot.
How charging works: The first N invocations of any handle are free per user (configurable per handle). Beyond that, DZIT is deducted from the user's account, with a 70/20/10 split between provider, referrer, and BizNode platform.
Topping up: users purchase DZIT credit packs from $10 to $10,000 via the BizNode dashboard. New web signups get 10 DZIT free.
Publish your own handle
Any registered BizNode bot can publish handles. Public handle registration costs 1 DZIT (one-time). After that, every invocation pays you 70% of its dzit_cost.
curl -s -X POST https://app.1bz.biz/api/handles/register \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <your JWT>' \
-d '{
"bot_id": "BZBOT-XXXXXX",
"handle_name": "quote",
"display_name": "Price quote",
"description": "Return a one-line price quote for my service.",
"is_public": 1,
"dzit_cost": 2.0,
"free_quota": 3,
"fields_schema": [
{"name":"service","type":"string","required":true},
{"name":"region","type":"string","required":false}
],
"handler_type": "llm"
}'
Changelog
- 2026-04-20 — Removed redirector multiplex. Reach any subdomain via a deep link directly:
t.me/biznode_bot?start=<sub>_<handle>. - 2026-04-19 (evening) — Free-quota system live: every handle ships with a configurable free-call ceiling per user (typically 2-10 calls). Bot replies now surface
Cost: FREE (X uses left)on free invocations, and the redundant "Payment Released" line is suppressed when no escrow is involved. DZIT is now deducted from the user's email-keyed account balance once free quota is exhausted, with the same 70/20/10 split. Subdomain redirector multiplex is live: 5 of 9 lightweight subdomain bots (@fvbiznode_bot,@dxbiznode_bot,@ubcbiznode_bot,@faxbiznode_bot,@copy_guardbot) reply to/startwith a deep link back to@biznode_bot. Note: the FV brand bot's canonical handle is@fvbiznode_bot(no underscore). - 2026-04-19 — Phase 4 Mother-Bot:
@biznode_botnow serves all 11 subdomains via/start <subdomain>_<handle>deep-link payloads (e.g.t.me/biznode_bot?start=fv_verify_kyc). The 9 subdomain brand bots (@fvbiznode_bot,@faxbiznode_bot,@copy_guardbot, etc.) run as a lightweight redirector multiplex and answer/startwith a pre-filled link to the mother bot. Unverified Telegram users now complete email verification in-chat via OTP; the original handle auto-fires on success. Web, Telegram, and shareable-URL paths all settle through the same/api/handles/invokepipeline with DZIT 70/20/10 split. - 2026-04-18 — Per-handle OG share cards, human-readable slugs, free-quota system (DB-driven), multi-platform docs.
- 2026-04-17 — Phase 2 Week 1: Telegram↔app bridge (signed URL auto-login). Phase 1 complete.
Last updated: 2026-04-20 · Open issues? postmaster@1bz.biz