تخطَّ إلى المحتوى
TakPhoto

REST API · الإصدار 1

صور مستندات مطابقة للشروط بطلب API واحد

أرسل صورة والمستند المطلوب لها، فتعود إليك مقصوصة وبالمقاس الصحيح ومفحوصة وفق الشروط الرسمية لذلك المستند، مع نتيجة كل فحص — المحرّك نفسه الذي يعمل عليه موقعنا، للتطبيقات ومحلات الطباعة والأكشاك.

العنوان الأساسي https://api.takiphoto.com/api/v1

حالة الـ API: جارٍ التحقق…

بدء سريع

من الصفر إلى صورة جاهزة في ثلاث خطوات.

  1. احصل على مفتاح تجريبي

    افتح حساب API وأنشئ مفتاحاً تجريبياً — يبدأ بـ pk_test_. المفاتيح التجريبية مجانية وتعيد معاينة بعلامة مائية.

    احصل على مفتاح تجريبي
  2. أرسل صورة

    أرسل الصورة بطلب POST مع المستند الذي تحتاجه. يصلك الرد فور جهوز الصورة، أو 202 مع ترويسة Location لتتابعها.

    curl -X POST "https://api.takiphoto.com/api/v1/photos" \
      -H "Authorization: Bearer pk_test_EXAMPLE000000000000000000000000000000000000" \
      -F "[email protected]" \
      -F "spec_id=us-passport" \
      -F 'outputs=["digital"]'
  3. اقرأ النتيجة

    تحمل الصورة حالتها، وكل فحص قيست به، وبعد اكتمالها روابط موقَّعة لملفاتها. هذا شكلها:

    {
      "checks": [
        {
          "code": "string",
          "hint": "string",
          "result": "string",
          "value": 0
        }
      ],
      "created_at": "2026-01-01T12:00:00Z",
      "credits_charged": 0,
      "crop": {
        "rotation_deg": 0,
        "scale": 0,
        "x0": 0,
        "x1": 0,
        "y0": 0,
        "y1": 0
      },
      "expires_at": "2026-01-01T12:00:00Z",
      "id": "string",
      "outputs": {
        "digital": {
          "bytes": 0,
          "height": 0,
          "url": "string",
          "width": 0
        },
        "sheets": {
          "key": {
            "jpeg": "string",
            "pdf": "string"
          }
        }
      },
      "review": {
        "reason": "string",
        "status": "string"
      },
      "spec": {
        "id": "string",
        "version": 0
      },
      "status": "processing"
    }

أمثلة برمجية

الطلبات الثلاثة نفسها بأربع لغات. ضع مفتاحك مكان المفتاح المثال.

رفع ملف صورة
curl -X POST "https://api.takiphoto.com/api/v1/photos" \
  -H "Authorization: Bearer pk_test_EXAMPLE000000000000000000000000000000000000" \
  -F "[email protected]" \
  -F "spec_id=us-passport" \
  -F 'outputs=["digital"]'
قراءة صورة
curl "https://api.takiphoto.com/api/v1/photos/PHOTO_ID" \
  -H "Authorization: Bearer pk_test_EXAMPLE000000000000000000000000000000000000"
إرسال صورة برابطها
curl -X POST "https://api.takiphoto.com/api/v1/photos" \
  -H "Authorization: Bearer pk_test_EXAMPLE000000000000000000000000000000000000" \
  -H "Content-Type: application/json" \
  -d '{"spec_id": "us-passport", "image_url": "https://example.com/photo.jpg", "outputs": ["digital"]}'

مرجع الـ API

مولَّد من عقد OpenAPI المنشور، فيسرد بالضبط ما يستجيب له الـ API — لا أكثر ولا أقل.

يحمل كل طلب مفتاح الـ API في الترويسة Authorization: Bearer pk_test_…. المفاتيح الحية (pk_live_) تُخصم من خطتك، والتجريبية (pk_test_) مجانية وتضع علامة مائية على النتيجة.

/photos

post/photosمفتاح API

Create Photo

A photo from file (multipart) or image_url (JSON). Answers 200 with the result when the photo settles within the wait — completed (one credit on a live key), needs_retake or failed (free) — else 202 with Location to poll. An expert review answers 202 in_review until the expert decides.

