DreamCheck ডেভেলপার API
আপনার অ্যাপ, ওয়েবসাইট, POS বা অর্ডার ম্যানেজমেন্ট সফটওয়্যারে বাংলাদেশি কাস্টমারের কুরিয়ার ডেলিভারি হিস্ট্রি আর ঝুঁকি যুক্ত করুন। JSON-ভিত্তিক সহজ REST API, এক key দিয়ে সব কুরিয়ার।
https://www.check.dreamlanceit.com/api/v1- ১. ফ্রি অ্যাকাউন্ট খুলুন।
- ২. API পেজ থেকে একটা টেস্ট key বানান — ফ্রি, নমুনা ডেটা দেয়, কোনো লিমিট কাটে না।
- ৩. অ্যাপ তৈরি হলে API আছে এমন প্ল্যান নিয়ে লাইভ key ব্যবহার করুন — কোড একই থাকবে, শুধু key বদলাবে।
Postman / Insomnia: Import → Link-এ https://www.check.dreamlanceit.com/api/v1/openapi.json দিন। OpenAPI Generator দিয়ে যেকোনো ভাষায় ক্লায়েন্ট লাইব্রেরি বানাতে পারবেন।
অথেন্টিকেশন
প্রতিটা রিকোয়েস্টে API key পাঠান — দুইভাবে যেকোনো একটা:
Authorization: Bearer dc_live_xxxxxxxxxxxxxxxx X-Api-Key: dc_live_xxxxxxxxxxxxxxxx
dc_live_…আসল ডেটা, দৈনিক লিমিট থেকে কাটেdc_test_…নমুনা ডেটা, ফ্রি, কিছু সেভ হয় না
প্রতিটা রেসপন্সে X-DreamCheck-Mode হেডার থাকে।
check— নম্বর চেক (check, bulk-check)report— ফ্রড রিপোর্ট পাঠানোdeliveries— ডেলিভারি ফলাফল পাঠানো
টেস্ট মোড
টেস্ট key দিয়ে /check ও /bulk-check আসল ফরম্যাটেই নমুনা রেজাল্ট দেয় — নম্বরের শেষ অঙ্ক অনুযায়ী ঝুঁকি ঠিক হয়, তাই সব অবস্থা সহজে পরীক্ষা করতে পারবেন। /reports ও /deliveries ভ্যালিডেশন চালায় কিন্তু কিছু সেভ করে না।
| শেষ অঙ্ক | risk.level | উদাহরণ নম্বর |
|---|---|---|
| 0, 1, 2 | low | 01700000000 |
| 3, 4 | medium | 01700000003 |
| 5, 6 | high | 01700000005 |
| 7, 8 | very_high | 01700000007 |
| 9 | new | 01700000009 |
লিমিট
- দৈনিক চেক লিমিট: আপনার প্ল্যান অনুযায়ী (ওয়েব, প্লাগইন, API মিলিয়ে)।
/me-তেremaining_todayদেখুন; প্রতিটা চেকের রেসপন্সেও থাকে। বাংলাদেশ সময় রাত ১২টায় রিসেট হয়। - রেট লিমিট: প্রতি অ্যাকাউন্টে মিনিটে ৬০টি রিকোয়েস্ট;
/bulk-checkমিনিটে ১০টি। রেসপন্সেX-RateLimit-LimitওX-RateLimit-Remainingহেডার থাকে; সীমা পেরোলে429ওRetry-After। - ক্যাশ: একই নম্বরের কুরিয়ার ডেটা কয়েক ঘণ্টা ক্যাশে থাকে — তবুও প্রতিটা চেক লিমিট থেকে কাটে। নিজের দিকে ফলাফল সংরক্ষণ করে রাখুন।
এরর
সব এরর একই ফরম্যাটে আসে। কোড দেখে সিদ্ধান্ত নিন, message দেখে নয় (message বাংলায়, বদলাতে পারে)।
{
"status": false,
"message": "এই key-তে এই কাজের অনুমতি (scope) নেই।",
"error": {
"code": "scope_missing",
"required_scope": "report"
}
}
| HTTP | error.code | অর্থ |
|---|---|---|
| 401 | invalid_api_key | API key নেই, ভুল অথবা বাতিল করা। |
| 403 | plan_required | লাইভ API ব্যবহারের জন্য API অ্যাক্সেস আছে এমন প্ল্যান লাগবে। টেস্ট key দিয়ে বিনামূল্যে পরীক্ষা করা যায়। |
| 403 | scope_missing | এই key-তে এই কাজের অনুমতি (scope) নেই। |
| 403 | bulk_not_in_plan | আপনার প্ল্যানে বাল্ক চেক নেই। |
| 403 | account_disabled | অ্যাকাউন্ট সাময়িকভাবে বন্ধ। |
| 422 | invalid_phone | সঠিক বাংলাদেশি মোবাইল নম্বর দিন (01XXXXXXXXX)। |
| 422 | validation_error | রিকোয়েস্টের তথ্য সঠিক নয়। |
| 429 | daily_limit_reached | আজকের চেক লিমিট শেষ। |
| 429 | rate_limited | অনেক বেশি রিকোয়েস্ট। একটু পরে আবার চেষ্টা করুন। |
| 404 | not_found | এই এন্ডপয়েন্ট নেই। |
| 405 | method_not_allowed | এই মেথড সমর্থিত নয়। |
| 500 | server_error | সার্ভারে সমস্যা হয়েছে। |
কোড উদাহরণ
একটা নম্বর চেক করে ঝুঁকি অনুযায়ী সিদ্ধান্ত:
curl -H "Authorization: Bearer $DREAMCHECK_KEY" \
"https://www.check.dreamlanceit.com/api/v1/check?phone=01712345678"
<?php
$ch = curl_init('https://www.check.dreamlanceit.com/api/v1/check?phone=' . urlencode($phone));
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('DREAMCHECK_KEY'), 'Accept: application/json'],
]);
$res = json_decode(curl_exec($ch), true);
if (! $res['status']) {
// $res['error']['code'] দেখে হ্যান্ডেল করুন (daily_limit_reached, invalid_phone ...)
throw new Exception($res['message']);
}
$risk = $res['data']['risk']['level']; // new | low | medium | high | very_high
if (in_array($risk, ['high', 'very_high'])) {
// অগ্রিম ডেলিভারি চার্জ চান / অর্ডার হোল্ড করুন
}
use Illuminate\Support\Facades\Http;
$res = Http::withToken(config('services.dreamcheck.key'))
->acceptJson()
->get('https://www.check.dreamlanceit.com/api/v1/check', ['phone' => $order->phone]);
if ($res->failed()) {
logger()->warning('DreamCheck', $res->json('error'));
return;
}
$order->update([
'risk_level' => $res->json('data.risk.level'),
'success_ratio' => $res->json('data.summary.success_ratio'),
]);
// Node.js 18+ (সার্ভারে চালান — key ব্রাউজারে রাখবেন না)
const res = await fetch(
'https://www.check.dreamlanceit.com/api/v1/check?phone=' + encodeURIComponent(phone),
{ headers: { Authorization: `Bearer ${process.env.DREAMCHECK_KEY}` } }
);
const body = await res.json();
if (!body.status) throw new Error(`${body.error.code}: ${body.message}`);
const { level, label, advice } = body.data.risk;
console.log(level, body.data.summary.success_ratio, advice);
import os, requests
r = requests.get(
"https://www.check.dreamlanceit.com/api/v1/check",
params={"phone": phone},
headers={"Authorization": f"Bearer {os.environ['DREAMCHECK_KEY']}"},
timeout=30,
)
body = r.json()
if not body["status"]:
raise RuntimeError(body["error"]["code"])
risk = body["data"]["risk"]["level"]
ratio = body["data"]["summary"]["success_ratio"]
Webhooks
API পেজ থেকে একটা https URL যোগ করুন, কোন ইভেন্ট চান বেছে নিন। ইভেন্ট ঘটলে আমরা সেই URL-এ JSON POST করব।
| ইভেন্ট | কখন | data |
|---|---|---|
| phone.reported | আপনি আগে চেক করেছেন এমন নম্বর অন্য সেলার রিপোর্ট করলে | phone, reason, reason_label, reported_at, your_last_check_at |
| bulk.completed | ব্যাকগ্রাউন্ড বাল্ক চেক শেষ হলে | id, status, mode, total, processed, invalid, results |
| plan.expiring | প্ল্যানের মেয়াদ ৩ দিনের মধ্যে শেষ হলে | plan, ends_at, renew_url |
| webhook.test | "টেস্ট পাঠান" বাটন চাপলে | message |
{
"id": "e3c9c1b0-0e1d-4d7e-8a31-5d2f7a9b1c44",
"event": "phone.reported",
"created_at": "2026-09-30T11:00:00+06:00",
"livemode": true,
"data": {
"phone": "01712345678",
"reason": "fake_order",
"reason_label": "ভুয়া অর্ডার",
"reported_at": "2026-09-30T11:00:00+06:00",
"your_last_check_at": "2026-09-29T18:20:00+06:00"
}
}Content-Type: application/json X-DreamCheck-Event: phone.reported X-DreamCheck-Delivery: e3c9c1b0-0e1d-4d7e-8a31-5d2f7a9b1c44 X-DreamCheck-Signature: t=1790000000,v1=5f1c…
সিগনেচার যাচাই (অবশ্যই করবেন)
v1 = HMAC-SHA256(signing secret, t + "." + raw body)। মিলিয়ে দেখুন, আর t ৫ মিনিটের বেশি পুরনো হলে বাতিল করুন। একই X-DreamCheck-Delivery দুবার এলে একবারই প্রসেস করুন (retry হতে পারে)। ১০ সেকেন্ডের মধ্যে যেকোনো 2xx উত্তর দিন; ভারী কাজ পরে করুন। ব্যর্থ হলে ১মি, ৫মি, ১৫মি, ১ঘ, ৬ঘ পরে আবার পাঠানো হয়; পরপর 20বার ব্যর্থ হলে endpoint বন্ধ হয়ে যায়।
<?php
$secret = getenv('DREAMCHECK_WEBHOOK_SECRET');
$body = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_DREAMCHECK_SIGNATURE'] ?? ''), $sig);
$expected = hash_hmac('sha256', $sig['t'] . '.' . $body, $secret);
if (! hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) $sig['t']) > 300) {
http_response_code(400);
exit;
}
$event = json_decode($body, true);
if ($event['event'] === 'phone.reported') {
// $event['data']['phone'] — এই কাস্টমারের পেন্ডিং অর্ডার হোল্ড করুন
}
http_response_code(200);
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.post('/dreamcheck/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const sig = Object.fromEntries((req.get('X-DreamCheck-Signature') || '').split(',').map(p => p.split('=')));
const expected = crypto.createHmac('sha256', process.env.DREAMCHECK_WEBHOOK_SECRET)
.update(sig.t + '.' + req.body).digest('hex');
const ok = sig.v1 && expected.length === sig.v1.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig.v1)) &&
Math.abs(Date.now() / 1000 - Number(sig.t)) < 300;
if (!ok) return res.sendStatus(400);
const event = JSON.parse(req.body);
console.log(event.event, event.data);
res.sendStatus(200);
});
import hmac, hashlib, os, time
from flask import Flask, request, abort
app = Flask(__name__)
@app.post('/dreamcheck/webhook')
def webhook():
body = request.get_data()
sig = dict(p.split('=', 1) for p in request.headers.get('X-DreamCheck-Signature', '').split(','))
expected = hmac.new(os.environ['DREAMCHECK_WEBHOOK_SECRET'].encode(),
sig.get('t', '').encode() + b'.' + body, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, sig.get('v1', '')) or abs(time.time() - int(sig.get('t', 0))) > 300:
abort(400)
event = request.get_json()
return '', 200
/api/v1/me
scope: —
Key, plan and remaining quota
সংযোগ পরীক্ষার জন্য ব্যবহার করুন — কোনো চেক খরচ হয় না।
{
"status": true,
"data": {
"name": "Demo Shop BD",
"email": "shop@example.com",
"plan": "Business",
"plan_ends_at": "2026-10-30T00:00:00+06:00",
"daily_limit": 500,
"remaining_today": 482,
"features": {
"api": true,
"bulk": true
},
"key": {
"name": "My app",
"mode": "live",
"scopes": [
"check",
"report",
"deliveries"
]
},
"app_url": "https://www.check.dreamlanceit.com/app"
}
}
এরর: 401, 403, 429 — এরর কোড দেখুন
/api/v1/check
scope: check
Check one phone number
নম্বরের সব কুরিয়ারের হিস্ট্রি, সফলতার হার, ঝুঁকি। প্রতি কলে দৈনিক লিমিট থেকে ১টি কাটে (লাইভ key)। যেকোনো ফরম্যাট চলে: 01…, +8801…, 8801…
| প্যারামিটার | কোথায় | টাইপ | আবশ্যক |
|---|---|---|---|
| phone | query | string | হ্যাঁ |
{
"status": true,
"data": {
"phone": "01712345678",
"summary": {
"total": 20,
"delivered": 14,
"cancelled": 6,
"success_ratio": 70,
"reports": 0,
"courier_reports": 0,
"couriers_with_data": 4
},
"risk": {
"level": "medium",
"label": "সতর্কতা",
"advice": "পাঠানোর আগে কল করে কনফার্ম করুন",
"color": "amber"
},
"couriers": {
"steadfast": {
"courier": "steadfast",
"status": "ok",
"total": 10,
"delivered": 7,
"cancelled": 3,
"success_ratio": 70,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "steadfast",
"source_label": "Steadfast",
"also_from": []
},
"pathao": {
"courier": "pathao",
"status": "ok",
"total": 6,
"delivered": 4,
"cancelled": 2,
"success_ratio": 66.7000000000000028421709430404007434844970703125,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "pathao",
"source_label": "Pathao",
"also_from": []
},
"redx": {
"courier": "redx",
"status": "ok",
"total": 4,
"delivered": 3,
"cancelled": 1,
"success_ratio": 75,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "fraudbd",
"source_label": "FraudBD",
"also_from": []
},
"paperfly": {
"courier": "paperfly",
"status": "ok",
"total": 0,
"delivered": 0,
"cancelled": 0,
"success_ratio": null,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "fraudbd",
"source_label": "FraudBD",
"also_from": []
},
"carrybee": {
"courier": "carrybee",
"status": "not_configured",
"total": null,
"delivered": null,
"cancelled": null,
"success_ratio": null,
"rating": null,
"fraud_reports": 0,
"message": "কোনো ডেটা সোর্স যুক্ত নেই",
"cached": false,
"source": null,
"source_label": null,
"also_from": []
}
},
"sources": {
"steadfast": {
"label": "Steadfast",
"status": "ok",
"message": null,
"cached": false
}
},
"community": {
"delivered": 0,
"returned": 0,
"sellers": 0
},
"checked_at": "2026-09-30T10:15:00+06:00"
},
"remaining_today": 481,
"mode": "live"
}
এরর: 401, 403, 422, 429 — এরর কোড দেখুন
/api/v1/check
scope: check
Check one phone number (JSON body)
GET-এর মতোই, শুধু নম্বর JSON body-তে।
{
"phone": "01712345678"
}
{
"status": true,
"data": {
"phone": "01712345678",
"summary": {
"total": 20,
"delivered": 14,
"cancelled": 6,
"success_ratio": 70,
"reports": 0,
"courier_reports": 0,
"couriers_with_data": 4
},
"risk": {
"level": "medium",
"label": "সতর্কতা",
"advice": "পাঠানোর আগে কল করে কনফার্ম করুন",
"color": "amber"
},
"couriers": {
"steadfast": {
"courier": "steadfast",
"status": "ok",
"total": 10,
"delivered": 7,
"cancelled": 3,
"success_ratio": 70,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "steadfast",
"source_label": "Steadfast",
"also_from": []
},
"pathao": {
"courier": "pathao",
"status": "ok",
"total": 6,
"delivered": 4,
"cancelled": 2,
"success_ratio": 66.7000000000000028421709430404007434844970703125,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "pathao",
"source_label": "Pathao",
"also_from": []
},
"redx": {
"courier": "redx",
"status": "ok",
"total": 4,
"delivered": 3,
"cancelled": 1,
"success_ratio": 75,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "fraudbd",
"source_label": "FraudBD",
"also_from": []
},
"paperfly": {
"courier": "paperfly",
"status": "ok",
"total": 0,
"delivered": 0,
"cancelled": 0,
"success_ratio": null,
"rating": null,
"fraud_reports": 0,
"message": null,
"cached": false,
"source": "fraudbd",
"source_label": "FraudBD",
"also_from": []
},
"carrybee": {
"courier": "carrybee",
"status": "not_configured",
"total": null,
"delivered": null,
"cancelled": null,
"success_ratio": null,
"rating": null,
"fraud_reports": 0,
"message": "কোনো ডেটা সোর্স যুক্ত নেই",
"cached": false,
"source": null,
"source_label": null,
"also_from": []
}
},
"sources": {
"steadfast": {
"label": "Steadfast",
"status": "ok",
"message": null,
"cached": false
}
},
"community": {
"delivered": 0,
"returned": 0,
"sellers": 0
},
"checked_at": "2026-09-30T10:15:00+06:00"
},
"remaining_today": 481,
"mode": "live"
}
এরর: 401, 403, 422, 429 — এরর কোড দেখুন
/api/v1/bulk-check
scope: check
Check up to 25 numbers
একসাথে অনেক নম্বর। প্রতিটা সঠিক নম্বরের জন্য ১টি চেক কাটে; ভুল নম্বর `invalid`-এ ফেরত আসে। প্ল্যানে বাল্ক অ্যাক্সেস লাগে। রেট লিমিট: মিনিটে ১০টি রিকোয়েস্ট।
{
"phones": [
"01712345678",
"+8801812345670",
"abc"
]
}
{
"status": true,
"data": {
"01712345678": {
"risk": "medium",
"risk_label": "সতর্কতা",
"success_ratio": 70,
"total": 20,
"delivered": 14,
"cancelled": 6,
"reports": 0,
"couriers": {
"steadfast": {
"total": 10,
"delivered": 7,
"cancelled": 3,
"rating": null,
"source": "steadfast"
}
}
}
},
"invalid": [
"abc"
],
"remaining_today": 480,
"mode": "live"
}
এরর: 401, 403, 422, 429 — এরর কোড দেখুন
/api/v1/bulk-jobs
scope: check
Start a background bulk check (up to 200 numbers)
বড় তালিকার জন্য। সাথে সাথে `202` ও job id ফেরত আসে; চেক ব্যাকগ্রাউন্ডে চলে। ফলাফল পেতে `GET /bulk-jobs/{id}` পোল করুন অথবা `bulk.completed` webhook নিন। টেস্ট key-তে সাথে সাথে শেষ হয়।
{
"phones": [
"01712345678",
"01812345670",
"01912345675"
]
}
{
"status": true,
"data": {
"id": "9b2f6c1e-4d7a-4a57-9a51-2f1f0f3c8e21",
"status": "queued",
"mode": "live",
"total": 3,
"processed": 0,
"invalid": [],
"created_at": "2026-09-30T10:15:00+06:00",
"url": "https://www.check.dreamlanceit.com/api/v1/bulk-jobs/9b2f6c1e-4d7a-4a57-9a51-2f1f0f3c8e21"
}
}
এরর: 401, 403, 422, 429 — এরর কোড দেখুন
/api/v1/bulk-jobs/{id}
scope: check
Bulk job status and results
`status`: queued → running → done (বা failed)। `processed`/`total` দিয়ে অগ্রগতি দেখান। লিমিট শেষ হয়ে গেলে বাকি নম্বরে `skipped: daily_limit_reached` থাকে।
| প্যারামিটার | কোথায় | টাইপ | আবশ্যক |
|---|---|---|---|
| id | path | string | হ্যাঁ |
{
"status": true,
"data": {
"id": "9b2f6c1e-4d7a-4a57-9a51-2f1f0f3c8e21",
"status": "done",
"mode": "live",
"total": 3,
"processed": 3,
"invalid": [],
"created_at": "2026-09-30T10:15:00+06:00",
"finished_at": "2026-09-30T10:15:09+06:00",
"results": {
"01712345678": {
"risk": "low",
"risk_label": "নিরাপদ",
"advice": "নিশ্চিন্তে পার্সেল পাঠাতে পারেন",
"success_ratio": 92.5,
"total": 40,
"delivered": 37,
"cancelled": 3,
"reports": 0,
"couriers": {
"steadfast": {
"total": 25,
"delivered": 23,
"cancelled": 2,
"rating": null,
"source": "steadfast"
}
}
}
}
}
}
এরর: 401, 403, 404 — এরর কোড দেখুন
/api/v1/reports
scope: report
Report a fraudulent number
একই নম্বর আবার রিপোর্ট করলে আগের রিপোর্ট আপডেট হয়। মিথ্যা রিপোর্ট করলে অ্যাকাউন্ট বন্ধ হতে পারে।
{
"phone": "01712345678",
"reason": "fake_order",
"note": "৩ বার অর্ডার করে রিসিভ করেনি"
}
{
"status": true,
"message": "Reported",
"mode": "live"
}
এরর: 401, 403, 422, 429 — এরর কোড দেখুন
/api/v1/deliveries
scope: deliveries
Send delivery outcomes (max 200)
আপনার অর্ডারের ডেলিভারি ফলাফল নেটওয়ার্কে পাঠান — সবার চেক আরও নির্ভুল হয়। `order_ref` দিয়ে idempotent: একই রেফারেন্স আবার পাঠালে আপডেট হয়, ডুপ্লিকেট হয় না। নাম-ঠিকানা পাঠাবেন না।
{
"records": [
{
"phone": "01712345678",
"order_ref": "shop.com#1001",
"outcome": "delivered",
"courier": "steadfast",
"amount": 1250
}
]
}
{
"status": true,
"saved": 1,
"skipped": [],
"mode": "live"
}
এরর: 401, 403, 422, 429 — এরর কোড দেখুন
ভার্সনিং ও সাপোর্ট
সব এন্ডপয়েন্ট /api/v1-এর অধীনে। v1-এ শুধু নতুন ফিল্ড যোগ হবে — কোনো ফিল্ড সরানো বা নাম বদলানো হবে না; বড় পরিবর্তন এলে /api/v2 আসবে। তাই অপরিচিত নতুন ফিল্ড উপেক্ষা করার মতো করে কোড লিখুন।