REST API • Laravel Sanctum Bearer Token • JSON Responses

Integration API Documentation

Integrate your booking system directly with the Visit Rawdah external integration platform. Manage live slot availability checks, balance inquiries, instant appointment reservations, and secure ticket QR outputs via a unified RESTful API.

API Base URL
https://visitrawdah.com/api/v1
Production & Sandbox (Test Mode) Supported
Format: application/json
Encoding: UTF-8
Auth Header: Authorization: Bearer <token>
🔐

Authentication

All protected API requests require a valid Bearer Token. To obtain a token, send a request to the /api/v1/login endpoint using your partner or user credentials.

Request Headers:
Authorization: Bearer 1|bzDWhKKu4Xkas7tCOXTe2DV4lZMlYI0Bc2YKtKqR...
Accept: application/json
Content-Type: application/json
💡 Test Mode: When Test Mode is active for your account, reservation purchases are simulated safely: your live provider balance is not deducted, and mock reservation tokens with test QR links are generated.

API Endpoints

Visit Rawdah v1 REST API methods and parameter schemas

9 Endpoints
POST /api/v1/login
Public (No Token Required)

Authenticates with email and password. Returns a Sanctum Bearer token along with current balance and unit price details.

Request Body
{
  "email": "[email protected]",
  "password": "YourStrongPassword123!"
}
Response (200 OK)
{
  "success": true,
  "data": {
    "token": "1|bzDWhKKu4Xkas7tCOXTe2DV4lZM...",
    "user": {
      "id": 14,
      "name": "Partner Tourism",
      "email": "[email protected]",
      "balance": "150.00",
      "ravza_price": "1.50"
    }
  }
}
POST /api/v1/logout
🔒 Bearer Token

Revokes the active Bearer token and safely terminates the session.

Response (200 OK)
{
  "success": true,
  "message": "Session terminated successfully."
}
GET /api/v1/me
🔒 Bearer Token

Returns profile details, current available wallet balance (balance), per-person unit price, role, and whether your account is in test mode.

Response (200 OK)
{
  "success": true,
  "data": {
    "id": 14,
    "name": "Partner Tourism",
    "email": "[email protected]",
    "balance": "145.50",
    "ravza_price": "1.50",
    "role": "user",
    "api_test_mode": false
  }
}
GET /api/v1/available-slots
🔒 Bearer Token

Queries live appointment availability dates, time slots, and real-time capacities. Male (dataMale) and female (dataFemale) capacities are mapped separately.

Sample Response (200 OK)
{
  "success": true,
  "data": {
    "dataMale": {
      "2026-09-25": {
        "14:20": 45,
        "14:40": 30,
        "15:00": 15
      }
    },
    "dataFemale": {
      "2026-09-25": {
        "14:20": 38,
        "14:40": 20
      }
    }
  },
  "meta": {
    "test_mode": false,
    "timezone": "Asia/Riyadh",
    "generated_at": "2026-09-23 11:30:00"
  }
}
POST /api/v1/orders
🔒 Bearer Token

Creates a new reservation order. Each appointment time slot in Rawdah is exclusively designated to either male or female visitors, so only a total count is required. Gender is automatically resolved based on the selected slot. In live mode, balance is automatically checked and deducted. In test mode (test_mode: true), orders are simulated without deducting balance.

Parameters
Parameter Type Required? Description
date string Yes Appointment date (Format: YYYY-MM-DD)
time string Yes Time slot in 24h format (e.g. 14:20 or 02:00)
count integer Yes Number of visitors (minimum: 1). Gender is auto-detected from the slot.
gender string Optional male or female (Auto-resolved if omitted)
group_name string Optional Tracking name for group / tour (max 255 chars)
Sample Request (POST JSON)
{
  "date": "2026-09-25",
  "time": "14:20",
  "count": 2,
  "group_name": "Hilal Group 1"
}
Response (201 Created)
{
  "success": true,
  "message": "Order created successfully.",
  "data": {
    "order": {
      "order_id": 499760,
      "date": "2026-09-25",
      "time": "14:20",
      "gender": "male",
      "piece": 2,
      "unit_price": "1.50",
      "total_price": "3.00",
      "status": "approved",
      "job_status": "done",
      "qr_link": "https://visitrawdah.com/qr/a1b2c3d4-...",
      "pdf_url": "https://visitrawdah.com/api/v1/orders/499760/pdf",
      "qr_endpoint": "https://visitrawdah.com/api/v1/orders/499760/qr",
      "share_token": "a1b2c3d4-..."
    },
    "new_balance": "141.00"
  },
  "meta": {
    "test_mode": false
  }
}
GET /api/v1/orders
🔒 Bearer Token