جسم الطلب application/json
backgroundstring | null

#RRGGBB; the document's own colour when absent.

الحدود:pattern: ^#[0-9A-Fa-f]{6}$

callback_urlstring | null

A public https URL told when this photo settles.

الحدود:maxLength: 512

expert_reviewboolean

Live keys: have an expert check the photo (one review credit).

الافتراضي: false

image_urlstring | nullمطلوب

JSON body only: a public http(s) URL of the photo, fetched by us (≤ 25 MB).

الحدود:maxLength: 2048

outputsarray<string>

The files wanted: the digital photo and any print sheets.

إحدى القيم:digital4x6in10x15cma4

الحدود:minItems: 1maxItems: 4

retouchboolean

The automatic light retouch, when it is offered.

الافتراضي: false

spec_idstringمطلوب

A document from GET /specs.

الحدود:minLength: 4maxLength: 64

مثال
{
  "background": "string",
  "callback_url": "string",
  "expert_review": false,
  "image_url": "string",
  "outputs": [
    "digital"
  ],
  "retouch": false,
  "spec_id": "string"
}
جسم الطلب multipart/form-data
backgroundstring | null

#RRGGBB; the document's own colour when absent.

الحدود:pattern: ^#[0-9A-Fa-f]{6}$

callback_urlstring | null

A public https URL told when this photo settles.

الحدود:maxLength: 512

expert_reviewboolean

Live keys: have an expert check the photo (one review credit).

الافتراضي: false

filestring<binary>مطلوب

The photo: JPEG, PNG, HEIC or WebP, at most 25 MB.

outputsstring

The files wanted, as the JSON text of an array: ["digital","4x6in"].

الافتراضي: ["digital"]

retouchboolean

The automatic light retouch, when it is offered.

الافتراضي: false

spec_idstringمطلوب

A document from GET /specs.

الحدود:minLength: 4maxLength: 64

الردود
    • 200Successful Response
    • 202Still processing after `api.sync_wait_s` (15 s): follow `Location`.
    مثال
    {
      "checks": [
        {
          "code": "string",
          "hint": "string",
          "result": "string",
          "value": 0
        }
      ],
      "created_at": "2026-01-01T12:00:00Z",
      "credits_charged": 0,
      "crop": {
        "rotation_deg": 0,
        "scale": 0,
        "x0": 0,
        "x1": 0,
        "y0": 0,
        "y1": 0
      },
      "expires_at": "2026-01-01T12:00:00Z",
      "id": "string",
      "outputs": {
        "digital": {
          "bytes": 0,
          "height": 0,
          "url": "string",
          "width": 0
        },
        "sheets": {
          "key": {
            "jpeg": "string",
            "pdf": "string"
          }
        }
      },
      "review": {
        "reason": "string",
        "status": "string"
      },
      "spec": {
        "id": "string",
        "version": 0
      },
      "status": "processing"
    }
    • 400Invalid request
    • 401Authentication required
    • 402Quota used up
    • 403Not allowed
    • 404Not found
    • 413Upload too large
    • 422Request is not valid
    • 429Rate limited
    • 503Maintenance
    مثال
    {
      "code": "string",
      "hint": "string",
      "message": "string"
    }

/photos/{photo_id}

get/photos/{photo_id}مفتاح API

Get Photo

The photo as it is now. Under the key's delete_after_download, the first read of a finished photo leaves it one more hour.

المعاملات
photo_idstringفي المسارمطلوب
الردود
    • 200Successful Response
    مثال
    {
      "checks": [
        {
          "code": "string",
          "hint": "string",
          "result": "string",
          "value": 0
        }
      ],
      "created_at": "2026-01-01T12:00:00Z",
      "credits_charged": 0,
      "crop": {
        "rotation_deg": 0,
        "scale": 0,
        "x0": 0,
        "x1": 0,
        "y0": 0,
        "y1": 0
      },
      "expires_at": "2026-01-01T12:00:00Z",
      "id": "string",
      "outputs": {
        "digital": {
          "bytes": 0,
          "height": 0,
          "url": "string",
          "width": 0
        },
        "sheets": {
          "key": {
            "jpeg": "string",
            "pdf": "string"
          }
        }
      },
      "review": {
        "reason": "string",
        "status": "string"
      },
      "spec": {
        "id": "string",
        "version": 0
      },
      "status": "processing"
    }
    • 400Invalid request
    • 401Authentication required
    • 402Quota used up
    • 403Not allowed
    • 404Not found
    • 413Upload too large
    • 422Request is not valid
    • 429Rate limited
    • 503Maintenance
    مثال
    {
      "code": "string",
      "hint": "string",
      "message": "string"
    }
