تخطَّ إلى المحتوى
دليل الأدوية المصري
تابع آخر تحديثات الأسعار على واتساب

توثيق الـ API v1.0.0

الرابط الأساسي https://api.dwaprice.com/v1 · JSON بترميز UTF-8 وأسماء snake_case · التغييرات غير المتوافقة فقط في /v2

مرجع نقاط النهاية والهياكل أدناه بالإنجليزية (مولَّد من ملف OpenAPI)؛ الأدلة بالعربية.

البداية

  1. جرّب العينة بلا مفتاح: GET https://api.dwaprice.com/v1/sample/drugs?q=augmentin (50 منتجًا ثابتًا بنفس الأشكال، مع "sample": true).
  2. اطلب الوصول؛ بعد التفعيل أنشئ مفتاحك من لوحة المطورين. يظهر المفتاح مرة واحدة.
  3. استدعِ نقاط النهاية الحقيقية بالترويسة Authorization: Bearer dp_live_…. احتفظ بالمفتاح على الخادم؛ لا تضعه في متصفح أو تطبيق هاتف.
أول طلب
curl "https://api.dwaprice.com/v1/drugs/by-barcode/6221051011317" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

المصادقة

كل طلب خارج العينة يحتاج Authorization: Bearer dp_live_…. المفتاح المفقود أو غير الصحيح أو المجهول أو الملغى أو المنتهي يعيد 401 unauthorized (نفس الإجابة دائمًا: لا نكشف السبب). المفتاح الصحيح الذي لا تسمح خطته أو صلاحياته أو قائمة IP بنقطة النهاية يعيد 403 forbidden مع details.required_scope أو details.plan.

المفاتيح: dp_live_ + 40 حرفًا base32 من 25 بايت عشوائي؛ نخزن تجزئة SHA-256 فقط. الصلاحيات: drugs:read وchanges:read وexport وwebhooks. التدوير يبقي المفتاح القديم 24 ساعة؛ الإلغاء فوري.

الترقيم

القوائم تأخذ limit (1–100، الافتراضي 20) وcursor وتعيد page: { limit, has_more, next_cursor }. المؤشر نص موقّع غير مقروء، صالح 24 ساعة ومرتبط بالترتيب والمرشحات (تغيير مرشح يعيد 400 invalid_cursor). القوائم تستخدم مؤشرات keyset تبقى ثابتة مع تغير البيانات؛ نتائج البحث (q) مرتبة بالصلة ومحدودة بـ 1,000. لا تحمل القوائم عددًا إجماليًا؛ /meta فيه أعداد المجموعة.

الصفحة الثانية
GET https://api.dwaprice.com/v1/drugs?dosage_form=syrup&limit=100&cursor=eyJmIjoi…

{ "data": [ … ], "page": { "limit": 100, "has_more": true, "next_cursor": "eyJmIjoi…" },
  "meta": { "dataset_version": "2026-10-21.1", "generated_at": "2026-10-21T14:36:16Z" } }

الأخطاء

شكل واحد لكل إجابة غير 2xx: { "error": { "code", "message", "details" } }. message للمطورين؛ details بنية منظمة (كائن، أو مصفوفة { param, issue } لأخطاء التحقق، أو null).

الأخطاء
400 validation_errorالنوع: details[]كل معامل غير صحيح مع param وissue.
400 invalid_cursorالنوع: —مؤشر منتهٍ أو تالف أو من مرشحات أخرى.
400 since_too_oldالنوع: window_dayssince خارج نافذة خطتك: أعد التحميل من /drugs.
401 unauthorizedالنوع: —مفتاح مفقود أو تالف أو مجهول أو ملغى أو منتهٍ.
403 forbiddenالنوع: plan, required_scope, reasonالخطة أو الصلاحية أو حساب موقوف أو اشتراك منتهٍ.
403 ip_not_allowedالنوع: —قائمة IP لخطة Enterprise.
404 not_foundالنوع: —معرّف أو مسار مجهول.
301 movedالنوع: new_id + Locationالمعرّف قديم؛ اتبع Location.
429 rate_limitedالنوع: retry_afterحد الدقيقة؛ ترويسة Retry-After.
429 quota_exceededالنوع: resets_atالحصة الشهرية؛ Retry-After حتى بداية الشهر.
500 internal_errorالنوع: request_idخطأ من جهتنا؛ اذكر request_id للدعم.
503 unavailableالنوع: —صيانة أو قاعدة بيانات غير متاحة؛ Retry-After.