Lists paginated orders for the authenticated user. Date, status, or group_name filters are supported.

Query Parameters
per_page
Items per page (default: 20, max: 100)
page
Page number (1, 2...)
status
approved, pending, failed...
date
YYYY-MM-DD filter
Sample Request & Response
GET /api/v1/orders?per_page=2&date=2026-09-25

{
  "success": true,
  "data": [
    {
      "order_id": 499760,
      "date": "2026-09-25",
      "time": "14:20",
      "gender": "male",
      "piece": 2,
      "unit_price": "1.50",
      "total_price": "3.00",
      "status": "approved",
      "job_status": "done",
      "qr_link": "https://visitrawdah.com/qr/a1b2c3d4-...",
      "pdf_url": "https://visitrawdah.com/api/v1/orders/499760/pdf",
      "qr_endpoint": "https://visitrawdah.com/api/v1/orders/499760/qr",
      "share_token": "a1b2c3d4-...",
      "group_name": "Hilal Group 1",
      "created_at": "2026-09-23 10:44:14"
    }
  ],
  "pagination": {
    "total": 1,
    "per_page": 2,
    "current_page": 1,
    "last_page": 1
  }
}
GET /api/v1/orders/{order_id}
🔒 Bearer Token

Retrieves details for a specific order including current status, white-labeled QR viewer URL (qr_link), PDF download URL (pdf_url), and raw QR endpoint.

Response (200 OK)
{
  "success": true,
  "data": {
    "order_id": 499760,
    "date": "2026-09-25",
    "time": "14:20",
    "service_id": 20,
    "gender": "male",
    "piece": 2,
    "unit_price": "1.50",
    "total_price": "3.00",
    "status": "approved",
    "job_status": "done",
    "qr_link": "https://visitrawdah.com/qr/a1b2c3d4-...",
    "pdf_url": "https://visitrawdah.com/api/v1/orders/499760/pdf",
    "qr_endpoint": "https://visitrawdah.com/api/v1/orders/499760/qr",
    "share_token": "a1b2c3d4-...",
    "group_name": "Hilal Group 1",
    "created_at": "2026-09-23 10:44:14"
  }
}
GET /api/v1/orders/{order_id}/qr
🔒 Bearer Token

Returns passenger ticket numbers, Nusuk verification statuses, and raw QR code payload strings (qr_code) in JSON format. Use this endpoint to render custom QR codes inside your own mobile or web application.

Response (200 OK)
{
  "success": true,
  "data": {
    "order_id": 499760,
    "date": "2026-09-25",
    "time": "14:20",
    "gender": "male",
    "piece": 2,
    "is_ready": true,
    "ready_count": 2,
    "total_count": 2,
    "qr_view_url": "https://visitrawdah.com/qr/a1b2c3d4-...",
    "pdf_download_url": "https://visitrawdah.com/api/v1/orders/499760/pdf",
    "tickets": [
      {
        "passenger_id": 182740,
        "name": "Ahmet Yilmaz",
        "gender": "male",
        "ticket_number": "81927461",
        "qr_code": "81927461AF20260925...",
        "has_qr": true,
        "nusuk_status": "Completed"
      },
      {
        "passenger_id": 182741,
        "name": "Mehmet Kaya",
        "gender": "male",
        "ticket_number": "81927462",
        "qr_code": "81927462AF20260925...",
        "has_qr": true,
        "nusuk_status": "Completed"
      }
    ]
  },
  "meta": {
    "notice": "All QR codes are ready."
  }
}
GET /api/v1/orders/{order_id}/pdf
🔒 Bearer Token