delete/photos/{photo_id}مفتاح API

Delete Photo

The photo and every file made from it, at once.

المعاملات
photo_idstringفي المسارمطلوب
الردود
    • 204Successful Response
    • 400Invalid request
    • 401Authentication required
    • 402Quota used up
    • 403Not allowed
    • 404Not found
    • 413Upload too large
    • 422Request is not valid
    • 429Rate limited
    • 503Maintenance
    مثال
    {
      "code": "string",
      "hint": "string",
      "message": "string"
    }

/photos/{photo_id}/adjust

post/photos/{photo_id}/adjustمفتاح API

Adjust Photo

Scale and shift the crop (the same rules as the web editor); the photo's files are made again at once. Free: credits_charged does not change.

المعاملات
photo_idstringفي المسارمطلوب
جسم الطلب application/json
dxnumberمطلوب

الحدود:minimum: -300maximum: 300

dynumberمطلوب

الحدود:minimum: -300maximum: 300

scalenumberمطلوب

الحدود:minimum: 0.7maximum: 1.4

مثال
{
  "dx": 0,
  "dy": 0,
  "scale": 0.7
}
الردود
    • 200Successful Response
    مثال
    {
      "checks": [
        {
          "code": "string",
          "hint": "string",
          "result": "string",
          "value": 0
        }
      ],
      "created_at": "2026-01-01T12:00:00Z",
      "credits_charged": 0,
      "crop": {
        "rotation_deg": 0,
        "scale": 0,
        "x0": 0,
        "x1": 0,
        "y0": 0,
        "y1": 0
      },
      "expires_at": "2026-01-01T12:00:00Z",
      "id": "string",
      "outputs": {
        "digital": {
          "bytes": 0,
          "height": 0,
          "url": "string",
          "width": 0
        },
        "sheets": {
          "key": {
            "jpeg": "string",
            "pdf": "string"
          }
        }
      },
      "review": {
        "reason": "string",
        "status": "string"
      },
      "spec": {
        "id": "string",
        "version": 0
      },
      "status": "processing"
    }
    • 400Invalid request
    • 401Authentication required
    • 402Quota used up
    • 403Not allowed
    • 404Not found
    • 413Upload too large
    • 422Request is not valid
    • 429Rate limited
    • 503Maintenance
    مثال
    {
      "code": "string",
      "hint": "string",
      "message": "string"
    }

/specs

get/specsمفتاح API

List Specs

The document specs a photo can be made for, verified ones first; country is the ISO 3166-1 alpha-2 code, q matches the id or a name in any language.

المعاملات
countrystring | nullفي الاستعلام

الحدود:minLength: 2maxLength: 2

qstring | nullفي الاستعلام

الحدود:maxLength: 64

limitintegerفي الاستعلام

الافتراضي: 50

الحدود:minimum: 1maximum: 200

الردود
    • 200Successful Response
    مثال
    [
      {
        "background": "string",
        "category": "string",
        "country": "string",
        "id": "string",
        "names": {
          "key": "string"
        },
        "output_px": [
          0
        ],
        "tier": "string",
        "version": 0
      }
    ]
    • 400Invalid request
    • 401Authentication required
    • 402Quota used up
    • 403Not allowed
    • 404Not found
    • 413Upload too large
    • 422Request is not valid
    • 429Rate limited
    • 503Maintenance
    مثال
    {
      "code": "string",
      "hint": "string",
      "message": "string"
    }

/specs/{spec_id}

get/specs/{spec_id}مفتاح API

Get Spec