الحدود

لكل مفتاح: حد في الدقيقة وحصة شهرية (الشهر التقويمي بتوقيت UTC)، كلاهما من خطتك. العينة محدودة لكل شبكة مصدر (30 في الدقيقة، 300 في اليوم). كل استجابة تحمل X-RateLimit-Limit وX-RateLimit-Remaining وX-RateLimit-Reset (ثوانٍ Unix)، وللمفاتيح X-Quota-Limit وX-Quota-Remaining وX-Quota-Reset. عند التجاوز: 429 مع Retry-After. استجابات 304 و4xx تُحسب طلبات؛ 5xx لا تُحسب. أرسل If-None-Match بقيمة ETag التي استلمتها لتحصل على 304 مجانية عندما لا يتغير شيء.

دليل المزامنة الجزئية

التغذية GET /price-changes?since= تعيد أحداثًا تُضاف فقط ومرتبة بـ id: price_changed وadded وstatus_changed وremoved وrenamed. كل حدث يحمل السجل الحالي (drug)، فطلب واحد يكفي لتحديث نسختك.

  • أول مزامنة: حمّل الكتالوج من GET /drugs (كل الصفحات) واحفظ meta.generated_at.
  • كل N دقيقة: GET /price-changes?since=<المحفوظ>؛ تابع الصفحات بـ cursor (يحمل since الأصلي)؛ طبّق كل حدث؛ احفظ latest_detected_at.
  • since شامل والتسليم at-least-once: تجاوز معرّفات الأحداث التي طبّقتها.
  • since أقدم من نافذة خطتك يعيد 400 since_too_old: أعد التحميل كاملًا.
حلقة المزامنة (JavaScript)
let since = stored.latest_detected_at;        // from the previous run
let cursor = null;
do {
  const url = cursor ? `https://api.dwaprice.com/v1/price-changes?cursor=${encodeURIComponent(cursor)}`
                     : `https://api.dwaprice.com/v1/price-changes?since=${since}&limit=100`;
  const page = await (await fetch(url, { headers: { Authorization: "Bearer " + KEY } })).json();
  for (const e of page.data) {
    if (e.id <= stored.last_event_id) continue;       // at-least-once: skip what you applied
    applyEvent(e);                                     // e.type, e.data, e.drug (current record)
    stored.last_event_id = e.id;
  }
  if (page.latest_detected_at) stored.latest_detected_at = page.latest_detected_at;
  cursor = page.page.next_cursor;
} while (cursor);

Drugs

Products, lookups, alternatives and price history.

GET/drugs

List or search drugs

Without q: the catalogue, filtered and sorted (keyset cursor, stable across updates). With q: typo-tolerant search over Arabic and English trade names, approved aliases and spelling variants, active ingredients and barcodes; ranked, at most 1,000 results.

المعاملات

GET /drugs parameters
q (query)Type: stringSearch text, 2–80 characters (Arabic or English; typo-tolerant).كونجستل
company (query)Type: stringCompany id (see `/companies`).sigma
ingredient (query)Type: stringIngredient id (see `/ingredients`); products containing it.paracetamol
atc (query)Type: stringATC code prefix, matched against product-level and ingredient-level codes (`J01` matches `J01CR02`).N02BE
dosage_form (query)Type: DosageFormClass
route (query)Type: RouteClass
prescription_status (query)Type: PrescriptionStatus
status (query)Type: ListingStatusDefault is all statuses.
has_barcode (query)Type: boolean
updated_since (query)Type: string (date-time)Records whose `updated_at` is after this timestamp (any field change). For price changes alone use `/price-changes`.
sort (query)Type: name | price | -price | updated_at | -updated_atIgnored when `q` is given (results are ranked by relevance).default "name"
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 A page of drugs. → DrugList
  • 400 Invalid parameter, cursor or `since`. → Error
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/drugs" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

GET/drugs/{id}

One drug by id

المعاملات