Streams or downloads the official A4 QR appointment ticket PDF document (application/pdf) directly through our server. Third-party provider links are never exposed to clients.

Inline Preview (Default)
GET /api/v1/orders/{id}/pdf
Opens PDF directly in browser or mobile PDF viewer.
Direct Download
GET /api/v1/orders/{id}/pdf?download=1
Forces browser file download attachment.
⚠️

Error Handling & HTTP Status Codes

All error responses adhere to a consistent standard JSON schema ({"success": false, "message": "...", "errors": {...}}).

HTTP Code Status Common Reason
401 Unauthenticated Bearer token missing, expired, or invalid.
422 Unprocessable Content Validation error, invalid date format, or insufficient wallet balance.
404 Not Found Requested order does not exist or does not belong to your account.
429 Too Many Requests Per-minute rate limit threshold exceeded.
503 Service Unavailable System maintenance mode is active; new orders temporarily paused.
⏱

Rate Limiting

To guarantee platform stability and prevent abuse, standard per-minute quotas are enforced:

POST /login
5 requests
per minute (IP-based)
POST /orders
10 requests
per minute (Account-based)
All Other Endpoints
60 requests
per minute (Account-based)
REST API Önizleme • Laravel Sanctum Bearer Token • JSON

Kişiye Özel Randevu API Dokümantasyonu

Acentelerin kişi bilgilerini göndererek kişiye özel randevu grubu oluşturmasını, rezervasyon durumunu izlemesini ve QR kodlarını almasını sağlar. PDF yüklenmez; yalnızca kişi bilgileri JSON olarak gönderilir.

API Base URL
https://visitrawdah.com/api/v1/personal
Format: application/json
Auth Header: Authorization: Bearer <token>
Currency: USD
🧭

Akış

  1. 1 Kişi ekle: pasaport no, vize no ve ülke gönderilir.
  2. 2 Grup oluştur: kişiler, tarih ve saat aralığı seçilir; kişi başı robot ücreti bakiyeden düşer.
  3. 3 Durumu sorgula: rezervasyon alınana kadar kişi bazında durum izlenir.
  4. 4 QR al: rezervasyonu alınan kişilerin QR kodu ve PDF'i indirilir.
🔐

Kimlik Doğrulama

Standart API ile aynı giriş kullanılır: /api/v1/login ile Bearer token alın ve her istekte Authorization başlığıyla gönderin.

Authorization: Bearer 1|bzDWhKKu4Xkas7tCOXTe2DV4lZMlYI0Bc2YKtKqR...
Accept: application/json
Content-Type: application/json
📌

Genel Kurallar

  • Ücret: grup oluşturulurken kişi başı robot ücreti bakiyeden düşer. Bakiye yetersizse hiçbir kayıt gruplanmaz ve ücret alınmaz.
  • İade: rezervasyonu alınamayan kişilerin ücreti yönetici tarafından manuel iade edilir; API üzerinden iade talebi yoktur.
  • PDF dosyası yüklenmez; yalnızca kişi bilgileri JSON olarak gönderilir.
  • Webhook yoktur; durum sorgulanarak (polling) izlenir. 2-5 dakikada bir sorgu yeterlidir.
  • Teknik altyapı hataları gösterilmez; bu durumdaki kişi 'waiting' görünür ve sistem denemeye devam eder.
  • Tarih aralığı en fazla 14 gün olabilir; aralık yalnızca genişletilebilir.

Uç Noktalar

13
GET /api/v1/personal/pricing
🔒 Bearer Token

Kişi başı ücret, bakiye ve Nusuk saat pencerelerini döner.

Response
{
  "success": true,
  "data": {
    "currency": "USD",
    "robot_price": "1.50",
    "balance": "250.00",
    "max_range_days": 14,
    "nusuk_hours": {
      "male":   ["02:00-05:30", "11:00-19:40"],
      "female": ["00:00-01:40", "06:00-10:40", "20:00-23:40"]
    }
  }
}
GET /api/v1/personal/countries
🔒 Bearer Token

Geçerli ülke kodlarını döner (nationality alanı için).