المعاملات
spec_idstringفي المسارمطلوب
الردود
    • 200Successful Response
    مثال
    {
      "allowed_backgrounds": [
        "string"
      ],
      "background": "string",
      "category": "string",
      "country": "string",
      "digital": {
        "format": "string",
        "height_px": 0,
        "max_kb": 0,
        "max_px": 0,
        "min_px": 0,
        "width_px": 0
      },
      "dpi": 0,
      "eye_line_from_bottom_mm": {
        "max": 0,
        "min": 0
      },
      "head_height_mm": {
        "max": 0,
        "min": 0
      },
      "id": "string",
      "names": {
        "key": "string"
      },
      "output_px": [
        0
      ],
      "print_sheets": [
        "string"
      ],
      "rules": {
        "color": "string",
        "expression": "string",
        "glasses": "string",
        "head_covering": "string"
      },
      "size_mm": {
        "height": 0,
        "width": 0
      },
      "source_url": "string",
      "tier": "string",
      "verified_at": "2026-01-01",
      "version": 0
    }
    • 400Invalid request
    • 401Authentication required
    • 402Quota used up
    • 403Not allowed
    • 404Not found
    • 413Upload too large
    • 422Request is not valid
    • 429Rate limited
    • 503Maintenance
    مثال
    {
      "code": "string",
      "hint": "string",
      "message": "string"
    }

/usage

get/usageمفتاح API

Usage

Credits left this period, the key's rate limit and mode, and its calls today.

الردود
    • 200Successful Response
    مثال
    {
      "mode": "live",
      "period_end": "2026-01-01T12:00:00Z",
      "photos": {
        "balance": 0,
        "quota": 0,
        "used_this_period": 0
      },
      "rate_limit_per_min": 0,
      "requests_today": 0,
      "reviews": {
        "balance": 0,
        "quota": 0,
        "used_this_period": 0
      }
    }
    • 400Invalid request
    • 401Authentication required
    • 402Quota used up
    • 403Not allowed
    • 404Not found
    • 413Upload too large
    • 422Request is not valid
    • 429Rate limited
    • 503Maintenance
    مثال
    {
      "code": "string",
      "hint": "string",
      "message": "string"
    }

رموز الفحوصات والأخطاء

كل رمز قد يعيده الـ API، من القائمة نفسها التي تترجمها تطبيقاتنا.

رموز الفحوصات

كل عنصر في فحوصات الصورة يسمّي أحد هذه الرموز مع نتيجته.

الرمزالمعنى
file_invalid

تعذّرت قراءة هذا الملف

ارفع صورة بصيغة JPEG أو PNG أو HEIC.

file_too_large

حجم الملف كبير جداً

صدّر نسخة أصغر وحاول مرة أخرى.

image_too_large

عدد بكسلات الصورة كبير جداً

أي صورة حتى 50 ميغابكسل تعمل.

no_face

لم نعثر على وجه

واجه الكاميرا في إضاءة متساوية دون أي غطاء على وجهك.

multiple_faces

أكثر من شخص في الصورة

يجب أن تكون وحدك في الإطار.

head_turned

رأسك مائل إلى الجانب

انظر مباشرة إلى الكاميرا.

head_tilted

رأسك مائل

حافظ على استقامة رأسك وانظر إلى الأمام مباشرة.

eyes_closed

عيناك تبدوان مغلقتين

افتح عينيك وانظر إلى الكاميرا.

mouth_open

فمك مفتوح

أغلق فمك بتعبير محايد.

not_neutral

التعبير غير محايد

أرخِ ملامح وجهك دون ابتسامة.

blurry

الصورة غير واضحة

ثبّت الكاميرا وتأكد من أن وجهك في بؤرة التركيز.

too_dark

الصورة داكنة جداً

واجه نافذة أو أضف إضاءة أمامك.

too_bright

الصورة شديدة الإضاءة

ابتعد عن الإضاءة المباشرة.

uneven_lighting

ظل على جانب من الوجه

يجب أن يأتي الضوء من أمامك لا من الجانب.

not_color

هذا المستند يتطلب صورة ملونة

التقط الصورة بوضع الألوان.

busy_background