GET /drugs/{id} parameters
id (path)*Type: stringStable public id (the product's URL slug).congestal-20-tabs

الاستجابات

  • 200 The drug. → DrugResponse
  • 301 The id was retired (product renamed in the source list). `Location` points at the current id. → Error
    مثال
    {
      "error": {
        "code": "moved",
        "message": "This id was replaced by congestal-20-tabs",
        "details": {
          "new_id": "congestal-20-tabs"
        }
      }
    }
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 404 Unknown id or path. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/drugs/congestal-20-tabs" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

GET/drugs/by-barcode/{barcode}

Drugs by barcode

Returns a list: in the source price lists 73 barcodes are shared by more than one pack (e.g. two pack sizes of one product). Ordered listed first, then newest price date. An unknown barcode gives an empty list.

المعاملات

GET /drugs/by-barcode/{barcode} parameters
barcode (path)*Type: string6221051011317

الاستجابات

  • 200 Matching drugs (possibly none). → DrugArrayResponse
  • 400 Invalid parameter, cursor or `since`. → Error
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/drugs/by-barcode/6221051011317" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

GET/drugs/{id}/alternatives

Alternatives with the same ingredients

Products with the same active ingredients and the same strength, cheapest first (no price last). strength=any appends products with the same ingredients at another strength.

المعاملات

GET /drugs/{id}/alternatives parameters
id (path)*Type: stringStable public id (the product's URL slug).congestal-20-tabs
strength (query)Type: same | anydefault "same"
limit (query)Type: integerdefault 50
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 Alternatives. → AlternativeList
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 404 Unknown id or path. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/drugs/congestal-20-tabs/alternatives" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

GET/drugs/{id}/price-history

Price history

Oldest first; the last point is the current price. Consecutive identical prices are collapsed.

المعاملات

GET /drugs/{id}/price-history parameters
id (path)*Type: stringStable public id (the product's URL slug).congestal-20-tabs

الاستجابات

  • 200 Price points. → PriceHistoryResponse
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 404 Unknown id or path. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/drugs/congestal-20-tabs/price-history" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

Changes

The delta feed for incremental synchronisation.

GET/price-changes

Delta feed of changes since a time

Append-only events ordered by id: price_changed, added, status_changed, removed, renamed. Each event carries the current record, so one call updates a local copy. Sync loop: store latest_detected_at, call again with it as since, page with cursor, skip event ids already applied (delivery is at-least-once). since older than the plan's feed window → 400 since_too_old (reload with /drugs). Requires scope changes:read.

المعاملات

GET /price-changes parameters
since (query)Type: string (date-time)Events with `detected_at` at or after this timestamp (inclusive; skip event ids already applied). Required unless `cursor` is given — a cursor carries the original `since`.2026-10-21T00:00:00Z
type (query)Type: stringComma-separated event types; default all.price_changed,status_changed
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 A page of events. → PriceChangeList
  • 400 Invalid parameter, cursor or `since`. → Error
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/price-changes" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

Reference

Companies and active ingredients.

GET/companies

Companies

المعاملات

GET /companies parameters
q (query)Type: stringName prefix, case-insensitive.
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 Companies sorted by name. → CompanyList
  • 400 Invalid parameter, cursor or `since`. → Error
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/companies" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

GET/ingredients

Active ingredients

المعاملات

GET /ingredients parameters
q (query)Type: stringArabic or English name prefix.
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 Ingredients sorted by English name. → IngredientList
  • 400 Invalid parameter, cursor or `since`. → Error
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/ingredients" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

Meta

Dataset version and counts.

GET/meta

Dataset version, update time and counts

الاستجابات

  • 200 Dataset metadata. → MetaResponse
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/meta" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

Sample

Free, keyless access to a fixed sample of about 50 drugs. Same shapes as the real endpoints.

GET/sample/drugsبلا مفتاح

List or search the sample drugs

Same parameters as /drugs; results come only from the fixed sample set. Rate limit per IP (30/min, 300/day).

المعاملات

GET /sample/drugs parameters
q (query)Type: stringSearch text, 2–80 characters (Arabic or English; typo-tolerant).كونجستل
company (query)Type: string
ingredient (query)Type: string
atc (query)Type: string
dosage_form (query)Type: DosageFormClass
prescription_status (query)Type: PrescriptionStatus
sort (query)Type: name | price | -price | updated_at | -updated_atdefault "name"
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 A page of sample drugs. → SampleDrugList
  • 400 Invalid parameter, cursor or `since`. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/drugs"

GET/sample/drugs/{id}بلا مفتاح

One sample drug

المعاملات

GET /sample/drugs/{id} parameters
id (path)*Type: stringStable public id (the product's URL slug).congestal-20-tabs

الاستجابات

  • 200 The drug. → SampleDrugResponse
  • 404 Unknown id or path. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/drugs/congestal-20-tabs"

GET/sample/drugs/by-barcode/{barcode}بلا مفتاح

Sample drugs by barcode

المعاملات

GET /sample/drugs/by-barcode/{barcode} parameters
barcode (path)*Type: string

الاستجابات

  • 200 Matching sample drugs (possibly none). → SampleDrugArrayResponse
  • 400 Invalid parameter, cursor or `since`. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/drugs/by-barcode/6221051011317"

GET/sample/drugs/{id}/alternativesبلا مفتاح

Alternatives inside the sample set

المعاملات

GET /sample/drugs/{id}/alternatives parameters
id (path)*Type: stringStable public id (the product's URL slug).congestal-20-tabs
strength (query)Type: same | anydefault "same"

الاستجابات

  • 200 Alternatives that are themselves sample drugs. → SampleAlternativeList
  • 404 Unknown id or path. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/drugs/congestal-20-tabs/alternatives"

GET/sample/drugs/{id}/price-historyبلا مفتاح

Price history of a sample drug

المعاملات

GET /sample/drugs/{id}/price-history parameters
id (path)*Type: stringStable public id (the product's URL slug).congestal-20-tabs

الاستجابات

  • 200 Price points. → SamplePriceHistoryResponse
  • 404 Unknown id or path. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/drugs/congestal-20-tabs/price-history"

GET/sample/price-changesبلا مفتاح

Delta feed restricted to the sample drugs

المعاملات

GET /sample/price-changes parameters
since (query)Type: string (date-time)
type (query)Type: string
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 Events for sample drugs only. → SamplePriceChangeList
  • 400 Invalid parameter, cursor or `since`. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/price-changes"

GET/sample/companiesبلا مفتاح

Companies of the sample drugs

المعاملات

GET /sample/companies parameters
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 Companies. → SampleCompanyList
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/companies"

GET/sample/ingredientsبلا مفتاح

Ingredients of the sample drugs

المعاملات

GET /sample/ingredients parameters
limit (query)Type: integerdefault 20
cursor (query)Type: stringOpaque cursor from `page.next_cursor` of the previous response.

الاستجابات

  • 200 Ingredients. → SampleIngredientList
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/ingredients"

GET/sample/metaبلا مفتاح

Dataset metadata (counts of the sample set)

الاستجابات

  • 200 Metadata. → SampleMetaResponse
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/sample/meta"

Enterprise

Bulk export and webhooks (Enterprise plan).

POST/exports

Request a full dataset export (CSV or JSON)

One export per dataset version is generated and reused. Requires scope export (Enterprise plan).

الاستجابات

  • 202 Export queued (or already ready). → ExportResponse
  • 400 Invalid parameter, cursor or `since`. → Error
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 429 Per-minute limit or monthly quota exceeded; `Retry-After` in seconds. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/exports" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

GET/exports/{id}

Export status and signed download URL

المعاملات

GET /exports/{id} parameters
id (path)*Type: string

الاستجابات

  • 200 Export status; `url` is a signed link valid for one hour once `status` is `ready`. → ExportResponse
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 404 Unknown id or path. → Error
  • 500 Our fault; quote `request_id` to support. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/exports/congestal-20-tabs" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

GET/webhooks

Registered webhooks

الاستجابات

  • 200 Webhooks of the client. → object
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/webhooks" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

POST/webhooks

Register a webhook

Batches of events are POSTed within 10 minutes of each dataset capture, signed with X-Dwaprice-Signature: sha256=<HMAC-SHA256 of the raw body with the secret> and X-Dwaprice-Delivery: <id>. Non-2xx answers are retried with exponential back-off for 24 hours; then the webhook is paused and the admin alerted. Requires scope webhooks.

الاستجابات

  • 201 Created; `secret` is shown only in this response. → object
  • 400 Invalid parameter, cursor or `since`. → Error
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/webhooks" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

DELETE/webhooks/{id}

Delete a webhook

المعاملات

DELETE /webhooks/{id} parameters
id (path)*Type: string

الاستجابات

  • 204 Deleted.
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 404 Unknown id or path. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/webhooks/congestal-20-tabs" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

POST/webhooks/{id}/test

Send a signed test delivery

المعاملات

POST /webhooks/{id}/test parameters
id (path)*Type: string

الاستجابات

  • 200 The receiver's status code and latency. → object
  • 401 Missing, malformed, unknown, revoked or expired key. → Error
  • 403 Key valid, but the plan, scope or IP does not allow this request. → Error
  • 404 Unknown id or path. → Error
  • أجسام الأخطاء: انظر الأخطاء.
curl
curl "https://api.dwaprice.com/v1/webhooks/congestal-20-tabs/test" \
  -H "Authorization: Bearer dp_live_YOUR_KEY"

الهياكل

Error

Error fields
error*Type: object
error.code*Type: validation_error | invalid_cursor | since_too_old | unauthorized | forbidden | ip_not_allowed | not_found | moved | rate_limited | quota_exceeded | internal_error | unavailable
error.message*Type: string
error.details*Type: object | object[] | nullStructured context (object or array) or null.

Page

Page fields
limit*Type: integer
has_more*Type: boolean
next_cursor*Type: string | nullOpaque; pass as `cursor`. Null on the last page.

Meta

Meta fields
dataset_version*Type: string2026-10-21.184
generated_at*Type: string (date-time)

DosageFormClass

إحدى القيم: tablet, capsule, injection, syrup, suspension, drops, sachet, cream, ointment, gel, lotion, solution, spray, powder, inhaler, suppository, other

RouteClass

إحدى القيم: oral, topical, injection, ophthalmic, vaginal, rectal, nasal, inhalation, otic, other

PrescriptionStatus

إحدى القيم: prescription, otc, not_applicable

ListingStatus

The price list's own marker on the line. `listed` = no marker; it is not a stock indication.

إحدى القيم: listed, not_available, not_yet_available, cancelled, illegal_import

EventType

إحدى القيم: price_changed, added, status_changed, removed, renamed

Ingredient

Ingredient fields
id*Type: string | nullparacetamol
name_en*Type: string | nullParacetamol (acetaminophen)
name_ar*Type: string | nullباراسيتامول
strength*Type: string | null650 mg
atc_code*Type: string | nullN02BE01

Price

Price fields
current*Type: number | null50
previous*Type: number | null31
unit_price*Type: number | nullPrice per tablet, capsule, sachet… as listed.2.5
currency*Type: "EGP"
effective_date*Type: string (date) | nullDate of the current price on the price list.
updated_at*Type: string (date-time) | nullWhen the API recorded the current price (sync key). Null only when there is no price.
verified*Type: booleanChecked against a published source.
verified_at*Type: string (date) | null

NamedRef

NamedRef fields
id*Type: stringsigma
name*Type: stringSigma

Category

Category fields
id*Type: stringcold
en*Type: string | nullCold/cough combination (analgesic + antihistamine + decongestant)
ar*Type: string | null

DosageForm

DosageForm fields
class*Type: DosageFormClass
en*Type: string | nullTablet
ar*Type: string | nullقرص

Drug

Drug fields
id*Type: stringStable public id (URL slug).congestal-20-tabs
trade_name_en*Type: stringCongestal 20 tabs
trade_name_ar*Type: string | nullكونجستال 20 قرص
scientific_name*Type: string | nullChlorpheniramine+paracetamol(acetaminophen)+pseudoephedrine
ingredients*Type: Ingredient[]
strength*Type: string | null650/4/60 mg
dosage_form*Type: DosageForm
dosage_form.class*Type: DosageFormClass
dosage_form.en*Type: string | nullTablet
dosage_form.ar*Type: string | nullقرص
route*Type: RouteClass | null
route_text*Type: string | nullOral
units_per_package*Type: integer | null20
packaging*Type: string | null20 tablets (2 blisters of 10)
price*Type: Price
price.current*Type: number | null50
price.previous*Type: number | null31
price.unit_price*Type: number | nullPrice per tablet, capsule, sachet… as listed.2.5
price.currency*Type: "EGP"
price.effective_date*Type: string (date) | nullDate of the current price on the price list.
price.updated_at*Type: string (date-time) | nullWhen the API recorded the current price (sync key). Null only when there is no price.
price.verified*Type: booleanChecked against a published source.
price.verified_at*Type: string (date) | null
barcode*Type: string | null6221051011317
company*Type: NamedRef | nullMarketing company when known, else the manufacturer.
manufacturer*Type: NamedRef | nullSet when a separate manufacturer is listed.
category*Type: Category | null
atc_codes*Type: string[]Product-level ATC codes; ingredient-level codes are on `ingredients[]`.
prescription_status*Type: PrescriptionStatus | null
status*Type: ListingStatusThe price list's own marker on the line. `listed` = no marker; it is not a stock indication.
price_list_name*Type: stringThe exact line name on the source price list.Congestal 20 tabs
created_at*Type: string (date-time)
updated_at*Type: string (date-time)Last change of any field.
links*Type: object
links.web_url*Type: string (uri)https://dwaprice.com/dawa/congestal-20-tabs
مثال
{
  "id": "congestal-20-tabs",
  "trade_name_en": "Congestal 20 tabs",
  "trade_name_ar": "كونجستال 20 قرص",
  "scientific_name": "Chlorpheniramine+paracetamol(acetaminophen)+pseudoephedrine",
  "ingredients": [
    {
      "id": "paracetamol",
      "name_en": "Paracetamol (acetaminophen)",
      "name_ar": "باراسيتامول",
      "strength": "650 mg",
      "atc_code": "N02BE01"
    },
    {
      "id": "chlorpheniramine",
      "name_en": "Chlorphenamine maleate",
      "name_ar": "كلورفينيرامين ماليات",
      "strength": "4 mg",
      "atc_code": "R06AB04"
    },
    {
      "id": "pseudoephedrine",
      "name_en": "Pseudoephedrine hydrochloride",
      "name_ar": "سودوإيفيدرين هيدروكلوريد",
      "strength": "60 mg",
      "atc_code": "R01BA02"
    }
  ],
  "strength": "650/4/60 mg",
  "dosage_form": {
    "class": "tablet",
    "en": "Tablet",
    "ar": "قرص"
  },
  "route": "oral",
  "route_text": "Oral",
  "units_per_package": 20,
  "packaging": "20 tablets (2 blisters of 10)",
  "price": {
    "current": 50,
    "previous": 31,
    "unit_price": 2.5,
    "currency": "EGP",
    "effective_date": "2024-06-06",
    "updated_at": "2026-11-01T00:00:00Z",
    "verified": true,
    "verified_at": "2026-10-03"
  },
  "barcode": "6221051011317",
  "company": {
    "id": "sigma",
    "name": "Sigma"
  },
  "manufacturer": null,
  "category": {
    "id": "cold",
    "en": "Cold/cough combination (analgesic + antihistamine + decongestant)",
    "ar": null
  },
  "atc_codes": [],
  "prescription_status": "otc",
  "status": "listed",
  "price_list_name": "Congestal 20 tabs",
  "created_at": "2026-11-01T00:00:00Z",
  "updated_at": "2026-11-01T00:00:00Z",
  "links": {
    "web_url": "https://dwaprice.com/dawa/congestal-20-tabs"
  }
}

Alternative

Alternative fields
id*Type: stringStable public id (URL slug).congestal-20-tabs
trade_name_en*Type: stringCongestal 20 tabs
trade_name_ar*Type: string | nullكونجستال 20 قرص
scientific_name*Type: string | nullChlorpheniramine+paracetamol(acetaminophen)+pseudoephedrine
ingredients*Type: Ingredient[]
strength*Type: string | null650/4/60 mg
dosage_form*Type: DosageForm
dosage_form.class*Type: DosageFormClass
dosage_form.en*Type: string | nullTablet
dosage_form.ar*Type: string | nullقرص
route*Type: RouteClass | null
route_text*Type: string | nullOral
units_per_package*Type: integer | null20
packaging*Type: string | null20 tablets (2 blisters of 10)
price*Type: Price
price.current*Type: number | null50
price.previous*Type: number | null31
price.unit_price*Type: number | nullPrice per tablet, capsule, sachet… as listed.2.5
price.currency*Type: "EGP"
price.effective_date*Type: string (date) | nullDate of the current price on the price list.
price.updated_at*Type: string (date-time) | nullWhen the API recorded the current price (sync key). Null only when there is no price.
price.verified*Type: booleanChecked against a published source.
price.verified_at*Type: string (date) | null
barcode*Type: string | null6221051011317
company*Type: NamedRef | nullMarketing company when known, else the manufacturer.
manufacturer*Type: NamedRef | nullSet when a separate manufacturer is listed.
category*Type: Category | null
atc_codes*Type: string[]Product-level ATC codes; ingredient-level codes are on `ingredients[]`.
prescription_status*Type: PrescriptionStatus | null
status*Type: ListingStatusThe price list's own marker on the line. `listed` = no marker; it is not a stock indication.
price_list_name*Type: stringThe exact line name on the source price list.Congestal 20 tabs
created_at*Type: string (date-time)
updated_at*Type: string (date-time)Last change of any field.
links*Type: object
links.web_url*Type: string (uri)https://dwaprice.com/dawa/congestal-20-tabs
match*Type: same_strength | other_strength
same_form*Type: booleanSame dosage-form class as the requested drug.
same_product*Type: booleanAnother pack of the same product.
price_diff*Type: number | nullalternative.price.current − drug.price.current
unit_price_diff_pct*Type: number | nullUnit-price difference in percent (negative = cheaper per unit).

PricePoint

PricePoint fields
price*Type: number
effective_date*Type: string (date) | null
recorded_at*Type: string (date-time) | null
source*Type: catalog | change_log

PriceChangeEvent

PriceChangeEvent fields
id*Type: integerMonotonic ordering key.
type*Type: EventType
detected_at*Type: string (date-time)
drug_id*Type: string
data*Type: objectprice_changed: {old, new, effective_date, change_pct}; added: {price}; status_changed: {old, new}; removed: {last_price, last_status}; renamed: {new_id}
drug*Type: Drug | nullThe current record; null for `removed`.
مثال
{
  "id": 48213,
  "type": "price_changed",
  "detected_at": "2026-10-21T12:22:04Z",
  "drug_id": "congestal-20-tabs",
  "data": {
    "old": 31,
    "new": 50,
    "effective_date": "2024-06-06",
    "change_pct": 61.29
  },
  "drug": {
    "id": "congestal-20-tabs",
    "trade_name_en": "Congestal 20 tabs",
    "...": "..."
  }
}

Company

Company fields
id*Type: stringeva-pharma
name*Type: stringEva Pharma
product_count*Type: integer305

IngredientSummary

IngredientSummary fields
id*Type: stringparacetamol
name_en*Type: string | nullParacetamol
name_ar*Type: string | nullباراسيتامول
product_count*Type: integer179

DatasetMeta

DatasetMeta fields
dataset_version*Type: string2026-10-21.184
updated_at*Type: string (date-time)
last_price_change_at*Type: string (date-time) | null
last_price_list_date*Type: string (date) | null
counts*Type: object
counts.drugs*Type: integer14726
counts.priced*Type: integer14169
counts.verified*Type: integer13597
counts.with_barcode*Type: integer5302
counts.companies*Type: integer3270
counts.ingredients*Type: integer3771
counts.categories*Type: integer987
api_version*Type: string1.0.0
docs_url*Type: string (uri)

Webhook

Webhook fields
id*Type: string
url*Type: string (uri)
events*Type: EventType[]
status*Type: active | paused
created_at*Type: string (date-time)
last_delivery_at*Type: string (date-time) | null
last_status*Type: integer | null

سجل التغييرات

  • 1.0.0 — 2026-10-21

    الإصدار الأول: الأدوية، البحث، الباركود، البدائل، تاريخ السعر، تغذية التغييرات، الشركات، المواد الفعالة، meta؛ عينة بلا مفتاح؛ التصدير والـ webhooks لخطة Enterprise.

التغييرات الإضافية (حقول ومعاملات ونقاط نهاية وقيم جديدة) تصدر في /v1 وتُسجَّل هنا؛ على العملاء تجاهل الحقول والقيم المجهولة. التغييرات غير المتوافقة تصدر في /v2 مع إبقاء /v1 اثني عشر شهرًا والإعلان بترويستي Deprecation وSunset.