🔌 Dovara.Biz

Embed & API Guide  ·  Hướng Dẫn Nhúng & API

Dovara.Biz offers three ways to integrate booking into any external website or app:

TierMethodBest for
Tier 1 iFrame Embed Simple websites — paste one line of HTML
Tier 2 JS Widget Any site — floating "Book Now" button with a modal
Tier 3 REST API Developers — full server-to-server integration
💡 Before using Tier 2 or Tier 3, generate your API Key in Settings → Embed & API.
1 Generate Your API Key
  1. Log in to your Provider Dashboard.
  2. Go to Settings → Embed & API.
  3. Click Generate API Key.
  4. Copy the key and store it securely — it will be masked after you navigate away.
⚠️ Treat your API key like a password. Never expose it in client-side JavaScript. Clicking Regenerate Key immediately invalidates the old key.
2 Embed the Booking Page with an iFrame

Paste this HTML anywhere on your website to show the full booking wizard inline. Replace YOUR_EMBED_TOKEN with your token from Settings → Embed & API. The token identifies your booking page without exposing your internal provider ID.

<iframe
  src="https://dovara.biz/book?token=YOUR_EMBED_TOKEN&embed=1"
  width="100%"
  height="650"
  frameborder="0"
  allow="forms"
  loading="lazy">
</iframe>

Optional URL parameters:

ParameterExamplePurpose
token?token=a3f8c2...Your embed token (from Settings → Embed & API)
lang&lang=viForce a language: en, vi, th, km, lo
embed&embed=1Enables embed mode (no header/footer)
3 Add a Floating "Book Now" Button

Paste one <script> tag anywhere in your page's <body>. A floating button appears — clicking it opens the booking form in a modal overlay.

<script
  src="https://dovara.biz/widget.js"
  data-token="YOUR_EMBED_TOKEN"
  data-lang="en"
  data-color="#0A76D8"
  data-label="Book Now"
  data-position="bottom-right">
</script>

Attributes:

AttributeDefaultDescription
data-tokenRequired. Your embed token from Settings → Embed & API. Does not expose your internal provider ID.
data-langenWidget language: en, vi, th, km, lo
data-color#0A76D8Button background colour (any CSS colour)
data-labelBook NowButton label text
data-positionbottom-rightbottom-right or bottom-left
data-base-urlautoOverride base URL (advanced)
💡 The widget does not require an API key — it simply opens the embed booking page in a modal.
4 Authentication

All API endpoints require your API key. Pass it as an HTTP header (recommended) or as a query parameter:

Option A — Authorization header (recommended)

Authorization: Bearer YOUR_64_CHAR_API_KEY

Option B — Query parameter

GET /api/v1/sessions.php?api_key=YOUR_64_CHAR_API_KEY&date=2026-03-25
⚠️ Never use Option B in client-side code (browser) — it exposes your key in browser history and server logs. Option B is safe only for server-to-server calls.

Rate limits:

EndpointLimit
GET /api/v1/sessions.php60 requests / minute
POST /api/v1/book.php20 requests / minute

Rate limit is per API key per minute window. HTTP 429 is returned when exceeded, with a Retry-After: 60 header.

5 GET List Available Sessions

GET https://dovara.biz/api/v1/sessions.php

Query Parameters:

ParameterRequiredDescription
dateNoDate in YYYY-MM-DD format. Defaults to today.
api_keyAlt.API key (or use Authorization header)

The provider is identified by your API key — no provider ID is required or accepted.

Example request:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://dovara.biz/api/v1/sessions.php?date=2026-03-25"

Success response (200):

{
  "status": "ok",
  "date": "2026-03-25",
  "sessions": [
    {
      "id": 7,
      "time": "09:00",
      "title": "Trang",
      "capacity": 2,
      "booked": 1,
      "available": 1
    },
    {
      "id": 8,
      "time": "09:00",
      "title": "Lan",
      "capacity": 2,
      "booked": 0,
      "available": 2
    }
  ]
}
6 POST Create a Booking

POST https://dovara.biz/api/v1/book.php

Request body (JSON):

FieldRequiredDescription
session_idYesSchedule ID from the sessions endpoint
nameYesClient full name
emailOne ofClient email address
phoneOne ofClient phone number (at least email or phone required)
noteNoOptional note to the provider

Example request:

curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": 7,
    "name": "Nguyen Van A",
    "email": "nvana@example.com",
    "phone": "+84901234567",
    "note": "Please confirm by SMS"
  }' \
  "https://dovara.biz/api/v1/book.php"

Success response (201):

{
  "status": "ok",
  "ref": "BK-1Z",
  "appo_number": 2,
  "appo_id": 55,
  "session_id": 7,
  "session_date": "2026-03-25",
  "session_time": "09:00"
}

Error responses:

HTTPcodeMeaning
401missing_api_keyNo key provided
401invalid_api_keyKey not found or provider not public
404session_not_foundSession doesn't exist for this provider
409session_fullNo capacity remaining
409session_pastSession date is in the past
422validationMissing / invalid fields
429rate_limitedToo many requests
7 JavaScript Quick-Start (Server-Side Node.js)

This example queries available sessions and then books the first available one:

const API_KEY = 'YOUR_64_CHAR_API_KEY';
const BASE    = 'https://dovara.biz';
const HEADERS = { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' };
const TODAY   = new Date().toISOString().slice(0, 10);

async function run() {
    // 1. Get sessions for today (provider derived from API key — no ID needed)
    const res1 = await fetch(`${BASE}/api/v1/sessions.php?date=${TODAY}`, { headers: HEADERS });
    const data1 = await res1.json();
    const session = data1.sessions.find(s => s.available > 0);
    if (!session) { console.log('No available sessions today.'); return; }

    // 2. Book the first available session
    const res2 = await fetch(`${BASE}/api/v1/book.php`, {
        method: 'POST',
        headers: HEADERS,
        body: JSON.stringify({
            session_id: session.id,
            name:       'Nguyen Van A',
            email:      'nvana@example.com',
            phone:      '+84901234567',
        })
    });
    const data2 = await res2.json();
    console.log('Booking confirmed:', data2.ref, '— Appo #', data2.appo_number);
}

run();
💡 Always run API calls from your server, not from a browser script, to keep the API key secret.