الخلفية مزدحمة

جدار بسيط خلفك يمنح حواف أنظف — أو أضف مراجعة من خبير.

head_not_measurable

تعذّر قياس رأسك

واجه الكاميرا في إضاءة جيدة وحاول مرة أخرى.

low_resolution

وجهك صغير جداً في الصورة

اقترب أكثر أو استخدم صورة أكبر.

crown_cut

أعلى الرأس مقصوص

اترك مسافة فوق الشعر.

shoulders_cut

الإطار ينتهي قريباً جداً من الذقن

أضف كتفيك إلى الصورة.

subject_cut_side

الشخص مقصوص من الحافة

توسّط الإطار مع مسافة متساوية على الجانبين.

eye_line_out_of_range

خط العينين خارج النطاق المسموح

أُطِّرت الصورة حسب ارتفاع الرأس بدلاً من ذلك.

head_size_out_of_range

حجم الرأس خارج النطاق المسموح لهذا المستند

قرّب أو بعّد حتى يلائم الرأس الدليل.

file_size_over_limit

حجم الملف أكبر مما يسمح به هذا المستند

خفّضنا الجودة إلى أقصى حد مقبول.

retouch_skipped

لا يوجد ما يمكن تحسينه بأمان

تم الاحتفاظ بالصورة الأصلية.

رموز الأخطاء

الطلب الذي يفشل يرد بحالة HTTP وغلاف خطأ رمزه أحد هذه الرموز.

الرمزحالة HTTPالمعنى
background_not_allowed400لون الخلفية هذا غير مسموح لهذا المستند.
credit_packs_disabled400حزم الرصيد غير معروضة للبيع حالياً.
crop_out_of_bounds400منطقة القص المطلوبة تتجاوز حدود الصورة.
email_required400يلزم إدخال بريد إلكتروني للتسليم.
invite_invalid400هذه الدعوة غير صالحة.
magic_link_invalid400رابط تسجيل الدخول هذا غير صالح أو منتهي الصلاحية — اطلب رابطاً جديداً.
plan_not_available400هذه الخطة غير متاحة.
product_not_available400هذا المنتج غير متاح.
setting_out_of_range400قيمة الإعداد خارج النطاق المسموح.
setting_unknown400مفتاح الإعداد هذا غير معروف.
totp_invalid400رمز التحقق غير صحيح.
turnstile_failed400فشل فحص مكافحة الروبوتات — أعد تحميل الصفحة وحاول مرة أخرى.
webhook_invalid400توقيع أو محتوى الـ webhook غير صالح.
api_key_invalid401مفتاح الـ API هذا غير صالح.
api_key_revoked401أُلغي مفتاح الـ API هذا.
session_expired401انتهت صلاحية جلستك — سجّل الدخول مرة أخرى.
unauthorized401يلزم تسجيل الدخول للمتابعة.
payment_required402لم يتم دفع ثمن هذا الطلب بعد.
quota_exceeded402نفدت حصة الصور لدى المؤسسة — رقِّ الخطة أو اشترِ حزمة رصيد.
review_quota_exceeded402لم تبقَ مراجعات خبير في فترة الفوترة هذه.
seat_limit402لا مقاعد شاغرة في خطتك — رقِّها أو أزل عضواً.
subscription_required402يلزم اشتراك فعّال — اختر خطة من صفحة الفوترة.
api_disabled403الـ API غير مفعّل لهذه المؤسسة.
forbidden403ليست لديك صلاحية الوصول إلى هذا.
org_forbidden403دورك في هذه المؤسسة لا يسمح بذلك.
org_suspended403هذه المؤسسة موقوفة — تواصل مع الدعم.
totp_required403هذا الإجراء يتطلب عامل تحقق ثانٍ.
client_not_found404لم نعثر على هذا الزبون.
handoff_not_found404انتهت صلاحية هذا الرابط — اعرض رمز QR جديداً وامسحه من جديد.
intake_disabled404رابط الاستقبال هذا غير مفعّل.
not_found404لم نعثر على هذا العنصر.
org_not_found404لم نعثر على هذه المؤسسة.
photo_not_found404لم نعثر على هذه الصورة.
spec_not_found404هذا المستند غير معروف.
upload_not_found404لم يتم العثور على هذا الملف المرفوع أو انتهت صلاحيته.
already_paid409تم دفع ثمن هذا الطلب بالفعل.
attempts_exhausted409بلغت الحد الأقصى لعدد المحاولات — سيراجع أحد المختصين هذا الطلب.
invalid_state409هذا الإجراء غير ممكن في الحالة الحالية للطلب.
last_owner409يجب أن يبقى للمؤسسة مالك واحد على الأقل.
org_slug_taken409اسم الرابط هذا مستخدم بالفعل.
owner_of_organisation409أنت المالك الوحيد لمؤسسة. اجعل عضواً آخر مالكاً لها أو احذف المؤسسة قبل حذف حسابك.
product_has_sales409لا يمكن حذف منتج له مبيعات — عطّله بدلاً من ذلك.
spec_switch_not_allowed409يمكن تغيير المستند مرة واحدة فقط، إلى مستند بسعر مساوٍ أو أقل.
upload_already_used409تم استخدام هذا الملف المرفوع في طلب آخر بالفعل.
invite_expired410انتهت صلاحية هذه الدعوة — اطلب من المالك إرسال دعوة جديدة.
export_too_large413حجم التصدير يتجاوز 2 GB — اختر نطاق تواريخ أقصر.
image_url_invalid422يجب أن يكون عنوان الصورة رابط http(s) عاماً.
image_url_unreachable422تعذّر جلب الصورة من هذا العنوان.
logo_invalid422يجب أن يكون الشعار بصيغة PNG أو JPEG وبحجم لا يتجاوز 1 MB.
org_slug_reserved422لا يمكن استخدام اسم الرابط هذا.
validation_error422الطلب غير صالح.
webhook_url_invalid422يجب أن يكون عنوان الـ webhook رابط https عاماً.
rate_limited429طلبات كثيرة جداً — يرجى الانتظار قليلاً.
test_key_daily_limit429بلغ مفتاح الاختبار حدّه اليومي — استخدم مفتاحاً حقيقياً للمزيد.
internal_error500حدث خطأ ما من جانبنا.
maintenance503تاك فوتو تحت الصيانة لفترة قصيرة — يرجى المحاولة بعد دقائق.