Response
{
  "success": true,
  "data": [
    { "code": "TUR", "name": "Turkey" },
    { "code": "AZE", "name": "Azerbaijan" }
  ]
}
GET /api/v1/personal/availability?date_from=2026-10-07&date_to=2026-10-08&gender=female
🔒 Bearer Token

Seçilen günlerde saat bazında boş/dolu slotları döner. Parametreler: date_from, date_to (en fazla 14 gün), gender (male|female).

Response
{
  "success": true,
  "data": {
    "gender": "female",
    "updated_at": "2026-10-05T04:42:10+03:00",
    "days": [
      {
        "date": "2026-10-07",
        "slots": [
          { "time": "10:20", "status": "free" },
          { "time": "10:40", "status": "full" }
        ]
      }
    ]
  }
}
POST /api/v1/personal/persons
🔒 Bearer Token

Kişi ekler (en fazla 100). Zorunlu: passport_no, visa_no, nationality. İsteğe bağlı: first_name, last_name, phone, gender, birth_date, issue_date, valid_until. Her kişi ayrı değerlendirilir; yanıt 207 olarak kişi bazında sonuç verir.

Request Body
{
  "persons": [
    { "passport_no": "U12345678", "visa_no": "402627115", "nationality": "AZE" },
    { "passport_no": "U87654321", "visa_no": "402627116", "nationality": "AZE",
      "first_name": "Ayse", "last_name": "Yilmaz", "gender": "female" }
  ]
}
Response
{
  "success": true,
  "data": {
    "created": 1,
    "rejected": 1,
    "results": [
      { "index": 0, "status": "created", "id": 9101 },
      { "index": 1, "status": "rejected",
        "error": { "code": "recent_reservation",
                   "message": "Reservation within the last 365 days." } }
    ]
  }
}
GET /api/v1/personal/persons?status=waiting&page=1&per_page=50
🔒 Bearer Token

Kişileri listeler. Filtre: status, page, per_page.

Response
{
  "success": true,
  "data": [
    { "id": 9102, "passport_no": "U87654321", "visa_no": "402627116",
      "nationality": "AZE", "status": "waiting",
      "group_code": "grp_k3x9a1b2cd", "created_at": "2026-10-05T04:44:00+03:00" }
  ]
}
POST /api/v1/personal/groups
🔒 Bearer Token

Gruplanmamış kişileri tarih ve saat aralığıyla gruplar ve ücreti tahsil eder. İşlem bütündür: bir kişi geçersizse hiçbiri gruplanmaz. Alanlar: group_name, person_ids, start_date, end_date (isteğe bağlı), start_hour, end_hour.

Request Body
{
  "group_name": "GRUP-07.10.2026",
  "person_ids": [9101, 9102, 9103],
  "start_date": "2026-10-07",
  "end_date": "2026-10-07",
  "start_hour": 10,
  "end_hour": 11
}
Response
{
  "success": true,
  "data": {
    "group_code": "grp_k3x9a1b2cd",
    "group_name": "GRUP-07.10.2026",
    "person_count": 3,
    "unit_price": "1.50",
    "total_charged": "4.50",
    "new_balance": "245.50"
  }
}
GET /api/v1/personal/groups?status=waiting
🔒 Bearer Token

Grupları en yeniden eskiye listeler. Filtre: status, page, per_page.

Response
{
  "success": true,
  "data": [
    { "group_code": "grp_k3x9a1b2cd", "group_name": "GRUP-07.10.2026",
      "person_count": 3, "booked_count": 1, "status": "partial",
      "window": { "start_date": "2026-10-07", "start_hour": 10,
                  "end_date": "2026-10-07", "end_hour": 11 },
      "created_at": "2026-10-05T04:44:00+03:00" }
  ]
}
GET /api/v1/personal/groups/{code}
🔒 Bearer Token

Grup detayını, aralığını ve kişi bazında durumları döner. Teknik hatalar gösterilmez.

