docs: add REST API documentation and installation guide

This commit is contained in:
thakares committed 2026-06-18 12:17:16 +05:30
1 parent 74524cb7d2
commit 17d8618443
2 files changed
+704 -218

No files matched your search

+391
View File
@@ -0,0 +1,391 @@
# BZOD REST API
> Programmatic access to URLs, Landing Pages, QR Codes, Analytics, and Audit Logs.
## Overview
The BZOD REST API allows automation and integration with external systems such as:
* Home Assistant
* Shell Scripts
* CI/CD Pipelines
* Monitoring Systems
* Internal Applications
* Self-hosted Services
All API endpoints require authentication using an API Token generated from:
```text
Admin Dashboard → Settings → REST API Tokens
```
---
# Authentication
Generate an API token from the Admin Dashboard.
Example token:
```text
bzo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```
Pass the token using the `Authorization` header.
## Example
```bash
curl \
-H "Authorization: bzo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
https://your-domain.com/api/v1/stats
```
---
# Base URL
```text
https://your-domain.com/api/v1
```
Example:
```text
https://bzo.in/api/v1
```
---
# Response Format
Successful responses:
```json
{
"success": true,
"data": {}
}
```
Error responses:
```json
{
"success": false,
"error": "Invalid API token"
}
```
---
# URL Management
## List URLs
```http
GET /api/v1/urls
```
### Example
```bash
curl \
-H "Authorization: TOKEN" \
https://your-domain.com/api/v1/urls
```
---
## Create URL
```http
POST /api/v1/urls
```
### Request
```json
{
"code": "rust",
"target_url": "https://www.rust-lang.org",
"description": "Rust Language"
}
```
### Example
```bash
curl \
-X POST \
-H "Authorization: TOKEN" \
-H "Content-Type: application/json" \
-d '{
"code":"rust",
"target_url":"https://www.rust-lang.org"
}' \
https://your-domain.com/api/v1/urls
```
---
## Get URL
```http
GET /api/v1/urls/{uuid}
```
Example:
```http
GET /api/v1/urls/5d4d9e98-7cb7-4c97-9a0a-123456789abc
```
---
## Update URL
```http
PUT /api/v1/urls/{uuid}
```
---
## Delete URL
```http
DELETE /api/v1/urls/{uuid}
```
---
## URL Preview
```http
GET /api/v1/urls/{uuid}/preview
```
Returns rendered metadata used by preview cards.
---
# Landing Pages
## List Pages
```http
GET /api/v1/pages
```
---
## Create Page
```http
POST /api/v1/pages
```
### Example Request
```json
{
"title": "My Product",
"slug": "product",
"description": "Product Landing Page",
"content": "<h1>Hello World</h1>"
}
```
---
## Get Page
```http
GET /api/v1/pages/{uuid}
```
---
## Update Page
```http
PUT /api/v1/pages/{uuid}
```
---
## Delete Page
```http
DELETE /api/v1/pages/{uuid}
```
---
# Analytics
## Global Statistics
```http
GET /api/v1/stats
```
Returns overall platform metrics.
Example response:
```json
{
"total_urls": 125,
"total_pages": 12,
"total_clicks": 8431,
"total_qr_scans": 241
}
```
---
## URL Statistics
```http
GET /api/v1/stats/url/{uuid}
```
Returns analytics for a single URL.
---
## Landing Page Statistics
```http
GET /api/v1/stats/page/{uuid}
```
Returns analytics for a single landing page.
---
# QR Codes
## Download QR Code
```http
GET /api/v1/qr/{code}
```
Example:
```http
GET /api/v1/qr/rust
```
Returns QR image.
---
# Bulk Operations
## Bulk QR Export
```http
POST /api/v1/bulk/qr
```
Generate QR codes for multiple URLs.
---
## Bulk URL Operations
```http
POST /api/v1/bulk/url
```
Bulk create, update, or manage URLs.
---
# Audit Log
## List Audit Events
```http
GET /api/v1/audit
```
Returns administrative activity history.
Example response:
```json
[
{
"event": "url_created",
"user": "admin",
"timestamp": "2026-06-17T14:30:00Z"
}
]
```
---
# HTTP Status Codes
| Code | Description |
| ---- | --------------------- |
| 200 | Success |
| 201 | Created |
| 400 | Invalid Request |
| 401 | Authentication Failed |
| 403 | Access Denied |
| 404 | Resource Not Found |
| 409 | Conflict |
| 500 | Internal Server Error |
---
# Security Notes
* API tokens are displayed only once during creation.
* Tokens are stored as hashes and cannot be recovered.
* Revoke unused tokens immediately.
* Always use HTTPS.
* Never embed API tokens in public repositories.
---
# Example: Create URL From Shell Script
```bash
TOKEN="bzo_xxxxxxxxxxxxxxxxx"
curl \
-X POST \
-H "Authorization: ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"code":"example",
"target_url":"https://example.com"
}' \
https://your-domain.com/api/v1/urls
```
---
# API Stability
The BZOD API follows semantic versioning.
Current API namespace:
```text
/api/v1
```
Future breaking changes will be introduced under a new versioned namespace.
Example:
```text
/api/v2
```
+313 -218
View File
@@ -1,237 +1,332 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>BZOD — Private • Fast • Beautiful URL Shortener</title> <title>BZOD — Private • Fast • Beautiful URL Shortener</title>
<script src="https://cdn.tailwindcss.com"></script> <script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"> <link
<style> rel="stylesheet"
body { font-family: 'Inter', system-ui, sans-serif; } href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"
.hero-bg { />
background: linear-gradient(135deg, #1a1a2e 0%, #0f0f1e 100%); <style>
} body {
</style> font-family: "Inter", system-ui, sans-serif;
</head> }
<body class="bg-zinc-950 text-zinc-200"> .hero-bg {
<!-- Hero --> background: linear-gradient(135deg, #1a1a2e 0%, #0f0f1e 100%);
<section class="hero-bg py-24"> }
<div class="max-w-5xl mx-auto px-6 text-center"> </style>
<div class="inline-flex items-center gap-2 bg-zinc-900 border border-zinc-700 rounded-full px-4 py-1.5 mb-6"> </head>
<span class="text-emerald-400">●</span> <body class="bg-zinc-950 text-zinc-200">
<span class="text-sm font-medium">Self-hosted • Rust • Single Binary</span> <!-- Hero -->
</div> <section class="hero-bg py-24">
<div class="max-w-5xl mx-auto px-6 text-center">
<h1 class="text-6xl md:text-7xl font-bold tracking-tighter mb-6"> <div
Short links.<br> class="inline-flex items-center gap-2 bg-zinc-900 border border-zinc-700 rounded-full px-4 py-1.5 mb-6"
<span class="bg-gradient-to-r from-violet-400 to-fuchsia-400 bg-clip-text text-transparent">Your domain.</span> >
</h1> <span class="text-emerald-400">●</span>
<span class="text-sm font-medium"
<p class="text-2xl text-zinc-400 max-w-2xl mx-auto mb-10"> >Self-hosted • Rust • Single Binary</span
Beautiful, private, and powerful URL shortener with rich landing pages, QR codes, analytics, and full CLI control. >
</p>
<div class="flex flex-wrap justify-center gap-4">
<a href="https://github.com/thakares/nx9-url-shortener"
target="_blank"
class="bg-white text-black px-8 py-4 rounded-2xl font-semibold flex items-center gap-3 hover:scale-105 transition">
<i class="fab fa-github text-xl"></i>
View on GitHub
</a>
<a href="/admin"
class="bg-violet-600 hover:bg-violet-700 px-8 py-4 rounded-2xl font-semibold transition">
Admin Dashboard →
</a>
</div>
<div class="mt-16 text-sm text-zinc-500">
Powered by <span class="font-mono text-emerald-400">bzo.in</span>
</div>
</div>
<!-- Highlights -->
<div class="max-w-6xl mx-auto px-6 -mt-10 relative z-10">
<div class="grid grid-cols-2 lg:grid-cols-5
bg-zinc-950/70 backdrop-blur-md
border border-zinc-800
rounded-3xl overflow-hidden">
<!-- Single Binary -->
<div class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800">
<i class="fas fa-bolt text-emerald-400 text-4xl mb-4"></i>
<h3 class="font-semibold text-xl mb-2">Single Binary</h3>
<p class="text-zinc-400 text-sm">
~18 MB Rust binary.<br>
No runtime required.
</p>
</div> </div>
<!-- SQLite --> <h1
<div class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800"> class="text-6xl md:text-7xl font-bold tracking-tighter mb-6"
<i class="fas fa-database text-emerald-400 text-4xl mb-4"></i> >
<h3 class="font-semibold text-xl mb-2">SQLite</h3> Short links.<br />
<p class="text-zinc-400 text-sm"> <span
Zero configuration.<br> class="bg-gradient-to-r from-violet-400 to-fuchsia-400 bg-clip-text text-transparent"
WAL mode enabled. >Your domain.</span
</p> >
</h1>
<p class="text-2xl text-zinc-400 max-w-2xl mx-auto mb-10">
Beautiful, private, and powerful URL shortener with rich
landing pages, QR codes, analytics, and full CLI control.
</p>
<div class="flex flex-wrap justify-center gap-4">
<a
href="https://github.com/thakares/nx9-url-shortener"
target="_blank"
class="bg-white text-black px-8 py-4 rounded-2xl font-semibold flex items-center gap-3 hover:scale-105 transition"
>
<i class="fab fa-github text-xl"></i>
View on GitHub
</a>
<a
href="/admin"
class="bg-violet-600 hover:bg-violet-700 px-8 py-4 rounded-2xl font-semibold transition"
>
Admin Dashboard →
</a>
</div> </div>
<!-- REST API --> <div class="mt-16 text-sm text-zinc-500">
<div class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800"> Powered by
<i class="fas fa-code text-emerald-400 text-4xl mb-4"></i> <span class="font-mono text-emerald-400">bzo.in</span>
<h3 class="font-semibold text-xl mb-2">REST API</h3>
<p class="text-zinc-400 text-sm">
Full automation.<br>
JSON everywhere.
</p>
</div>
<!-- Self Hosted -->
<div class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800">
<i class="fas fa-server text-emerald-400 text-4xl mb-4"></i>
<h3 class="font-semibold text-xl mb-2">Self Hosted</h3>
<p class="text-zinc-400 text-sm">
Your links.<br>
Your infrastructure.
</p>
</div>
<!-- MIT -->
<div class="p-8 text-center">
<i class="fas fa-shield-alt text-emerald-400 text-4xl mb-4"></i>
<h3 class="font-semibold text-xl mb-2">MIT License</h3>
<p class="text-zinc-400 text-sm">
Open source.<br>
Commercial friendly.
</p>
</div>
</div>
</div>
</section>
<!-- Features -->
<section class="py-20 bg-zinc-900">
<div class="max-w-5xl mx-auto px-6">
<h2 class="text-4xl font-bold text-center mb-16">Why people love BZOD</h2>
<div class="grid md:grid-cols-3 gap-8">
<div class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8">
<div class="text-4xl mb-6">⚡</div>
<h3 class="text-2xl font-semibold mb-3">Lightning Fast</h3>
<p class="text-zinc-400">~18 MB single Rust binary. Starts instantly. Uses SQLite with WAL mode. Minimal resource usage.</p>
</div>
<div class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8">
<div class="text-4xl mb-6">🔒</div>
<h3 class="text-2xl font-semibold mb-3">Private by Design</h3>
<p class="text-zinc-400">No telemetry. No third-party services. Everything runs on your server. Strong password hashing & audit logs.</p>
</div>
<div class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8">
<div class="text-4xl mb-6">🎨</div>
<h3 class="text-2xl font-semibold mb-3">Beautiful Links</h3>
<p class="text-zinc-400">Rich custom landing pages with title, description, OG metadata, and branded preview.</p>
</div> </div>
</div> </div>
<!-- Highlights -->
<div class="max-w-6xl mx-auto px-6 -mt-10 relative z-10">
<div
class="grid grid-cols-2 lg:grid-cols-5 bg-zinc-950/70 backdrop-blur-md border border-zinc-800 rounded-3xl overflow-hidden"
>
<!-- Single Binary -->
<div
class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800"
>
<i
class="fas fa-bolt text-emerald-400 text-4xl mb-4"
></i>
<h3 class="font-semibold text-xl mb-2">
Single Binary
</h3>
<p class="text-zinc-400 text-sm">
~18 MB Rust binary.<br />
No runtime required.
</p>
</div>
<div class="grid md:grid-cols-3 gap-8 mt-8"> <!-- SQLite -->
<div class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"> <div
<div class="text-4xl mb-6">📱</div> class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800"
<h3 class="text-2xl font-semibold mb-3">QR Codes Built-in</h3> >
<p class="text-zinc-400">Generate PNG & SVG QR codes. Track scans separately in analytics.</p> <i
class="fas fa-database text-emerald-400 text-4xl mb-4"
></i>
<h3 class="font-semibold text-xl mb-2">SQLite</h3>
<p class="text-zinc-400 text-sm">
Zero configuration.<br />
WAL mode enabled.
</p>
</div>
<!-- REST API -->
<div
class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800"
>
<i
class="fas fa-code text-emerald-400 text-4xl mb-4"
></i>
<h3 class="font-semibold text-xl mb-2">REST API</h3>
<p class="text-zinc-400 text-sm">
Full automation.<br />
JSON everywhere.
</p>
</div>
<!-- Self Hosted -->
<div
class="p-8 text-center border-b lg:border-b-0 lg:border-r border-zinc-800"
>
<i
class="fas fa-server text-emerald-400 text-4xl mb-4"
></i>
<h3 class="font-semibold text-xl mb-2">Self Hosted</h3>
<p class="text-zinc-400 text-sm">
Your links.<br />
Your infrastructure.
</p>
</div>
<!-- MIT -->
<div class="p-8 text-center">
<i
class="fas fa-shield-alt text-emerald-400 text-4xl mb-4"
></i>
<h3 class="font-semibold text-xl mb-2">MIT License</h3>
<p class="text-zinc-400 text-sm">
Open source.<br />
Commercial friendly.
</p>
</div>
</div> </div>
<div
<div class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"> class="bg-black border border-zinc-800 rounded-3xl overflow-hidden"
<div class="text-4xl mb-6">🛠️</div> >
<h3 class="text-2xl font-semibold mb-3">CLI First</h3> <div
<p class="text-zinc-400">backup, restore, doctor, stats, validate, create-admin — everything from terminal.</p> class="flex items-center justify-between px-5 py-3 border-b border-zinc-800"
</div> >
<span class="text-zinc-500 text-sm">
<div class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"> Linux Installation
<div class="text-4xl mb-6">🔑</div> </span>
<h3 class="text-2xl font-semibold mb-3">Powerful Features</h3> <button
<p class="text-zinc-400">Password protection • Expiry • Access limits • Tags • REST API • Bulk QR export</p>
</div>
</div>
</div>
</section>
<!-- Install -->
<section class="py-20 bg-zinc-950 border-t border-zinc-800 border-b border-zinc-800">
<div class="max-w-4xl mx-auto px-6 text-center">
<h2 class="text-4xl font-bold mb-4">
Install BZOD
</h2>
<p class="text-zinc-400 mb-10">
Deploy on any Debian/Ubuntu VPS, homelab, mini-PC, or Raspberry Pi.
</p>
<div class="bg-black border border-zinc-800 rounded-3xl overflow-hidden">
<div class="flex items-center justify-between px-5 py-3 border-b border-zinc-800">
<span class="text-zinc-500 text-sm">
Linux Installation
</span>
<button
onclick="copyInstallCommand()" onclick="copyInstallCommand()"
class="text-sm bg-violet-600 hover:bg-violet-700 px-4 py-2 rounded-lg transition"> class="text-sm bg-violet-600 hover:bg-violet-700 px-4 py-2 rounded-lg transition"
Copy >
</button> Copy
</button>
</div>
<pre
class="text-left overflow-x-auto p-6 text-emerald-400 font-mono text-sm"
><code id="install-command">curl -fsSL https://bzo.in/deploy.sh | sudo bash</code></pre>
</div>
</div>
</section>
<!-- Features -->
<section class="py-20 bg-zinc-900">
<div class="max-w-5xl mx-auto px-6">
<h2 class="text-4xl font-bold text-center mb-16">
Why people love BZOD
</h2>
<div class="grid md:grid-cols-3 gap-8">
<div
class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"
>
<div class="text-4xl mb-6">⚡</div>
<h3 class="text-2xl font-semibold mb-3">
Lightning Fast
</h3>
<p class="text-zinc-400">
~18 MB single Rust binary. Starts instantly. Uses
SQLite with WAL mode. Minimal resource usage.
</p>
</div>
<div
class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"
>
<div class="text-4xl mb-6">🔒</div>
<h3 class="text-2xl font-semibold mb-3">
Private by Design
</h3>
<p class="text-zinc-400">
No telemetry. No third-party services. Everything
runs on your server. Strong password hashing & audit
logs.
</p>
</div>
<div
class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"
>
<div class="text-4xl mb-6">🎨</div>
<h3 class="text-2xl font-semibold mb-3">
Beautiful Links
</h3>
<p class="text-zinc-400">
Rich custom landing pages with title, description,
OG metadata, and branded preview.
</p>
</div>
</div> </div>
<pre class="text-left overflow-x-auto p-6 text-emerald-400 font-mono text-sm"><code id="install-command">curl -fsSL https://bzo.in/deploy.sh | sudo bash</code></pre> <div class="grid md:grid-cols-3 gap-8 mt-8">
<div
class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"
>
<div class="text-4xl mb-6">📱</div>
<h3 class="text-2xl font-semibold mb-3">
QR Codes Built-in
</h3>
<p class="text-zinc-400">
Generate PNG & SVG QR codes. Track scans separately
in analytics.
</p>
</div>
<div
class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"
>
<div class="text-4xl mb-6">🛠️</div>
<h3 class="text-2xl font-semibold mb-3">CLI First</h3>
<p class="text-zinc-400">
backup, restore, doctor, stats, validate,
create-admin — everything from terminal.
</p>
</div>
<div
class="bg-zinc-950 border border-zinc-800 rounded-3xl p-8"
>
<div class="text-4xl mb-6">🔑</div>
<h3 class="text-2xl font-semibold mb-3">
Powerful Features
</h3>
<p class="text-zinc-400">
Password protection • Expiry • Access limits • Tags
• REST API • Bulk QR export
</p>
</div>
</div>
</div> </div>
</section>
<p class="text-zinc-500 text-sm mt-4"> <!-- Install -->
Downloads the latest release and installs BZOD as a systemd service. <section
</p> class="py-20 bg-zinc-950 border-t border-zinc-800 border-b border-zinc-800"
</div> >
</section> <div class="max-w-4xl mx-auto px-6 text-center">
<h2 class="text-4xl font-bold mb-4">Install BZOD</h2>
<script> <p class="text-zinc-400 mb-10">
function copyInstallCommand() { Deploy on any Debian/Ubuntu VPS, homelab, mini-PC, or
const text = Raspberry Pi.
"curl -fsSL https://bzo.in/deploy.sh | sudo bash"; </p>
navigator.clipboard.writeText(text); <p class="text-zinc-500 text-sm mt-4">
Downloads the latest release and installs BZOD as a systemd
const btn = event.target; service.
const old = btn.innerText; </p>
btn.innerText = "Copied!";
setTimeout(() => {
btn.innerText = old;
}, 2000);
}
</script>
<!-- CTA -->
<section class="py-20 bg-black border-t border-zinc-800">
<div class="max-w-2xl mx-auto text-center px-6">
<h2 class="text-4xl font-bold mb-6">Ready to own your short links?</h2>
<p class="text-zinc-400 mb-10">Self-host BZOD in under 5 minutes on any VPS, homelab, or even a Raspberry Pi.</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a href="https://github.com/thakares/nx9-url-shortener"
target="_blank"
class="bg-white text-black px-10 py-4 rounded-2xl font-semibold text-lg">
Get BZOD Now
</a>
<a href="/admin"
class="border border-zinc-700 hover:bg-zinc-900 px-10 py-4 rounded-2xl font-semibold text-lg transition">
Open Dashboard
</a>
</div> </div>
</div> </section>
</section>
<footer class="bg-zinc-950 py-12 border-t border-zinc-800"> <script>
<div class="max-w-5xl mx-auto px-6 text-center text-zinc-500 text-sm"> function copyInstallCommand() {
© 2026 BZOD • Made with ❤️ in Rust by Sunil Purushottam Thakare • Running on <span class="font-mono">bzo.in</span> const text = "curl -fsSL https://bzo.in/deploy.sh | sudo bash";
</div>
</footer> navigator.clipboard.writeText(text);
</body>
const btn = event.target;
const old = btn.innerText;
btn.innerText = "Copied!";
setTimeout(() => {
btn.innerText = old;
}, 2000);
}
</script>
<!-- CTA -->
<section class="py-20 bg-black border-t border-zinc-800">
<div class="max-w-2xl mx-auto text-center px-6">
<h2 class="text-4xl font-bold mb-6">
Ready to own your short links?
</h2>
<p class="text-zinc-400 mb-10">
Self-host BZOD in under 5 minutes on any VPS, homelab, or
even a Raspberry Pi.
</p>
<div class="flex flex-col sm:flex-row gap-4 justify-center">
<a
href="https://github.com/thakares/nx9-url-shortener"
target="_blank"
class="bg-white text-black px-10 py-4 rounded-2xl font-semibold text-lg"
>
Get BZOD Now
</a>
<a
href="/admin"
class="border border-zinc-700 hover:bg-zinc-900 px-10 py-4 rounded-2xl font-semibold text-lg transition"
>
Open Dashboard
</a>
</div>
</div>
</section>
<footer class="bg-zinc-950 py-12 border-t border-zinc-800">
<div
class="max-w-5xl mx-auto px-6 text-center text-zinc-500 text-sm"
>
© 2026 BZOD • Made with ❤️ in Rust by Sunil Purushottam Thakare
• Running on <span class="font-mono">bzo.in</span>
</div>
</footer>
</body>
</html> </html>