الـ Webhooks

اضبط رابط webhook على مفتاحك، أو callback_url على صورة واحدة، فنرسل إليك الصورة لحظة استقرار حالتها — بلا استطلاع متكرر.

الأحداث

photo.completed
اكتملت الصورة وملفاتها جاهزة.
photo.failed
تعذّر إنتاج الصورة. لم يُخصم شيء.
review.approved
وافق خبير المراجعة على الصورة.
review.rejected
رفض خبير المراجعة الصورة؛ السبب في review.reason.

الترويسات

X-Event
اسم الحدث.
X-Delivery-Id
معرّف هذا الإرسال.
X-Signature
التوقيع، متى صار لمفتاحك سرّ webhook.

إعادة المحاولة

ردّ بأي حالة 2xx خلال 10 ثوانٍ. أي شيء آخر — حالة أخرى أو تحويل أو عدم الرد في الوقت — محاولة فاشلة، ويُعاد الإرسال:

  1. المحاولة 1: فوراً
  2. المحاولة 2: بعد دقيقة من سابقتها
  3. المحاولة 3: بعد 5 دقائق من سابقتها
  4. المحاولة 4: بعد 30 دقيقة من سابقتها
  5. المحاولة 5: بعد ساعتان من سابقتها

إن فشلت المحاولة 5 أيضاً، يُتخلّى عن الإرسال.

الحمولة

طلب POST بجسم JSON: الحدث، ووقته، والصورة كما تعيدها قراءتها عبر الـ API تماماً. قد يصل الحدث نفسه أكثر من مرة، فأزل التكرار بمعرّفه id.