Response
{
  "success": true,
  "data": {
    "group_code": "grp_k3x9a1b2cd",
    "status": "partial",
    "counts": { "total": 3, "booked": 1, "waiting": 1, "blocked": 1, "refunded": 0 },
    "persons": [
      { "id": 9101, "status": "booked",
        "booking": { "date": "2026-10-07", "time": "10:20 - 10:40" },
        "qr_available": true },
      { "id": 9102, "status": "waiting" },
      { "id": 9103, "status": "blocked",
        "message": "Reservation within the last 365 days." }
    ]
  }
}
GET /api/v1/personal/groups/{code}/suggestion
🔒 Bearer Token

Seçilen aralıkta boş slot yokken aralık dışında müsait vakit varsa öneri döner; yoksa data null olur.

Response
{
  "success": true,
  "data": {
    "slots": [ { "date": "2026-10-08", "time": "09:20", "gender": "female" } ],
    "suggested_window": {
      "start_date": "2026-10-07", "start_hour": 10,
      "end_date": "2026-10-08",   "end_hour": 9
    }
  }
}
PATCH /api/v1/personal/groups/{code}/window
🔒 Bearer Token

Tarih ve saat aralığını genişletir (daraltılamaz, ek ücret yoktur). Alanlar: start_date, end_date, start_hour, end_hour.

Request Body
{
  "start_date": "2026-10-07", "start_hour": 10,
  "end_date": "2026-10-08",   "end_hour": 9
}
Response
{
  "success": true,
  "data": { "group_code": "grp_k3x9a1b2cd", "window": { "start_date": "2026-10-07", "start_hour": 10, "end_date": "2026-10-08", "end_hour": 9 } }
}
GET /api/v1/personal/groups/{code}/qr
🔒 Bearer Token

Gruptaki rezervasyonu alınan kişilerin QR kodlarını döner.

Response
{
  "success": true,
  "data": [
    { "person_id": 9101, "date": "2026-10-07", "time": "10:20 - 10:40", "qr": "4500123AF..." }
  ]
}
GET /api/v1/personal/groups/{code}/pdf
🔒 Bearer Token

Gruptaki tüm QR kodlarını tek PDF olarak indirir (application/pdf).

Response
HTTP/1.1 200 OK
Content-Type: application/pdf
GET /api/v1/personal/persons/{id}/qr
🔒 Bearer Token

Tek kişinin QR kodunu döner. QR hazır değilse 409 qr_not_ready döner.

Response
{
  "success": true,
  "data": { "person_id": 9101, "date": "2026-10-07", "time": "10:20 - 10:40", "qr": "4500123AF..." }
}
🏷️

Durum Değerleri

Kişi Durumu
Değer Anlam
pending Eklendi, henüz gruplanmadı.
waiting Gruplandı, rezervasyon bekleniyor.
booked Rezervasyon alındı.
blocked Nusuk kuralı veya geçersiz bilgi nedeniyle alınamadı; iade için destek ile iletişime geçin.
refunded Ücret iade edildi.
Grup Durumu
Değer Anlam
waiting Hiçbir kişi için rezervasyon alınmadı.
partial Bazı kişiler alındı, diğerleri bekliyor veya engelli.
completed Engelli ve iade edilenler dışında herkes alındı.
blocked Tüm kişiler engelli veya iade edilmiş.
⚠️

Hata Kodları

{"success": false, "error": {"code": "...", "message": "...", "details": {}}}

HTTP Kod Neden
401 unauthenticated Token yok veya geçersiz.
402 insufficient_balance Bakiye yetersiz.
403 forbidden Hesabın kişiye özel API'yi kullanma yetkisi yok.
404 not_found Grup veya kişi bulunamadı ya da size ait değil.
409 qr_not_ready QR henüz oluşmadı.
422 validation_error Eksik veya hatalı alan; details alan bazlı mesaj içerir.
422 invalid_persons / duplicate_person / recent_reservation Geçersiz, başkasına ait veya zaten gruplanmış kişi; mükerrer pasaport/vize; 365 gün kuralı.
422 invalid_window / no_waiting_persons Geçmiş tarih, ters aralık, 14 günü aşan veya daraltılan aralık.
429 rate_limited İstek sınırı aşıldı.
⏱

İstek Sınırları

Diğer GET uçları
60
dakikada
Kişi ekleme ve aralık güncelleme
30
dakikada
Grup oluşturma
10
dakikada