{
  "id": "evt_00000000000000000000000000000000",
  "event": "photo.completed",
  "created_at": "2026-01-01T12:00:00Z",
  "data": {
    "checks": [
      {
        "code": "string",
        "hint": "string",
        "result": "string",
        "value": 0
      }
    ],
    "created_at": "2026-01-01T12:00:00Z",
    "credits_charged": 0,
    "crop": {
      "rotation_deg": 0,
      "scale": 0,
      "x0": 0,
      "x1": 0,
      "y0": 0,
      "y1": 0
    },
    "expires_at": "2026-01-01T12:00:00Z",
    "id": "string",
    "outputs": {
      "digital": {
        "bytes": 0,
        "height": 0,
        "url": "string",
        "width": 0
      },
      "sheets": {
        "key": {
          "jpeg": "string",
          "pdf": "string"
        }
      }
    },
    "review": {
      "reason": "string",
      "status": "string"
    },
    "spec": {
      "id": "string",
      "version": 0
    },
    "status": "processing"
  }
}

تحقّق من التوقيع

شكل X-Signature هو t=<timestamp>,v1=<hex>. احسب HMAC-SHA256 بسرّ الـ webhook على الطابع الزمني ثم نقطة ثم جسم الطلب الخام، وقارنه بـ v1 بمقارنة ثابتة الزمن، وارفض الإرسال إن اختلفا أو إن ابتعد الطابع الزمني عن ساعتك أكثر من 300 ثانية.

import hashlib
import hmac
import time

TOLERANCE_S = 300


def verify(secret: str, header: str, raw_body: bytes) -> bool:
    """header is X-Signature; raw_body is the request body before any JSON parsing."""
    parts = dict(item.split("=", 1) for item in header.split(",") if "=" in item)
    t, v1 = parts.get("t", ""), parts.get("v1", "")
    if not t.isdigit() or not v1 or abs(time.time() - int(t)) > TOLERANCE_S:
        return False
    expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, v1)

الأسعار

خطط شهرية للمفاتيح الحية. المفاتيح التجريبية مجانية دائماً.

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

كل تغيير في /api/v1. أي تغيير كاسر يأتي بإصدار جديد فقط، ويبقى الإصدار القديم عاملاً 12 شهراً.

v1 — 2026-09

الإصدار الأول من /api/v1.

نقاط النهاية (Endpoints)

  • GET /specs وGET /specs/{spec_id} — كتالوج مواصفات المستندات.
  • POST /photos — رفع صورة (multipart أو image_url موجَّه)؛ إجابة متزامنة خلال 15 ثانية أو 202 مع Location لمتابعة النتيجة.
  • GET /photos/{photo_id} — حالة الصورة ومخرجاتها.
  • POST /photos/{photo_id}/adjust — تعديل القص/التكبير مجاناً على النتيجة الجاهزة.
  • DELETE /photos/{photo_id} — حذف فوري للصورة وملفاتها.
  • GET /usage — الحصة المتبقية والاستهلاك الحالي.
  • GET /content/legal/{name} وGET /content/changelog/{name} — الوثائق القانونية وسجل التغييرات بصيغة Markdown.

المصادقة

كل نداء موثَّق يحتاج Authorization: Bearer <مفتاحك>. مفاتيح pk_live_... تُخصم من حصتك وتُنتج ملفات حقيقية؛ مفاتيح pk_test_... مجانية بالكامل وتُنتج معاينة موسومة بعلامة اختبار، لتجربة التكامل قبل التشغيل الفعلي.

الـ Webhooks

إن ضبطت webhook_url لمفتاحك (أو callback_url لصورة واحدة)، تصلك أحداث photo.completed، photo.failed، review.approved وreview.rejected موقَّعة بـ HMAC-SHA256 في ترويسة X-Signature، مع إعادة محاولة تلقائية حتى 5 مرات عند فشل التسليم.

الحدود

كل استجابة موثَّقة تحمل X-RateLimit-Limit، X-RateLimit-Remaining، X-RateLimit-Reset وX-Quota-Remaining. تجاوز حصة الخطة الشهرية يوقف الخدمة أو يُفوتَر كتجاوز، حسب إعداد خطتك.

ابنِ الربط كاملاً مجاناً

المفاتيح التجريبية مجانية وتعيد معاينة بعلامة مائية، فيعمل كل شيء قبل أول صورة مدفوعة.

احصل على مفتاح تجريبي