{"openapi":"3.0.0","paths":{"/files/{id}":{"get":{"operationId":"Files_serve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"signature","required":false,"in":"query","description":"Private files only.","schema":{}},{"name":"expires","required":false,"in":"query","description":"Private files only.","schema":{}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"The file, with its stored content type."},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Download a file\n\nPublic files (ad media, logos, avatars) need nothing else. Private\nfiles (CR images, work documents) need the `expires` and `signature` from their URL; an invalid or\nexpired link answers 404. Supports `Range` for video seeking.","tags":["System"],"x-public":true,"security":[]}},"/health":{"get":{"operationId":"Health_check","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponseDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"The database is down.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponseDto"}}}}},"summary":"Readiness: MySQL and Redis\n\n200 while the API can serve requests (`ok`, or `degraded` when only the\ncache is down), 503 when the database is unreachable. The Docker image's\nHEALTHCHECK calls this.","tags":["System"],"x-public":true,"security":[]}},"/health/live":{"get":{"operationId":"Health_live","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LivenessResponseDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Liveness: the process is up","tags":["System"],"x-public":true,"security":[]}},"/v1/customer/notifications":{"get":{"description":"The Notifications screen (BRD): title, content, date and time, read or unread, newest first, in the request language, paged. `group` picks the icon; `target` is the page a tap opens (null: just show the text). Tapping one: `POST notifications/{id}/read`, then open the target. Empty: \"No notifications currently available\".","operationId":"CustomerNotification_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My notifications","tags":["Customer · Notifications"],"security":[{"customer":[]}]}},"/v1/customer/notifications/unread-count":{"get":{"description":"For the bell badge (also on the home screen).","operationId":"CustomerNotification_unreadCount","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Unread count","tags":["Customer · Notifications"],"security":[{"customer":[]}]}},"/v1/customer/notifications/{id}/read":{"post":{"description":"When the notification is opened (BRD). Idempotent; someone else’s is `NOT_FOUND`.","operationId":"CustomerNotification_markRead","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Mark one read","tags":["Customer · Notifications"],"security":[{"customer":[]}]}},"/v1/customer/notifications/read-all":{"post":{"description":"Returns how many were unread.","operationId":"CustomerNotification_markAllRead","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadAllDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Mark all read","tags":["Customer · Notifications"],"security":[{"customer":[]}]}},"/v1/customer/devices":{"put":{"description":"Call after signing in, whenever the messaging SDK gives a new token, and when the app's language changes (pushes are written in `locale`). One device per sign-in: calling again replaces it. Signing out (or any other end of the session) removes it.","operationId":"CustomerDevice_register","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeviceDto"}}}},"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Register this device for push","tags":["Customer · Devices"],"security":[{"customer":[]}]},"delete":{"description":"Removes this sign-in's device; the session stays.","operationId":"CustomerDevice_remove","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Stop push on this device","tags":["Customer · Devices"],"security":[{"customer":[]}]}},"/v1/customer/devices/test":{"post":{"description":"Sends \"Test notification · إشعار تجريبي\" to this sign-in's registered device, to check the app's push setup. 5 per 10 minutes. `NOT_FOUND` until the device is registered.","operationId":"CustomerDevice_test","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Send a test push","tags":["Customer · Devices"],"security":[{"customer":[]}]}},"/v1/customer/auth/register":{"post":{"description":"Checks the registration form, saves it as an unverified sign-up and sends a 4-digit code to the mobile. The account works only once `register/verify` confirms the code; until then it can’t log in. Registering the same number again replaces the unverified form. `MOBILE_ALREADY_REGISTERED` means the app should offer login.","operationId":"CustomerAuth_register","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, EMAIL_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Register","tags":["Customer · Auth"],"x-public":true,"security":[]}},"/v1/customer/auth/register/resend-otp":{"post":{"description":"Once `resendAfterSeconds` have passed: a new code for the `verificationId` from `register`, which stays the same.","operationId":"CustomerAuth_resendRegisterCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VERIFICATION_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Resend the registration code","tags":["Customer · Auth"],"x-public":true,"security":[]}},"/v1/customer/auth/register/verify":{"post":{"description":"The `verificationId` from `register` and the code: activates the account and starts a session (the app then shows Home).","operationId":"CustomerAuth_verifyRegistration","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSessionDto"}}}},"400":{"description":"VERIFICATION_INVALID, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_INVALID":{"value":{"code":"OTP_INVALID","message":"The verification code is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_EXPIRED":{"value":{"code":"OTP_EXPIRED","message":"The verification code is invalid or expired. Please request a new one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_TOO_MANY_ATTEMPTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_TOO_MANY_ATTEMPTS":{"value":{"code":"OTP_TOO_MANY_ATTEMPTS","message":"Too many incorrect attempts. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Verify the registration","tags":["Customer · Auth"],"x-public":true,"x-session-token":{"namespace":"customer","field":"accessToken"},"security":[]}},"/v1/customer/auth/login":{"post":{"description":"Sends a 4-digit code to a registered, active number and answers its `verificationId`. `MOBILE_NOT_REGISTERED` means the app should offer registration.","operationId":"CustomerAuth_login","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"MOBILE_NOT_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_NOT_REGISTERED":{"value":{"code":"MOBILE_NOT_REGISTERED","message":"No account is registered with this number. Please make sure the mobile number is correct.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Log in","tags":["Customer · Auth"],"x-public":true,"security":[]}},"/v1/customer/auth/login/resend-otp":{"post":{"description":"Once `resendAfterSeconds` have passed: a new code for the `verificationId` from `login`, which stays the same.","operationId":"CustomerAuth_resendLoginCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VERIFICATION_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Resend the login code","tags":["Customer · Auth"],"x-public":true,"security":[]}},"/v1/customer/auth/login/verify":{"post":{"description":"The `verificationId` from `login` and the code: starts a session.","operationId":"CustomerAuth_verifyLogin","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSessionDto"}}}},"400":{"description":"VERIFICATION_INVALID, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_INVALID":{"value":{"code":"OTP_INVALID","message":"The verification code is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_EXPIRED":{"value":{"code":"OTP_EXPIRED","message":"The verification code is invalid or expired. Please request a new one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"MOBILE_NOT_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_NOT_REGISTERED":{"value":{"code":"MOBILE_NOT_REGISTERED","message":"No account is registered with this number. Please make sure the mobile number is correct.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_TOO_MANY_ATTEMPTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_TOO_MANY_ATTEMPTS":{"value":{"code":"OTP_TOO_MANY_ATTEMPTS","message":"Too many incorrect attempts. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Verify the login","tags":["Customer · Auth"],"x-public":true,"x-session-token":{"namespace":"customer","field":"accessToken"},"security":[]}},"/v1/customer/auth/logout":{"post":{"description":"Ends the session of the token sent; it stops working immediately. Other devices stay signed in.","operationId":"CustomerSession_logout","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"Logged out."},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Log out","tags":["Customer · Auth"],"security":[{"customer":[]}]}},"/v1/customer/account":{"get":{"operationId":"CustomerAccount_get","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My account","tags":["Customer · Account"],"security":[{"customer":[]}]},"patch":{"description":"The \"Change language\" screen. Requests without `Accept-Language` or `?lang=` are answered in it from the next request, and SMS messages use it.","operationId":"CustomerAccount_update","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Change my language","tags":["Customer · Account"],"security":[{"customer":[]}]},"delete":{"description":"Call after the app's confirmation dialog; there is no SMS code. Your details and files are removed, every device is signed out (this one included), and your number, email (and CR number) can register a new, empty account.","operationId":"CustomerAccount_delete","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"The account was deleted."},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete my account","tags":["Customer · Account"],"security":[{"customer":[]}]}},"/v1/customer/account/change-mobile":{"post":{"description":"Step 1 of changing the mobile number: the code goes to the new number, and the answer carries the `verificationId` for step 2. Resend with `POST account/change-mobile/resend-otp`.","operationId":"CustomerAccount_requestCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeMobileOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"MOBILE_UNCHANGED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_UNCHANGED":{"value":{"code":"MOBILE_UNCHANGED","message":"The new number is the same as your current number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Send a code to a new number","tags":["Customer · Account"],"security":[{"customer":[]}]}},"/v1/customer/account/change-mobile/resend-otp":{"post":{"description":"Once `resendAfterSeconds` have passed: a new code for the `verificationId` from `account/change-mobile`, which stays the same.","operationId":"CustomerAccount_resendCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VERIFICATION_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Resend the code to the new number","tags":["Customer · Account"],"security":[{"customer":[]}]}},"/v1/customer/account/change-mobile/verify":{"post":{"description":"Step 2: the `verificationId` and the code sent to the new number; swaps it in, and the old number no longer signs in. Every other device is signed out; this one stays signed in. A wrong code keeps the old number.","operationId":"CustomerAccount_changeMobile","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeMobileDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerDto"}}}},"400":{"description":"MOBILE_UNCHANGED, VERIFICATION_INVALID, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_UNCHANGED":{"value":{"code":"MOBILE_UNCHANGED","message":"The new number is the same as your current number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_INVALID":{"value":{"code":"OTP_INVALID","message":"The verification code is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_EXPIRED":{"value":{"code":"OTP_EXPIRED","message":"The verification code is invalid or expired. Please request a new one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_TOO_MANY_ATTEMPTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_TOO_MANY_ATTEMPTS":{"value":{"code":"OTP_TOO_MANY_ATTEMPTS","message":"Too many incorrect attempts. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Change my mobile number","tags":["Customer · Account"],"security":[{"customer":[]}]}},"/v1/customer/profile":{"get":{"operationId":"CustomerProfile_get","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My profile","tags":["Customer · Profile"],"security":[{"customer":[]}]},"patch":{"description":"Send only the fields that changed. A new photo goes in the `avatar` part (the old one is deleted). The mobile number is changed through `account/change-mobile`.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `avatar` as file parts.","operationId":"CustomerProfile_update","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Letters and digits, 2–100 characters.","example":"سارة أحمد"},"email":{"type":"string","nullable":true,"description":"Unique; sent empty, removes it.","example":"sara@example.com"},"avatarFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `avatar` file instead."},"avatar":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."}},"required":[]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerDto"}}}},"400":{"description":"FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"EMAIL_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TOO_LARGE":{"value":{"code":"FILE_TOO_LARGE","message":"File size exceeds the allowed limit ({maxMb} MB).","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"415":{"description":"FILE_TYPE_NOT_ALLOWED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TYPE_NOT_ALLOWED":{"value":{"code":"FILE_TYPE_NOT_ALLOWED","message":"Unsupported file type. Allowed: {allowed}","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Save my profile","tags":["Customer · Profile"],"security":[{"customer":[]}]}},"/v1/customer/cities":{"get":{"description":"The active cities, for city pickers (ads, filters), each with its region, sorted by name in the request language. Public. Send the chosen `id`; an inactive or unknown city is refused with `CITY_NOT_AVAILABLE`.","operationId":"CustomerCities_list","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CityListDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"List cities","tags":["Customer · Cities"],"x-public":true,"security":[]}},"/v1/customer/categories":{"get":{"description":"The active main categories (home \"Categories\"), in display order. Public. Open one with `/categories/{id}/children`.","operationId":"CustomerCategories_mains","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryListDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Main categories","tags":["Customer · Categories"],"x-public":true,"security":[]}},"/v1/customer/categories/tree":{"get":{"description":"Active main categories with their active subcategories, for the ad form and filters. Public.","operationId":"CustomerCategories_tree","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryTreeDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"The whole category tree","tags":["Customer · Categories"],"x-public":true,"security":[]}},"/v1/customer/categories/{id}":{"get":{"description":"An active category with its `path` from the main category (breadcrumbs). Public. A hidden or unknown category is `NOT_FOUND`.","operationId":"CustomerCategories_detail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryDetailDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"One category","tags":["Customer · Categories"],"x-public":true,"security":[]}},"/v1/customer/categories/{id}/children":{"get":{"description":"The active subcategories of a main category. Empty (and `hasChildren: false` on the parent) means the app goes straight to its ads. Public. A hidden or unknown category is `NOT_FOUND`.","operationId":"CustomerCategories_children","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryListDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Subcategories","tags":["Customer · Categories"],"x-public":true,"security":[]}},"/v1/customer/settings":{"get":{"description":"The admin’s contact channels (More → Contact Us): only the configured ones are included (BRD); `phones` is always a list. Public and cached.","operationId":"CustomerSettings_read","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppSettingsDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Read app settings","tags":["Customer · Settings"],"x-public":true,"security":[]}},"/v1/customer/content/pages/{key}":{"get":{"description":"About, Terms or Privacy (More menu, and the Terms link on sign-up), as rich text (HTML). Shared by both apps. When the text is empty in the request language, the other language is used. Public and cached.","operationId":"CustomerContent_page","parameters":[{"name":"key","required":true,"in":"path","schema":{"enum":["about","terms","privacy"],"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Read a page","tags":["Customer · Content"],"x-public":true,"security":[]}},"/v1/customer/contact":{"get":{"description":"The configured contact channels, and the types for a message and for a complaint, in the request language. Public.","operationId":"CustomerContact_screen","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppContactDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Contact Us screen","tags":["Customer · Contact"],"x-public":true,"security":[]}},"/v1/customer/contact/messages":{"post":{"description":"To the administration. `kind` picks the `type` list (`message` by default). Guests can send; with a valid token of this app the message is linked to the account, and a missing or expired token sends as a guest. At most 3 an hour per account (or mobile, for guests) and 5 an hour per network. On 201 the app shows `message` (\"Your message has been successfully sent\").","operationId":"CustomerContact_send","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendContactMessageDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Send a message or a complaint","tags":["Customer · Contact"],"x-public":true,"security":[]}},"/v1/customer/home":{"get":{"description":"For guests and signed-in customers (BRD). Send `lat` and `lng` (the user’s or a chosen location) for nearest-first lists and distances. The active categories, the advertising space (the latest ads near you, D16), the 3 newest ads, and \"Mashhour ads\" for the `categoryId` tab (all when left out). `header` is null for guests. Only live ads appear.","operationId":"CustomerHome_home","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"categoryId","required":false,"in":"query","description":"The \"Mashhour ads\" tab: a main category; all when left out.","schema":{"format":"uuid","type":"string"}},{"name":"lat","required":false,"in":"query","schema":{"minimum":-90,"maximum":90,"example":24.7136,"type":"number"}},{"name":"lng","required":false,"in":"query","schema":{"minimum":-180,"maximum":180,"example":46.6753,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerHomeDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Home","tags":["Customer · Home"],"x-public":true,"security":[]}},"/v1/customer/ads":{"get":{"description":"Live ads as cards, for guests and customers. Filters: `categoryId` (a main category, or a subcategory), `q` (part of the title, up to 100 characters), `cityId`, `dateFrom`/`dateTo` (publish date, Saudi days). With `lat` and `lng` they are sorted nearest first (BRD) with `distanceKm`; else newest first (`sort=newest` forces it). No match: `items: []` (the app shows \"No results available\").","operationId":"CustomerAds_browse","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"categoryId","required":false,"in":"query","description":"A main category or a subcategory.","schema":{"format":"uuid","type":"string"}},{"name":"q","required":false,"in":"query","description":"Part of the ad's title, up to 100 characters.","schema":{"maxLength":100,"example":"مشويات","type":"string"}},{"name":"cityId","required":false,"in":"query","schema":{"format":"uuid","type":"string"}},{"name":"dateFrom","required":false,"in":"query","description":"Published on or after this Saudi day, `YYYY-MM-DD`.","schema":{"type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Published on or before this Saudi day, `YYYY-MM-DD`.","schema":{"type":"string"}},{"name":"sort","required":false,"in":"query","description":"`nearest` (the default with a location, BRD) or `newest` (the default\nwithout one).","schema":{"type":"string","enum":["nearest","newest"]}},{"name":"lat","required":false,"in":"query","schema":{"minimum":-90,"maximum":90,"example":24.7136,"type":"number"}},{"name":"lng","required":false,"in":"query","schema":{"minimum":-180,"maximum":180,"example":46.6753,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerAdCardPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Browse and search ads","tags":["Customer · Ads"],"x-public":true,"security":[]}},"/v1/customer/ads/{id}":{"get":{"description":"For guests and customers (BRD): title, categories, description, images and video, prices and discount, expiry, views, the store (opens `GET merchants/{id}`), call and WhatsApp, email, map location, `isFavorite` and `shareUrl` (for the share sheet and its QR code). Send `lat`/`lng` for `distanceKm`. Counts a view once per viewer per day. An ad that is gone, expired or hidden is `AD_NOT_AVAILABLE`.","operationId":"CustomerAds_detail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"lat","required":false,"in":"query","schema":{"minimum":-90,"maximum":90,"example":24.7136,"type":"number"}},{"name":"lng","required":false,"in":"query","schema":{"minimum":-180,"maximum":180,"example":46.6753,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerAdDetailDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"AD_NOT_AVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_NOT_AVAILABLE":{"value":{"code":"AD_NOT_AVAILABLE","message":"This ad is no longer available.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Ad details","tags":["Customer · Ads"],"x-public":true,"security":[]}},"/v1/customer/ads/{id}/events":{"post":{"description":"Send when the customer taps call, WhatsApp or share on an ad (guests too): the merchant’s statistics count each once per viewer per day (D2). Always 204, even for an ad that is no longer live, so a stale screen never shows an error; at most 60 an hour per network.","operationId":"CustomerAds_event","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdEventDto"}}}},"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Count a call, WhatsApp or share tap","tags":["Customer · Ads"],"x-public":true,"security":[]}},"/v1/customer/merchants/{id}":{"get":{"description":"For guests and customers: the store, its contact and its live ads (nearest first with `lat`/`lng`). Opened from an ad, send `fromAdId`: the visit counts for that ad’s \"activity page visits\" once per viewer per day (BRD, D2). An inactive or deleted merchant is `MERCHANT_NOT_AVAILABLE`.","operationId":"CustomerMerchants_page","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"lat","required":false,"in":"query","schema":{"minimum":-90,"maximum":90,"example":24.7136,"type":"number"}},{"name":"lng","required":false,"in":"query","schema":{"minimum":-180,"maximum":180,"example":46.6753,"type":"number"}},{"name":"fromAdId","required":false,"in":"query","description":"The ad the page was opened from: the visit counts for that ad's\n\"activity page visits\" (BRD, D2).","schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"MERCHANT_NOT_AVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_NOT_AVAILABLE":{"value":{"code":"MERCHANT_NOT_AVAILABLE","message":"This store is no longer available.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"A merchant’s activity page","tags":["Customer · Ads"],"x-public":true,"security":[]}},"/v1/customer/favorites":{"get":{"description":"The ads you saved that are live now (D19), newest saved first, as cards (`isFavorite: true`). Empty: the app shows its empty state. Signed-in customers only (BRD).","operationId":"Favorites_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerAdCardPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My favorites","tags":["Customer · Favorites"],"security":[{"customer":[]}]}},"/v1/customer/favorites/{adId}":{"put":{"description":"The heart on a card or the details. Saving again changes nothing. Only a live ad can be saved (`AD_NOT_AVAILABLE`). Guests get 401 (sign in first, BRD).","operationId":"Favorites_save","parameters":[{"name":"adId","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"AD_NOT_AVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_NOT_AVAILABLE":{"value":{"code":"AD_NOT_AVAILABLE","message":"This ad is no longer available.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Save an ad","tags":["Customer · Favorites"],"security":[{"customer":[]}]},"delete":{"description":"Removing again changes nothing; the ad itself is never touched (BRD).","operationId":"Favorites_remove","parameters":[{"name":"adId","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Remove an ad from favorites","tags":["Customer · Favorites"],"security":[{"customer":[]}]}},"/v1/customer/ads/{id}/reports":{"post":{"description":"The Report ad window (BRD): a reason and an explanation, both required. Signed-in customers only (D11). One open report per ad (`ALREADY_REPORTED`); at most 10 reports an hour. An ad customers can’t see is `AD_NOT_AVAILABLE`.","operationId":"AdReports_report","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportAdDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportSentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"AD_NOT_AVAILABLE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_NOT_AVAILABLE":{"value":{"code":"AD_NOT_AVAILABLE","message":"This ad is no longer available.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"ALREADY_REPORTED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ALREADY_REPORTED":{"value":{"code":"ALREADY_REPORTED","message":"You have already reported this ad; we are reviewing it.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Report an ad","tags":["Customer · Ads"],"security":[{"customer":[]}]}},"/v1/merchant/notifications":{"get":{"description":"The Notifications screen (BRD): title, content, date and time, read or unread, newest first, in the request language, paged. `group` picks the icon; `target` is the page a tap opens (null: just show the text). Tapping one: `POST notifications/{id}/read`, then open the target. Empty: \"No notifications currently available\".","operationId":"MerchantNotification_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My notifications","tags":["Merchant · Notifications"],"security":[{"merchant":[]}]}},"/v1/merchant/notifications/unread-count":{"get":{"description":"For the bell badge (also on the home screen).","operationId":"MerchantNotification_unreadCount","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnreadCountDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Unread count","tags":["Merchant · Notifications"],"security":[{"merchant":[]}]}},"/v1/merchant/notifications/{id}/read":{"post":{"description":"When the notification is opened (BRD). Idempotent; someone else’s is `NOT_FOUND`.","operationId":"MerchantNotification_markRead","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Mark one read","tags":["Merchant · Notifications"],"security":[{"merchant":[]}]}},"/v1/merchant/notifications/read-all":{"post":{"description":"Returns how many were unread.","operationId":"MerchantNotification_markAllRead","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReadAllDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Mark all read","tags":["Merchant · Notifications"],"security":[{"merchant":[]}]}},"/v1/merchant/devices":{"put":{"description":"Call after signing in, whenever the messaging SDK gives a new token, and when the app's language changes (pushes are written in `locale`). One device per sign-in: calling again replaces it. Signing out (or any other end of the session) removes it.","operationId":"MerchantDevice_register","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDeviceDto"}}}},"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Register this device for push","tags":["Merchant · Devices"],"security":[{"merchant":[]}]},"delete":{"description":"Removes this sign-in's device; the session stays.","operationId":"MerchantDevice_remove","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Stop push on this device","tags":["Merchant · Devices"],"security":[{"merchant":[]}]}},"/v1/merchant/devices/test":{"post":{"description":"Sends \"Test notification · إشعار تجريبي\" to this sign-in's registered device, to check the app's push setup. 5 per 10 minutes. `NOT_FOUND` until the device is registered.","operationId":"MerchantDevice_test","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Send a test push","tags":["Merchant · Devices"],"security":[{"merchant":[]}]}},"/v1/merchant/auth/register":{"post":{"description":"The registration form as `multipart/form-data`: the fields as text, and the files as parts `storeLogo` (optional), `crImage` (optional) and `workDocument` (needed when no `crNumber` is given). Saves the application unverified and sends a 4-digit code to the mobile; `register/verify` confirms it. A rejected merchant registers again with the same mobile: the new application replaces the rejected one once verified, and is reviewed again.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `storeLogo`, `crImage`, `workDocument` as file parts.","operationId":"MerchantAuth_register","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Letters and numbers only, 2–100 characters.","example":"محمد عبدالله"},"username":{"type":"string","description":"Used to log in: 3–30 English letters, numbers, `.` or `_`; unique,\ncase-insensitive (stored lowercased).","example":"albait.alshami"},"password":{"type":"string","description":"At least 8 characters with a number.","example":"mashhour2026"},"passwordConfirmation":{"type":"string","description":"Must equal `password`.","example":"mashhour2026"},"mobile":{"type":"string","description":"Saudi mobile, `05XXXXXXXX`; a code is sent to it.","example":"0551234567"},"email":{"type":"string","description":"Unique, at most 100 characters.","example":"store@example.com"},"storeName":{"type":"string","description":"2–100 characters.","example":"مطعم البيت الشامي للمشاويات"},"crNumber":{"type":"string","description":"Commercial registration number, 10 digits, unique. Required unless a\n`workDocument` part is sent.","example":"1010123456"},"acceptTerms":{"type":"boolean","description":"The Terms and Conditions checkbox; must be `true`."},"storeLogo":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."},"crImage":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."},"workDocument":{"type":"string","format":"binary","description":"PDF, PNG, JPG, up to 5 MB."}},"required":["name","username","password","passwordConfirmation","mobile","email","storeName","acceptTerms"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, USERNAME_TAKEN, EMAIL_ALREADY_REGISTERED, CR_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"USERNAME_TAKEN":{"value":{"code":"USERNAME_TAKEN","message":"This username is already in use. Please choose another one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"CR_ALREADY_REGISTERED":{"value":{"code":"CR_ALREADY_REGISTERED","message":"The commercial registration number is already in use.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TOO_LARGE":{"value":{"code":"FILE_TOO_LARGE","message":"File size exceeds the allowed limit ({maxMb} MB).","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"415":{"description":"FILE_TYPE_NOT_ALLOWED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TYPE_NOT_ALLOWED":{"value":{"code":"FILE_TYPE_NOT_ALLOWED","message":"Unsupported file type. Allowed: {allowed}","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Register","tags":["Merchant · Auth"],"x-public":true,"security":[]}},"/v1/merchant/auth/register/resend-otp":{"post":{"description":"Only the `verificationId`, after the 60-second countdown.","operationId":"MerchantAuth_resendRegistration","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VERIFICATION_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Resend the registration code","tags":["Merchant · Auth"],"x-public":true,"security":[]}},"/v1/merchant/auth/register/verify":{"post":{"description":"Confirms the mobile. The application is then `under_review` until an admin approves it (the app shows the \"under review\" screen); no session is issued.","operationId":"MerchantAuth_verifyRegistration","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegistrationVerifiedDto"}}}},"400":{"description":"VERIFICATION_INVALID, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_INVALID":{"value":{"code":"OTP_INVALID","message":"The verification code is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_EXPIRED":{"value":{"code":"OTP_EXPIRED","message":"The verification code is invalid or expired. Please request a new one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_TOO_MANY_ATTEMPTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_TOO_MANY_ATTEMPTS":{"value":{"code":"OTP_TOO_MANY_ATTEMPTS","message":"Too many incorrect attempts. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Verify the registration","tags":["Merchant · Auth"],"x-public":true,"security":[]}},"/v1/merchant/auth/login":{"post":{"description":"Username (any case) and password. Only approved merchants get a session; `ACCOUNT_UNDER_REVIEW` and `ACCOUNT_REJECTED` (with the reason in `details`) tell the app which screen to show. Repeated failures are refused for a while (`TOO_MANY_REQUESTS`, `Retry-After`).","operationId":"MerchantAuth_login","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantLoginDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantSessionDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"INVALID_CREDENTIALS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CREDENTIALS":{"value":{"code":"INVALID_CREDENTIALS","message":"The username or password is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_UNDER_REVIEW, ACCOUNT_REJECTED, ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_UNDER_REVIEW":{"value":{"code":"ACCOUNT_UNDER_REVIEW","message":"Your account is still under review. You can log in once it is approved.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_REJECTED":{"value":{"code":"ACCOUNT_REJECTED","message":"Your account was not approved.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Log in","tags":["Merchant · Auth"],"x-public":true,"x-session-token":{"namespace":"merchant","field":"accessToken"},"security":[]}},"/v1/merchant/auth/password/forgot":{"post":{"description":"The registered mobile; a code is sent to it. Then `password/forgot/verify`.","operationId":"MerchantAuth_forgot","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"MOBILE_NOT_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_NOT_REGISTERED":{"value":{"code":"MOBILE_NOT_REGISTERED","message":"No account is registered with this number. Please make sure the mobile number is correct.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Forgot password: send a code","tags":["Merchant · Auth"],"x-public":true,"security":[]}},"/v1/merchant/auth/password/forgot/resend-otp":{"post":{"operationId":"MerchantAuth_resendForgot","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VERIFICATION_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Forgot password: resend the code","tags":["Merchant · Auth"],"x-public":true,"security":[]}},"/v1/merchant/auth/password/forgot/verify":{"post":{"description":"A right code returns a one-time `resetToken`, valid for 10 minutes, for `password/reset`.","operationId":"MerchantAuth_verifyForgot","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetTokenDto"}}}},"400":{"description":"VERIFICATION_INVALID, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_INVALID":{"value":{"code":"OTP_INVALID","message":"The verification code is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_EXPIRED":{"value":{"code":"OTP_EXPIRED","message":"The verification code is invalid or expired. Please request a new one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"MOBILE_NOT_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_NOT_REGISTERED":{"value":{"code":"MOBILE_NOT_REGISTERED","message":"No account is registered with this number. Please make sure the mobile number is correct.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_TOO_MANY_ATTEMPTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_TOO_MANY_ATTEMPTS":{"value":{"code":"OTP_TOO_MANY_ATTEMPTS","message":"Too many incorrect attempts. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Forgot password: check the code","tags":["Merchant · Auth"],"x-public":true,"security":[]}},"/v1/merchant/auth/password/reset":{"post":{"description":"Uses the `resetToken` once. Every session of the merchant is signed out; they log in with the new password.","operationId":"MerchantAuth_reset","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordDto"}}}},"responses":{"204":{"description":""},"400":{"description":"RESET_TOKEN_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"RESET_TOKEN_INVALID":{"value":{"code":"RESET_TOKEN_INVALID","message":"This password reset link is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Set a new password","tags":["Merchant · Auth"],"x-public":true,"security":[]}},"/v1/merchant/auth/logout":{"post":{"description":"Ends the session of the token sent; it stops working immediately. Other devices stay signed in.","operationId":"MerchantSession_logout","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"Logged out."},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Log out","tags":["Merchant · Auth"],"security":[{"merchant":[]}]}},"/v1/merchant/account":{"get":{"operationId":"MerchantAccount_get","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My account","tags":["Merchant · Account"],"security":[{"merchant":[]}]},"patch":{"description":"The \"Change language\" screen. Requests without `Accept-Language` or `?lang=` are answered in it from the next request, and SMS messages use it.","operationId":"MerchantAccount_update","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Change my language","tags":["Merchant · Account"],"security":[{"merchant":[]}]},"delete":{"description":"Call after the app's confirmation dialog; there is no SMS code. Your details and files are removed, every device is signed out (this one included), and your number, email (and CR number) can register a new, empty account.","operationId":"MerchantAccount_delete","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"The account was deleted."},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete my account","tags":["Merchant · Account"],"security":[{"merchant":[]}]}},"/v1/merchant/account/change-mobile":{"post":{"description":"Step 1 of changing the mobile number: the code goes to the new number, and the answer carries the `verificationId` for step 2. Resend with `POST account/change-mobile/resend-otp`.","operationId":"MerchantAccount_requestCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeMobileOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"MOBILE_UNCHANGED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_UNCHANGED":{"value":{"code":"MOBILE_UNCHANGED","message":"The new number is the same as your current number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Send a code to a new number","tags":["Merchant · Account"],"security":[{"merchant":[]}]}},"/v1/merchant/account/change-mobile/resend-otp":{"post":{"description":"Once `resendAfterSeconds` have passed: a new code for the `verificationId` from `account/change-mobile`, which stays the same.","operationId":"MerchantAccount_resendCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VERIFICATION_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Resend the code to the new number","tags":["Merchant · Account"],"security":[{"merchant":[]}]}},"/v1/merchant/account/change-mobile/verify":{"post":{"description":"Step 2: the `verificationId` and the code sent to the new number; swaps it in, and the old number no longer signs in. Every other device is signed out; this one stays signed in. A wrong code keeps the old number.","operationId":"MerchantAccount_changeMobile","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeMobileDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantDto"}}}},"400":{"description":"MOBILE_UNCHANGED, VERIFICATION_INVALID, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_UNCHANGED":{"value":{"code":"MOBILE_UNCHANGED","message":"The new number is the same as your current number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_INVALID":{"value":{"code":"OTP_INVALID","message":"The verification code is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_EXPIRED":{"value":{"code":"OTP_EXPIRED","message":"The verification code is invalid or expired. Please request a new one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_TOO_MANY_ATTEMPTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_TOO_MANY_ATTEMPTS":{"value":{"code":"OTP_TOO_MANY_ATTEMPTS","message":"Too many incorrect attempts. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Change my mobile number","tags":["Merchant · Account"],"security":[{"merchant":[]}]}},"/v1/merchant/profile":{"get":{"operationId":"MerchantProfile_get","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My profile","tags":["Merchant · Profile"],"security":[{"merchant":[]}]},"patch":{"description":"Send only the fields that changed. New documents go in the parts `storeLogo`, `crImage` and `workDocument` (the replaced ones are deleted). A CR number or a work document must remain. The username can’t change; the mobile changes through `account/change-mobile`.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `storeLogo`, `crImage`, `workDocument` as file parts.","operationId":"MerchantProfile_update","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Letters and digits, 2–100 characters.","example":"محمد عبدالله"},"email":{"type":"string","description":"Required and unique.","example":"store@example.com"},"storeName":{"type":"string","description":"2–100 characters.","example":"مطعم البيت الشامي للمشاويات"},"crNumber":{"type":"string","nullable":true,"description":"10 digits, unique; sent empty, removes it (then a work document must\nremain).","example":"1010123456"},"storeLogoFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `storeLogo` file instead."},"crImageFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `crImage` file instead."},"workDocumentFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `workDocument` file instead."},"storeLogo":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."},"crImage":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."},"workDocument":{"type":"string","format":"binary","description":"PDF, PNG, JPG, up to 5 MB."}},"required":[]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantDto"}}}},"400":{"description":"FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"EMAIL_ALREADY_REGISTERED, CR_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"CR_ALREADY_REGISTERED":{"value":{"code":"CR_ALREADY_REGISTERED","message":"The commercial registration number is already in use.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TOO_LARGE":{"value":{"code":"FILE_TOO_LARGE","message":"File size exceeds the allowed limit ({maxMb} MB).","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"415":{"description":"FILE_TYPE_NOT_ALLOWED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TYPE_NOT_ALLOWED":{"value":{"code":"FILE_TYPE_NOT_ALLOWED","message":"Unsupported file type. Allowed: {allowed}","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Save my profile","tags":["Merchant · Profile"],"security":[{"merchant":[]}]}},"/v1/merchant/account/change-password":{"post":{"description":"The current password and the new one. This device stays signed in; every other device is signed out.","operationId":"MerchantPassword_changePassword","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordDto"}}}},"responses":{"204":{"description":""},"400":{"description":"PASSWORD_INCORRECT, PASSWORD_UNCHANGED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PASSWORD_INCORRECT":{"value":{"code":"PASSWORD_INCORRECT","message":"The current password is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"PASSWORD_UNCHANGED":{"value":{"code":"PASSWORD_UNCHANGED","message":"The new password must be different from the current one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Change my password","tags":["Merchant · Account"],"security":[{"merchant":[]}]}},"/v1/merchant/cities":{"get":{"description":"The active cities, for city pickers (ads, filters), each with its region, sorted by name in the request language. Public. Send the chosen `id`; an inactive or unknown city is refused with `CITY_NOT_AVAILABLE`.","operationId":"MerchantCities_list","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CityListDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"List cities","tags":["Merchant · Cities"],"x-public":true,"security":[]}},"/v1/merchant/categories":{"get":{"description":"The active main categories (home \"Categories\"), in display order. Public. Open one with `/categories/{id}/children`.","operationId":"MerchantCategories_mains","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryListDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Main categories","tags":["Merchant · Categories"],"x-public":true,"security":[]}},"/v1/merchant/categories/tree":{"get":{"description":"Active main categories with their active subcategories, for the ad form and filters. Public.","operationId":"MerchantCategories_tree","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryTreeDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"The whole category tree","tags":["Merchant · Categories"],"x-public":true,"security":[]}},"/v1/merchant/categories/{id}":{"get":{"description":"An active category with its `path` from the main category (breadcrumbs). Public. A hidden or unknown category is `NOT_FOUND`.","operationId":"MerchantCategories_detail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryDetailDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"One category","tags":["Merchant · Categories"],"x-public":true,"security":[]}},"/v1/merchant/categories/{id}/children":{"get":{"description":"The active subcategories of a main category. Empty (and `hasChildren: false` on the parent) means the app goes straight to its ads. Public. A hidden or unknown category is `NOT_FOUND`.","operationId":"MerchantCategories_children","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryListDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Subcategories","tags":["Merchant · Categories"],"x-public":true,"security":[]}},"/v1/merchant/settings":{"get":{"description":"The admin’s contact channels (More → Contact Us): only the configured ones are included (BRD); `phones` is always a list. Public and cached.","operationId":"MerchantSettings_read","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppSettingsDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Read app settings","tags":["Merchant · Settings"],"x-public":true,"security":[]}},"/v1/merchant/content/pages/{key}":{"get":{"description":"About, Terms or Privacy (More menu, and the Terms link on sign-up), as rich text (HTML). Shared by both apps. When the text is empty in the request language, the other language is used. Public and cached.","operationId":"MerchantContent_page","parameters":[{"name":"key","required":true,"in":"path","schema":{"enum":["about","terms","privacy"],"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Read a page","tags":["Merchant · Content"],"x-public":true,"security":[]}},"/v1/merchant/contact":{"get":{"description":"The configured contact channels, and the types for a message and for a complaint, in the request language. Public.","operationId":"MerchantContact_screen","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppContactDto"}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Contact Us screen","tags":["Merchant · Contact"],"x-public":true,"security":[]}},"/v1/merchant/contact/messages":{"post":{"description":"To the administration. `kind` picks the `type` list (`message` by default). Guests can send; with a valid token of this app the message is linked to the account, and a missing or expired token sends as a guest. At most 3 an hour per account (or mobile, for guests) and 5 an hour per network. On 201 the app shows `message` (\"Your message has been successfully sent\").","operationId":"MerchantContact_send","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendContactMessageDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageSentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Send a message or a complaint","tags":["Merchant · Contact"],"x-public":true,"security":[]}},"/v1/merchant/payments/{id}":{"get":{"description":"The status of one of your payments (a top-up, a subscription or an ad fee). When the result of a payment is unclear (a timeout, the app closed during checkout), check it here before trying again (BRD); retry only after `failed` or `cancelled`. Anyone else’s payment is `NOT_FOUND`.","operationId":"Payments_find","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Check a payment","tags":["Merchant · Payments"],"security":[{"merchant":[]}]}},"/v1/merchant/wallet":{"get":{"description":"The balance and the transaction log (BRD: amount, date and time, status, balance after), newest first: top-ups, ad fees and package subscriptions.","operationId":"Wallet_overview","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My wallet","tags":["Merchant · Wallet"],"security":[{"merchant":[]}]}},"/v1/merchant/wallet/topups":{"post":{"description":"Pays `amount` through the gateway (PayMob). The balance is credited once the payment is confirmed: with the fake gateway at once; with PayMob, open `payment.checkoutUrl` and then check `GET payments/{id}`. Send an `Idempotency-Key` so a retry after a timeout charges nothing more.","operationId":"Wallet_topUp","parameters":[{"name":"Idempotency-Key","in":"header","description":"A unique value per attempt (8–64 letters, digits, `-`, `_`), e.g. a UUID. Sending the same request again with the same key returns the first result and charges nothing more (a retry after a timeout); the same key with a different request is `IDEMPOTENCY_KEY_REUSED`.","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopUpDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopUpResultDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"IDEMPOTENCY_KEY_REUSED":{"value":{"code":"IDEMPOTENCY_KEY_REUSED","message":"This Idempotency-Key was already used for a different request.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Top up the wallet","tags":["Merchant · Wallet"],"security":[{"merchant":[]}]}},"/v1/merchant/packages":{"get":{"description":"The active packages, each with its price, duration and benefits (BRD); `isCurrent` marks the package of your active subscription. `walletBalance` is shown before you confirm a subscription.","operationId":"Packages_list","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PackageListDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Packages","tags":["Merchant · Packages"],"security":[{"merchant":[]}]}},"/v1/merchant/subscriptions/current":{"get":{"description":"The active subscription: package, status, start and end dates, remaining days and benefits (BRD). `subscription: null` means none (\"No active subscription\", with \"View packages\"). `trial` is the free trial (Figma’s free-package card). Reading never creates or charges anything.","operationId":"Subscriptions_current","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentSubscriptionDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My current subscription","tags":["Merchant · Subscriptions"],"security":[{"merchant":[]}]}},"/v1/merchant/subscriptions":{"get":{"description":"Your current and past subscriptions, newest first (BRD: package, status, start, end, fee). An expired one has `canRenew` (the \"Renew subscription\" button opens the packages). Empty: \"No previous subscriptions\".","operationId":"Subscriptions_history","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Subscription history","tags":["Merchant · Subscriptions"],"security":[{"merchant":[]}]},"post":{"description":"After the confirm dialog (package and fee). Only one active subscription at a time (`SUBSCRIPTION_ALREADY_ACTIVE`); renewing is this call once the last one expired. `wallet`: the fee is deducted and the subscription starts now, or `INSUFFICIENT_BALANCE` with nothing deducted (offer a top-up). `gateway`: open `payment.checkoutUrl` when set; the subscription starts when the payment is confirmed (at once with the fake gateway). Send an `Idempotency-Key` so a retry never pays twice.","operationId":"Subscriptions_subscribe","parameters":[{"name":"Idempotency-Key","in":"header","description":"A unique value per attempt (8–64 letters, digits, `-`, `_`), e.g. a UUID. Sending the same request again with the same key returns the first result and charges nothing more (a retry after a timeout); the same key with a different request is `IDEMPOTENCY_KEY_REUSED`.","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PurchaseDto"}}}},"400":{"description":"PACKAGE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PACKAGE_NOT_AVAILABLE":{"value":{"code":"PACKAGE_NOT_AVAILABLE","message":"This package is not available. Please choose another package.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"402":{"description":"INSUFFICIENT_BALANCE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INSUFFICIENT_BALANCE":{"value":{"code":"INSUFFICIENT_BALANCE","message":"Your wallet balance is insufficient. Top up your wallet and try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"SUBSCRIPTION_ALREADY_ACTIVE, IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SUBSCRIPTION_ALREADY_ACTIVE":{"value":{"code":"SUBSCRIPTION_ALREADY_ACTIVE","message":"You already have an active subscription. You can subscribe to a new package when it ends.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"IDEMPOTENCY_KEY_REUSED":{"value":{"code":"IDEMPOTENCY_KEY_REUSED","message":"This Idempotency-Key was already used for a different request.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Subscribe to a package","tags":["Merchant · Subscriptions"],"security":[{"merchant":[]}]}},"/v1/merchant/publish-gate":{"get":{"description":"Checked in the BRD’s order before an ad is created or reposted: `trial` (free during the free trial), `subscription` (free with an active package), or `fee_required` (pay `fee` from the wallet or by card). The ad form shows it up front; publishing checks it again.","operationId":"PublishGate_check","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishGateDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"What publishing an ad costs","tags":["Merchant · Subscriptions"],"security":[{"merchant":[]}]}},"/v1/merchant/ads":{"get":{"description":"Your ads, newest first, as cards (BRD: main image, title, category, a short description, the location as a Google Maps link, price): filter by `status` (the tabs) and main `categoryId`. An active ad past its expiry is in the `expired` tab. Empty: \"There are no ads currently\".","operationId":"MerchantAds_mine","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"One tab; all of them when left out.","schema":{"type":"string","enum":["active","disabled","rejected","pending_review","expired"]}},{"name":"categoryId","required":false,"in":"query","description":"Ads of one main category.","schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdCardPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"My ads","tags":["Merchant · Ads"],"security":[{"merchant":[]}]},"post":{"description":"The Create ad form as `multipart/form-data`: the fields as text (`subcategoryIds[]` repeated) and the files as parts `images` (1–5: JPG, PNG or WEBP) and `video` (optional, one MP4 or MOV, up to 100 MB). Publishing is checked first (BRD; `GET publish-gate`): free during the trial or with a subscription; otherwise the ad fee, paid with `paymentMethod` `wallet` (`INSUFFICIENT_BALANCE` creates nothing) or `gateway` (open `payment.checkoutUrl` when set; the ad is created once the payment succeeds). Without `paymentMethod` it is `AD_FEE_REQUIRED`. The new ad then waits for review (\"Your ad has been sent for review!\"). Send an `Idempotency-Key` so a retry never creates or charges twice.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `images`, `video` as file parts.","operationId":"MerchantAds_create","parameters":[{"name":"Idempotency-Key","in":"header","description":"A unique value per attempt (8–64 letters, digits, `-`, `_`), e.g. a UUID. Sending the same request again with the same key returns the first result and charges nothing more (a retry after a timeout); the same key with a different request is `IDEMPOTENCY_KEY_REUSED`.","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Up to 100 characters (BRD).","example":"عرض المشويات المشكلة لشخصين"},"description":{"type":"string","description":"Up to 500 characters; line breaks kept.","example":"مشويات مشكلة مع مقبلات وخبز طازج، العرض ساري حتى نهاية الشهر."},"price":{"type":"number","description":"SAR, at most two decimals.","example":50},"previousPrice":{"type":"number","description":"The price before the discount, SAR (D3); above `price`. The discount\npercent is computed.","example":60},"categoryId":{"type":"string","description":"The main category (`GET categories`)."},"subcategoryIds":{"description":"One or more of the main category's subcategories (D4); required when\nit has any. Multipart: repeat `subcategoryIds[]`.","maxItems":20,"type":"array","items":{"type":"string","format":"uuid"}},"cityId":{"type":"string","description":"`GET cities`."},"latitude":{"type":"number","description":"The map pin (BRD: the ad's location).","example":24.7136},"longitude":{"type":"number","example":46.6753},"address":{"type":"string","description":"The address line under the map; optional, up to 200 characters.","example":"حي العليا، طريق الملك فهد"},"contactMobile":{"type":"string","description":"The phone customers call (BRD: required, Saudi `05XXXXXXXX`).","example":"0551234567"},"contactEmail":{"type":"string","description":"Optional (Figma).","example":"store@example.com"},"expiresOn":{"type":"string","description":"The last day the ad runs, `YYYY-MM-DD` (Saudi calendar), today or\nlater; optional (BRD), 30 days by default (D14).","example":"2026-12-31"},"paymentMethod":{"type":"string","description":"How to pay the ad fee when there is no trial or subscription\n(`GET publish-gate` says `fee_required`): `wallet` or `gateway`.\nIgnored otherwise.","enum":["wallet","gateway"]},"images":{"type":"array","items":{"type":"string","format":"binary"},"maxItems":5,"description":"PNG, JPG, WEBP, up to 5 MB. Up to 5, repeat the part."},"video":{"type":"string","format":"binary","description":"MP4, MOV, up to 100 MB."}},"required":["title","description","price","categoryId","cityId","latitude","longitude","contactMobile"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdSavedDto"}}}},"400":{"description":"CATEGORY_NOT_AVAILABLE, CITY_NOT_AVAILABLE, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CATEGORY_NOT_AVAILABLE":{"value":{"code":"CATEGORY_NOT_AVAILABLE","message":"This category is not available. Please choose another category.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"CITY_NOT_AVAILABLE":{"value":{"code":"CITY_NOT_AVAILABLE","message":"This city is not available. Please choose another.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"402":{"description":"AD_FEE_REQUIRED, INSUFFICIENT_BALANCE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_FEE_REQUIRED":{"value":{"code":"AD_FEE_REQUIRED","message":"Publishing this ad costs {fee} SAR. Pay from your wallet or by card, or subscribe to a package.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"INSUFFICIENT_BALANCE":{"value":{"code":"INSUFFICIENT_BALANCE","message":"Your wallet balance is insufficient. Top up your wallet and try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"IDEMPOTENCY_KEY_REUSED":{"value":{"code":"IDEMPOTENCY_KEY_REUSED","message":"This Idempotency-Key was already used for a different request.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TOO_LARGE":{"value":{"code":"FILE_TOO_LARGE","message":"File size exceeds the allowed limit ({maxMb} MB).","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"415":{"description":"FILE_TYPE_NOT_ALLOWED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TYPE_NOT_ALLOWED":{"value":{"code":"FILE_TYPE_NOT_ALLOWED","message":"Unsupported file type. Allowed: {allowed}","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Create an ad","tags":["Merchant · Ads"],"security":[{"merchant":[]}]}},"/v1/merchant/ads/{id}":{"get":{"description":"The ad details screen (BRD): prices and discount, categories, status and expiry, images and video, the store’s contact, description, map location, the statistics cards (views, profile visits, call and WhatsApp clicks, shares, saves), and the `actions` its status allows. Another merchant’s or a deleted ad is `NOT_FOUND`.","operationId":"MerchantAds_detail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdDetailDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"One of my ads","tags":["Merchant · Ads"],"security":[{"merchant":[]}]},"patch":{"description":"As `multipart/form-data`, only the fields that change, with the create rules. Images: `imageFileIds[]` lists the images to keep (their `images[].id`), in order, and new `images` parts are added after them (1–5 in all); send neither to leave them. `videoFileId` sent empty removes the video; a `video` part replaces it. Changing the title, description, prices, categories or media sends the ad back to review (D1; `message` says so). Not for a disabled ad (`AD_STATUS_INVALID`). A refused edit saves nothing.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `images`, `video` as file parts.","operationId":"MerchantAds_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"title":{"type":"string","example":"عرض المشويات المشكلة لأربعة أشخاص"},"description":{"type":"string"},"price":{"type":"number","description":"SAR."},"previousPrice":{"type":"number","nullable":true,"description":"SAR; sent empty, removes the discount."},"categoryId":{"type":"string"},"subcategoryIds":{"description":"Replaces the subcategories; they must belong to the main category.","maxItems":20,"type":"array","items":{"type":"string","format":"uuid"}},"cityId":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"address":{"type":"string","nullable":true,"description":"Sent empty, removes it."},"contactMobile":{"type":"string"},"contactEmail":{"type":"string","nullable":true,"description":"Sent empty, removes it."},"expiresOn":{"type":"string","description":"`YYYY-MM-DD`, today or later."},"imageFileIds":{"description":"The current images to keep, in order (their ids; repeat `imageFileIds[]`). New `images` files are added after them; any not listed is removed. Leave both out to keep them as they are.","type":"array","items":{"type":"string","format":"uuid"}},"videoFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `video` file instead.","format":"uuid"},"images":{"type":"array","items":{"type":"string","format":"binary"},"maxItems":5,"description":"PNG, JPG, WEBP, up to 5 MB. Up to 5, repeat the part."},"video":{"type":"string","format":"binary","description":"MP4, MOV, up to 100 MB."}},"required":[]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdSavedDto"}}}},"400":{"description":"CATEGORY_NOT_AVAILABLE, CITY_NOT_AVAILABLE, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CATEGORY_NOT_AVAILABLE":{"value":{"code":"CATEGORY_NOT_AVAILABLE","message":"This category is not available. Please choose another category.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"CITY_NOT_AVAILABLE":{"value":{"code":"CITY_NOT_AVAILABLE","message":"This city is not available. Please choose another.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"AD_STATUS_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_STATUS_INVALID":{"value":{"code":"AD_STATUS_INVALID","message":"This can't be done to the ad in its current status.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"413":{"description":"FILE_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TOO_LARGE":{"value":{"code":"FILE_TOO_LARGE","message":"File size exceeds the allowed limit ({maxMb} MB).","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"415":{"description":"FILE_TYPE_NOT_ALLOWED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_TYPE_NOT_ALLOWED":{"value":{"code":"FILE_TYPE_NOT_ALLOWED","message":"Unsupported file type. Allowed: {allowed}","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit an ad","tags":["Merchant · Ads"],"security":[{"merchant":[]}]},"delete":{"description":"After the app’s confirmation (BRD). The ad disappears from every list and its images and video are deleted; it can’t be restored.","operationId":"MerchantAds_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"AD_STATUS_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_STATUS_INVALID":{"value":{"code":"AD_STATUS_INVALID","message":"This can't be done to the ad in its current status.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete an ad","tags":["Merchant · Ads"],"security":[{"merchant":[]}]}},"/v1/merchant/ads/{id}/repost":{"post":{"description":"The \"Repost ad\" button of an expired ad (`actions.canRepost`), with a new expiry day (30 days by default). Checked like creating (BRD): free in the trial or with a subscription, else the ad fee with `paymentMethod` (`AD_FEE_REQUIRED` without one). The ad goes back live, or to review if its content was edited while expired. Any other status is `AD_STATUS_INVALID`. Send an `Idempotency-Key` so a retry never pays twice.","operationId":"MerchantAds_repost","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","description":"A unique value per attempt (8–64 letters, digits, `-`, `_`), e.g. a UUID. Sending the same request again with the same key returns the first result and charges nothing more (a retry after a timeout); the same key with a different request is `IDEMPOTENCY_KEY_REUSED`.","required":false,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepostAdDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdSavedDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"402":{"description":"AD_FEE_REQUIRED, INSUFFICIENT_BALANCE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_FEE_REQUIRED":{"value":{"code":"AD_FEE_REQUIRED","message":"Publishing this ad costs {fee} SAR. Pay from your wallet or by card, or subscribe to a package.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"INSUFFICIENT_BALANCE":{"value":{"code":"INSUFFICIENT_BALANCE","message":"Your wallet balance is insufficient. Top up your wallet and try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"AD_STATUS_INVALID, IDEMPOTENCY_KEY_REUSED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_STATUS_INVALID":{"value":{"code":"AD_STATUS_INVALID","message":"This can't be done to the ad in its current status.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"IDEMPOTENCY_KEY_REUSED":{"value":{"code":"IDEMPOTENCY_KEY_REUSED","message":"This Idempotency-Key was already used for a different request.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Repost an expired ad","tags":["Merchant · Ads"],"security":[{"merchant":[]}]}},"/v1/merchant/home":{"get":{"description":"The header (name, store logo, unread notifications), the statistics cards summed over your ads (BRD: total ads, views, activity page visits, shares, saves), your 3 latest ads, and how publishing is covered (trial, subscription, or the fee).","operationId":"MerchantHome_home","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantHomeDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Home","tags":["Merchant · Home"],"security":[{"merchant":[]}]}},"/v1/admin/auth/login":{"post":{"description":"Logs in with mobile and password. After 5 failed attempts for a number (or 20 from one IP) within 15 minutes, logins answer `TOO_MANY_REQUESTS` until the window ends. A disabled admin gets `ACCOUNT_DISABLED`, only with the right password.","operationId":"AdminAuth_login","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLoginDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSessionDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"INVALID_CREDENTIALS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INVALID_CREDENTIALS":{"value":{"code":"INVALID_CREDENTIALS","message":"The username or password is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Log in","tags":["Admin · Auth"],"x-public":true,"x-session-token":{"namespace":"admin","field":"accessToken"},"security":[]}},"/v1/admin/auth/password/forgot":{"post":{"description":"Sends a 4-digit code by SMS to an active admin’s mobile (BRD: valid 3 minutes, the countdown) and answers its `verificationId`. Resend with `POST /auth/password/forgot/resend-otp` after `resendAfterSeconds`, which replaces the code. An unknown or disabled number gets `MOBILE_NOT_REGISTERED`.","operationId":"AdminAuth_forgotPassword","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"MOBILE_NOT_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_NOT_REGISTERED":{"value":{"code":"MOBILE_NOT_REGISTERED","message":"No account is registered with this number. Please make sure the mobile number is correct.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Send a password reset code","tags":["Admin · Auth"],"x-public":true,"security":[]}},"/v1/admin/auth/password/forgot/resend-otp":{"post":{"description":"Once `resendAfterSeconds` have passed: a new code for the `verificationId` from `password/forgot`, which stays the same.","operationId":"AdminAuth_resendResetCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerificationSentDto"}}}},"400":{"description":"VERIFICATION_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_RESEND_TOO_SOON, TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_RESEND_TOO_SOON":{"value":{"code":"OTP_RESEND_TOO_SOON","message":"You can request a new code in {seconds} seconds.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"503":{"description":"SMS_SEND_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SMS_SEND_FAILED":{"value":{"code":"SMS_SEND_FAILED","message":"The verification code could not be sent. Please try again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Resend the password reset code","tags":["Admin · Auth"],"x-public":true,"security":[]}},"/v1/admin/auth/password/forgot/verify":{"post":{"description":"The `verificationId` from `password/forgot` and the code. A right code returns a one-time `resetToken` for `POST /auth/password/reset`, valid for 10 minutes.","operationId":"AdminAuth_verifyResetCode","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyResetCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminResetTokenDto"}}}},"400":{"description":"VERIFICATION_INVALID, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VERIFICATION_INVALID":{"value":{"code":"VERIFICATION_INVALID","message":"This verification is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_INVALID":{"value":{"code":"OTP_INVALID","message":"The verification code is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"OTP_EXPIRED":{"value":{"code":"OTP_EXPIRED","message":"The verification code is invalid or expired. Please request a new one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"MOBILE_NOT_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_NOT_REGISTERED":{"value":{"code":"MOBILE_NOT_REGISTERED","message":"No account is registered with this number. Please make sure the mobile number is correct.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"OTP_TOO_MANY_ATTEMPTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"OTP_TOO_MANY_ATTEMPTS":{"value":{"code":"OTP_TOO_MANY_ATTEMPTS","message":"Too many incorrect attempts. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Check a password reset code","tags":["Admin · Auth"],"x-public":true,"security":[]}},"/v1/admin/auth/password/reset":{"post":{"description":"Uses the `resetToken` from a verified code, once. Every session of the admin is signed out; the dashboard shows \"Password changed successfully.\" and returns to login.","operationId":"AdminAuth_resetPassword","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminResetPasswordDto"}}}},"responses":{"204":{"description":"The password was changed."},"400":{"description":"RESET_TOKEN_INVALID, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"RESET_TOKEN_INVALID":{"value":{"code":"RESET_TOKEN_INVALID","message":"This password reset link is no longer valid. Please request a new code.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Set a new password","tags":["Admin · Auth"],"x-public":true,"security":[]}},"/v1/admin/auth/me":{"get":{"description":"The signed-in admin with their role and permissions, for building the dashboard menu.","operationId":"AdminAuth_me","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Current admin","tags":["Admin · Auth"],"security":[{"admin":[]}]}},"/v1/admin/auth/permissions":{"get":{"description":"Every permission a role can grant, grouped by control panel area, with labels in the request language.","operationId":"AdminAuth_permissions","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionCatalogueDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Permission catalogue","tags":["Admin · Auth"],"security":[{"admin":[]}]}},"/v1/admin/auth/logout":{"post":{"description":"Ends the session of the token sent; it stops working immediately. Other devices stay signed in.","operationId":"AdminSession_logout","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"Logged out."},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Log out","tags":["Admin · Auth"],"security":[{"admin":[]}]}},"/v1/admin/profile":{"get":{"description":"The same as `GET auth/me`; the role is read-only.","operationId":"Profile_get","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Your profile","tags":["Admin · Profile"],"security":[{"admin":[]}]},"patch":{"description":"Send only what changed. Changing `mobile` (your login) or `email` needs `currentPassword`; a new mobile signs out your other devices. After 5 wrong passwords in 15 minutes, `TOO_MANY_REQUESTS`. The answer is in the saved language.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `avatar` as file parts.","operationId":"Profile_update","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"سارة العتيبي"},"email":{"type":"string","description":"Needs `currentPassword`.","example":"sara@mashhour.sa","maxLength":100,"format":"email"},"mobile":{"type":"string","description":"Your login number; needs `currentPassword`, and signs out your other\ndevices.","example":"0551234567"},"currentPassword":{"type":"string","description":"Required when the `mobile` or `email` sent differs from the saved one\n(the form can resend unchanged values without it).","maxLength":100},"avatarFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `avatar` file instead."},"language":{"type":"string","description":"The control panel's language.","example":"en","enum":["ar","en"]},"avatar":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."}},"required":[]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"400":{"description":"PASSWORD_INCORRECT, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PASSWORD_INCORRECT":{"value":{"code":"PASSWORD_INCORRECT","message":"The current password is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, EMAIL_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit your profile or language","tags":["Admin · Profile"],"security":[{"admin":[]}]}},"/v1/admin/profile/change-password":{"post":{"description":"With the current password (BRD). Signs out your other devices; this one stays signed in.","operationId":"Profile_changePassword","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminChangePasswordDto"}}}},"responses":{"204":{"description":"The password was changed."},"400":{"description":"PASSWORD_INCORRECT, PASSWORD_UNCHANGED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PASSWORD_INCORRECT":{"value":{"code":"PASSWORD_INCORRECT","message":"The current password is incorrect.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"PASSWORD_UNCHANGED":{"value":{"code":"PASSWORD_UNCHANGED","message":"The new password must be different from the current one.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"429":{"description":"TOO_MANY_REQUESTS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"TOO_MANY_REQUESTS":{"value":{"code":"TOO_MANY_REQUESTS","message":"Too many requests, please try again shortly","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Change your password","tags":["Admin · Profile"],"security":[{"admin":[]}]}},"/v1/admin/audit":{"get":{"description":"Who changed what in the control panel, newest first. Filter by admin, record (`entityType` + `entityId` for one record’s history), action and days.\n\n**Permission:** `audit.view`.","operationId":"AdminAudit_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"adminId","required":false,"in":"query","description":"Only this admin's actions.","schema":{"format":"uuid","type":"string"}},{"name":"entityType","required":false,"in":"query","description":"`role`, `admin`, `customer`, `advertiser`, …","schema":{"maxLength":30,"example":"role","type":"string"}},{"name":"entityId","required":false,"in":"query","description":"One record's history (with `entityType`): its id, or a setting's key.","schema":{"maxLength":64,"example":"boost_enabled","type":"string"}},{"name":"action","required":false,"in":"query","description":"An exact action, e.g. `advertiser.deactivate`.","schema":{"maxLength":50,"example":"role.update","type":"string"}},{"name":"from","required":false,"in":"query","description":"From this day (`YYYY-MM-DD`, UTC), inclusive.","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-10-01","type":"string"}},{"name":"to","required":false,"in":"query","description":"To this day (`YYYY-MM-DD`, UTC), inclusive.","schema":{"pattern":"^\\d{4}-\\d{2}-\\d{2}$","example":"2026-10-31","type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Audit trail","tags":["Admin · Audit"],"security":[{"admin":[]}]}},"/v1/admin/roles":{"get":{"description":"Pages of roles, the Super Admin role first, then newest. `q` searches both names.\n\n**Permission:** `roles.view`.","operationId":"Roles_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Only roles with this status.","schema":{"type":"string","enum":["active","disabled"]}},{"name":"q","required":false,"in":"query","description":"Text to look for (case-insensitive).","schema":{"maxLength":100,"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolePageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search roles","tags":["Admin · Roles"],"security":[{"admin":[]}]},"post":{"description":"Permissions come from `GET /v1/admin/auth/permissions`. Only super admins can grant permissions they don’t have themselves.\n\n**Permission:** `roles.create`.","operationId":"Roles_create","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"FORBIDDEN, ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"ROLE_NAME_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ROLE_NAME_TAKEN":{"value":{"code":"ROLE_NAME_TAKEN","message":"A role with this name already exists. Please enter another name.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Add a role","tags":["Admin · Roles"],"security":[{"admin":[]}]}},"/v1/admin/roles/{id}":{"get":{"operationId":"Roles_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View a role","tags":["Admin · Roles"],"security":[{"admin":[]}],"description":"**Permission:** `roles.view`."},"patch":{"description":"Its admins get the new permissions on their next request, and their open dashboards receive `permissions.changed`. The Super Admin role and your own role can’t be edited.\n\n**Permission:** `roles.update`.","operationId":"Roles_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoleDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SELF_CHANGE_NOT_ALLOWED, FORBIDDEN, ACCOUNT_DISABLED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"ROLE_NAME_TAKEN, SYSTEM_ROLE_LOCKED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ROLE_NAME_TAKEN":{"value":{"code":"ROLE_NAME_TAKEN","message":"A role with this name already exists. Please enter another name.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SYSTEM_ROLE_LOCKED":{"value":{"code":"SYSTEM_ROLE_LOCKED","message":"The Super Admin role can’t be changed.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit a role","tags":["Admin · Roles"],"security":[{"admin":[]}]},"delete":{"description":"Refused while admins have it (`ROLE_IN_USE`): move them to another role first.\n\n**Permission:** `roles.delete`.","operationId":"Roles_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"The role was deleted."},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SELF_CHANGE_NOT_ALLOWED, ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"ROLE_IN_USE, SYSTEM_ROLE_LOCKED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ROLE_IN_USE":{"value":{"code":"ROLE_IN_USE","message":"The role cannot be deleted because it is associated with a system administrator.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SYSTEM_ROLE_LOCKED":{"value":{"code":"SYSTEM_ROLE_LOCKED","message":"The Super Admin role can’t be changed.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete a role","tags":["Admin · Roles"],"security":[{"admin":[]}]}},"/v1/admin/roles/{id}/activate":{"post":{"description":"Its admins get its permissions again on their next request.\n\n**Permission:** `roles.status`.","operationId":"Roles_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SELF_CHANGE_NOT_ALLOWED, ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"SYSTEM_ROLE_LOCKED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SYSTEM_ROLE_LOCKED":{"value":{"code":"SYSTEM_ROLE_LOCKED","message":"The Super Admin role can’t be changed.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Activate a role","tags":["Admin · Roles"],"security":[{"admin":[]}]}},"/v1/admin/roles/{id}/deactivate":{"post":{"description":"A deactivated role grants nothing to its admins (`adminCount` says how many), from their next request, and can’t be given to admins.\n\n**Permission:** `roles.status`.","operationId":"Roles_deactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SELF_CHANGE_NOT_ALLOWED, ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"SYSTEM_ROLE_LOCKED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SYSTEM_ROLE_LOCKED":{"value":{"code":"SYSTEM_ROLE_LOCKED","message":"The Super Admin role can’t be changed.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Deactivate a role","tags":["Admin · Roles"],"security":[{"admin":[]}]}},"/v1/admin/admins":{"get":{"description":"Newest first. Filters by part of the name, email or mobile (as typed, `055…`), status and role.\n\n**Permission:** `admins.view`.","operationId":"Admins_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"name","required":false,"in":"query","description":"Part of the name.","schema":{"maxLength":100,"type":"string"}},{"name":"email","required":false,"in":"query","description":"Part of the email.","schema":{"maxLength":100,"type":"string"}},{"name":"mobile","required":false,"in":"query","description":"Part of the mobile, as typed (`055…`).","schema":{"maxLength":10,"example":"0551","type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["active","disabled"]}},{"name":"roleId","required":false,"in":"query","description":"Only admins with this role.","schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search admins","tags":["Admin · Admins"],"security":[{"admin":[]}]},"post":{"description":"The admin logs in with the mobile and password. They are emailed that the account exists (without the password).\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `avatar` as file parts.\n\n**Permission:** `admins.create`.","operationId":"Admins_create","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Letters and numbers, 2–100 characters.","example":"سارة العتيبي"},"email":{"type":"string","description":"Unique; notices are sent here.","example":"sara@maqsed.sa","maxLength":100,"format":"email"},"mobile":{"type":"string","description":"Saudi mobile, unique; the admin logs in with it.","example":"0551234567"},"password":{"type":"string","description":"8–25 characters with an uppercase letter, a lowercase letter, a number\nand a symbol, no spaces.","example":"Maqsed@2026"},"passwordConfirmation":{"type":"string","example":"Maqsed@2026"},"roleId":{"type":"string","description":"An active role from `GET /v1/admin/roles`, not the Super Admin."},"status":{"type":"string","description":"`disabled` creates the account without letting it log in yet.","example":"active","enum":["active","disabled"]},"avatar":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."}},"required":["name","email","mobile","password","passwordConfirmation","roleId"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"400":{"description":"ROLE_NOT_AVAILABLE, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ROLE_NOT_AVAILABLE":{"value":{"code":"ROLE_NOT_AVAILABLE","message":"This role is not available. Please choose another role.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, EMAIL_ALREADY_REGISTERED, SUPER_ADMIN_ROLE_RESERVED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SUPER_ADMIN_ROLE_RESERVED":{"value":{"code":"SUPER_ADMIN_ROLE_RESERVED","message":"The Super Admin role can’t be given to another administrator.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Add an admin","tags":["Admin · Admins"],"security":[{"admin":[]}]}},"/v1/admin/admins/{id}":{"get":{"description":"With the login count and last login (BRD).\n\n**Permission:** `admins.view`.","operationId":"Admins_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View an admin","tags":["Admin · Admins"],"security":[{"admin":[]}]},"patch":{"description":"Send only what changed. A new role applies on their next request (`permissions.changed` to their dashboard); a new password or mobile signs them out. Only the super admin edits the super admin, and nobody changes their own role.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `avatar` as file parts.\n\n**Permission:** `admins.update`.","operationId":"Admins_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"name":{"type":"string","example":"سارة العتيبي"},"email":{"type":"string","example":"sara@maqsed.sa","maxLength":100,"format":"email"},"mobile":{"type":"string","description":"Their login number; changing it signs them out.","example":"0551234567"},"password":{"type":"string","description":"Changing it signs them out everywhere."},"passwordConfirmation":{"type":"string"},"roleId":{"type":"string","description":"Their permissions change on their next request."},"avatarFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `avatar` file instead."},"avatar":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 10 MB."}},"required":[]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"400":{"description":"ROLE_NOT_AVAILABLE, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ROLE_NOT_AVAILABLE":{"value":{"code":"ROLE_NOT_AVAILABLE","message":"This role is not available. Please choose another role.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SUPER_ADMIN_PROTECTED, SELF_CHANGE_NOT_ALLOWED, ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SUPER_ADMIN_PROTECTED":{"value":{"code":"SUPER_ADMIN_PROTECTED","message":"Super Admin accounts can’t be changed by other administrators.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, EMAIL_ALREADY_REGISTERED, SUPER_ADMIN_ROLE_RESERVED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SUPER_ADMIN_ROLE_RESERVED":{"value":{"code":"SUPER_ADMIN_ROLE_RESERVED","message":"The Super Admin role can’t be given to another administrator.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit an admin","tags":["Admin · Admins"],"security":[{"admin":[]}]},"delete":{"description":"Signs them out, frees their mobile and email, and emails them. The super admin and your own account can’t be deleted.\n\n**Permission:** `admins.delete`.","operationId":"Admins_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"The admin was deleted."},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SUPER_ADMIN_PROTECTED, SELF_CHANGE_NOT_ALLOWED, ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SUPER_ADMIN_PROTECTED":{"value":{"code":"SUPER_ADMIN_PROTECTED","message":"Super Admin accounts can’t be changed by other administrators.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete an admin","tags":["Admin · Admins"],"security":[{"admin":[]}]}},"/v1/admin/admins/{id}/activate":{"post":{"description":"They can log in again; they are emailed.\n\n**Permission:** `admins.status`.","operationId":"Admins_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SUPER_ADMIN_PROTECTED, SELF_CHANGE_NOT_ALLOWED, ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SUPER_ADMIN_PROTECTED":{"value":{"code":"SUPER_ADMIN_PROTECTED","message":"Super Admin accounts can’t be changed by other administrators.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Activate an admin","tags":["Admin · Admins"],"security":[{"admin":[]}]}},"/v1/admin/admins/{id}/deactivate":{"post":{"description":"Needs a `reason` (3–250, BRD); signs them out at once and emails them the reason.\n\n**Permission:** `admins.status`.","operationId":"Admins_deactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"SUPER_ADMIN_PROTECTED, SELF_CHANGE_NOT_ALLOWED, ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"SUPER_ADMIN_PROTECTED":{"value":{"code":"SUPER_ADMIN_PROTECTED","message":"Super Admin accounts can’t be changed by other administrators.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"SELF_CHANGE_NOT_ALLOWED":{"value":{"code":"SELF_CHANGE_NOT_ALLOWED","message":"You can’t change your own role or account.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Deactivate an admin","tags":["Admin · Admins"],"security":[{"admin":[]}]}},"/v1/admin/customers":{"get":{"description":"Newest first (join date). Filters by part of the name, mobile (as typed, `055…`) or email, and status. Deleted accounts are not listed.\n\n**Permission:** `customers.view`.","operationId":"AdminCustomers_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"name","required":false,"in":"query","description":"Part of the name.","schema":{"maxLength":100,"type":"string"}},{"name":"mobile","required":false,"in":"query","description":"Part of the mobile, as typed (`055…`).","schema":{"maxLength":10,"example":"0551","type":"string"}},{"name":"email","required":false,"in":"query","description":"Part of the email.","schema":{"maxLength":100,"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["active","disabled"]}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomerPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search customers","tags":["Admin · Customers"],"security":[{"admin":[]}]}},"/v1/admin/customers/{id}":{"get":{"description":"With their favorites, reports and chats counted.\n\n**Permission:** `customers.view`.","operationId":"AdminCustomers_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomerDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View a customer","tags":["Admin · Customers"],"security":[{"admin":[]}]},"patch":{"description":"Send only what changed; `null` clears an optional field. A new mobile is their login, so it signs them out.\n\n**Permission:** `customers.update`.","operationId":"AdminCustomers_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateCustomerDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomerDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, EMAIL_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MOBILE_ALREADY_REGISTERED":{"value":{"code":"MOBILE_ALREADY_REGISTERED","message":"The mobile number is already registered, please check the number.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit a customer","tags":["Admin · Customers"],"security":[{"admin":[]}]}},"/v1/admin/customers/{id}/activate":{"post":{"description":"After the confirmation (BRD): they can log in to the app again, and are emailed when they have an email.\n\n**Permission:** `customers.status`.","operationId":"AdminCustomers_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomerDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Activate a customer","tags":["Admin · Customers"],"security":[{"admin":[]}]}},"/v1/admin/customers/{id}/deactivate":{"post":{"description":"Needs a `reason` (3–250, letters and numbers, BRD); signs them out of the app at once and emails them the reason when they have an email.\n\n**Permission:** `customers.status`.","operationId":"AdminCustomers_deactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomerDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Deactivate a customer","tags":["Admin · Customers"],"security":[{"admin":[]}]}},"/v1/admin/merchants":{"get":{"description":"Newest first unless `sort`/`order` say otherwise. `reviewStatus=under_review` lists the joining requests; `counts` has each review status (with the other filters) for the menu badge. Sign-ups whose mobile isn’t verified and deleted accounts are not listed.\n\n**Permission:** `merchants.view`.","operationId":"AdminMerchants_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Part of the name, store name, mobile (as typed, `055…`) or email.","schema":{"maxLength":100,"type":"string"}},{"name":"reviewStatus","required":false,"in":"query","schema":{"type":"string","enum":["under_review","approved","rejected"]}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["active","disabled"]}},{"name":"sort","required":false,"in":"query","description":"Default `createdAt` (the registration date).","schema":{"type":"string","enum":["name","createdAt","reviewStatus"]}},{"name":"order","required":false,"in":"query","description":"Default `desc`.","schema":{"type":"string","enum":["asc","desc"]}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMerchantPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search service providers","tags":["Admin · Merchants"],"security":[{"admin":[]}]}},"/v1/admin/merchants/{id}":{"get":{"description":"Everything from registration, the CR image and work document as signed links, the trial and subscription, and the ads count.\n\n**Permission:** `merchants.view`.","operationId":"AdminMerchants_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMerchantDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View a service provider","tags":["Admin · Merchants"],"security":[{"admin":[]}]},"patch":{"description":"Send only what changed: name, store name, email, CR number (the profile’s rules). A CR number or a work document must remain.\n\n**Permission:** `merchants.update`.","operationId":"AdminMerchants_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpdateMerchantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMerchantDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"EMAIL_ALREADY_REGISTERED, CR_ALREADY_REGISTERED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"EMAIL_ALREADY_REGISTERED":{"value":{"code":"EMAIL_ALREADY_REGISTERED","message":"The email address is already registered.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"CR_ALREADY_REGISTERED":{"value":{"code":"CR_ALREADY_REGISTERED","message":"The commercial registration number is already in use.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit a service provider","tags":["Admin · Merchants"],"security":[{"admin":[]}]}},"/v1/admin/merchants/{id}/approve":{"post":{"description":"Under review only. The merchant can log in, the free trial starts while seats remain, and they get an SMS and a notification.\n\n**Permission:** `merchants.update`.","operationId":"AdminMerchants_approve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMerchantDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MERCHANT_REVIEW_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_REVIEW_INVALID":{"value":{"code":"MERCHANT_REVIEW_INVALID","message":"This request has already been reviewed.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Approve a joining request","tags":["Admin · Merchants"],"security":[{"admin":[]}]}},"/v1/admin/merchants/{id}/reject":{"post":{"description":"Under review only, with a `reason` (3–250) the merchant sees at login and in a notification. They may apply again.\n\n**Permission:** `merchants.update`.","operationId":"AdminMerchants_reject","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectMerchantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMerchantDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MERCHANT_REVIEW_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"MERCHANT_REVIEW_INVALID":{"value":{"code":"MERCHANT_REVIEW_INVALID","message":"This request has already been reviewed.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Reject a joining request","tags":["Admin · Merchants"],"security":[{"admin":[]}]}},"/v1/admin/merchants/{id}/activate":{"post":{"description":"They can log in again and their ads are shown to customers again; they are emailed.\n\n**Permission:** `merchants.status`.","operationId":"AdminMerchants_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMerchantDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Activate a service provider","tags":["Admin · Merchants"],"security":[{"admin":[]}]}},"/v1/admin/merchants/{id}/deactivate":{"post":{"description":"Needs a `reason` (3–250). Signs them out at once, hides their ads from customers, and emails them the reason.\n\n**Permission:** `merchants.status`.","operationId":"AdminMerchants_deactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeactivateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminMerchantDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Deactivate a service provider","tags":["Admin · Merchants"],"security":[{"admin":[]}]}},"/v1/admin/ads":{"get":{"description":"Newest first. Filters by part of the title, main category, status (`pending_review` is the review queue; an active ad past its date is `expired`) and merchant. `totals` are the BRD’s cards: all ads and per category, with every filter but the category.\n\n**Permission:** `ads.view`.","operationId":"AdminAds_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Part of the title.","schema":{"maxLength":100,"type":"string"}},{"name":"categoryId","required":false,"in":"query","description":"The main category (a totals chip).","schema":{"format":"uuid","type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["active","disabled","rejected","pending_review","expired"]}},{"name":"merchantId","required":false,"in":"query","schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search ads","tags":["Admin · Ads"],"security":[{"admin":[]}]}},"/v1/admin/ads/{id}":{"get":{"description":"All its data, images and video, the merchant’s contact, the open reports, what can be done now (`adminActions`) and its history.\n\n**Permission:** `ads.view`.","operationId":"AdminAds_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View an ad","tags":["Admin · Ads"],"security":[{"admin":[]}]},"delete":{"description":"After the confirmation (BRD): gone for the merchant and customers, out of favorites, its media deleted; statistics follow at once. The body is optional (`reason`, `closeReports`).\n\n**Permission:** `ads.delete`.","operationId":"AdminAds_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdActionDto"}}}},"responses":{"204":{"description":""},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete an ad","tags":["Admin · Ads"],"security":[{"admin":[]}]}},"/v1/admin/ads/{id}/approve":{"post":{"description":"From the review queue: it goes live (or expired, if its date passed while waiting); the merchant is notified.\n\n**Permission:** `ads.update`.","operationId":"AdminAds_approve","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"AD_STATUS_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_STATUS_INVALID":{"value":{"code":"AD_STATUS_INVALID","message":"This can't be done to the ad in its current status.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Approve an ad","tags":["Admin · Ads"],"security":[{"admin":[]}]}},"/v1/admin/ads/{id}/reject":{"post":{"description":"From the review queue, with a `reason` (3–500) the merchant sees on the ad and in a notification; they can edit it and send it again.\n\n**Permission:** `ads.update`.","operationId":"AdminAds_reject","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectAdDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"AD_STATUS_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_STATUS_INVALID":{"value":{"code":"AD_STATUS_INVALID","message":"This can't be done to the ad in its current status.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Reject an ad","tags":["Admin · Ads"],"security":[{"admin":[]}]}},"/v1/admin/ads/{id}/disable":{"post":{"description":"From the queue, live or expired: hidden from customers at once, the merchant notified (with the `reason` when given). `closeReports: true` marks its open reports reviewed.\n\n**Permission:** `ads.update`.","operationId":"AdminAds_disable","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdActionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"AD_STATUS_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_STATUS_INVALID":{"value":{"code":"AD_STATUS_INVALID","message":"This can't be done to the ad in its current status.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Disable an ad","tags":["Admin · Ads"],"security":[{"admin":[]}]}},"/v1/admin/ads/{id}/enable":{"post":{"description":"A disabled ad goes live again (or expired, if its date passed meanwhile).\n\n**Permission:** `ads.update`.","operationId":"AdminAds_enable","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminAdDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"AD_STATUS_INVALID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"AD_STATUS_INVALID":{"value":{"code":"AD_STATUS_INVALID","message":"This can't be done to the ad in its current status.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Enable an ad","tags":["Admin · Ads"],"security":[{"admin":[]}]}},"/v1/admin/categories":{"get":{"description":"Inactive ones included, in display order, by part of the Arabic or English name and status, with their ads and subcategories counted.\n\n**Permission:** `categories.view`.","operationId":"AdminCategories_mains","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Part of the name, Arabic or English.","schema":{"maxLength":100,"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["active","inactive"]}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search main categories","tags":["Admin · Categories"],"security":[{"admin":[]}]},"post":{"description":"Sent as `multipart/form-data`, the picture as the `image` part. Without `parentId` it is a main category; with it, a subcategory of that active main category. Added last among its siblings, active.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `image` as file parts.\n\n**Permission:** `categories.create`.","operationId":"AdminCategories_create","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"parentId":{"type":"string","description":"The main category, for a subcategory.","format":"uuid"},"nameAr":{"type":"string","description":"Unique among its siblings.","example":"مطاعم"},"nameEn":{"type":"string","description":"Unique among its siblings.","example":"Restaurants"},"descriptionAr":{"type":"string","nullable":true,"description":"The line under the name on the home cards.","maxLength":250},"descriptionEn":{"type":"string","nullable":true,"maxLength":250},"image":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 5 MB."}},"required":["nameAr","nameEn"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryDto"}}}},"400":{"description":"CATEGORY_NOT_AVAILABLE, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CATEGORY_NOT_AVAILABLE":{"value":{"code":"CATEGORY_NOT_AVAILABLE","message":"This category is not available. Please choose another category.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"CATEGORY_NAME_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CATEGORY_NAME_TAKEN":{"value":{"code":"CATEGORY_NAME_TAKEN","message":"A category with this name already exists. Please enter a different name.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Add a category or subcategory","tags":["Admin · Categories"],"security":[{"admin":[]}]}},"/v1/admin/categories/subcategories":{"get":{"description":"By part of the name, status and main category (`parentId`); each with its main category.\n\n**Permission:** `categories.view`.","operationId":"AdminCategories_subcategories","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Part of the name, Arabic or English.","schema":{"maxLength":100,"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["active","inactive"]}},{"name":"parentId","required":false,"in":"query","description":"Only this main category's subcategories.","schema":{"format":"uuid","type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search subcategories","tags":["Admin · Categories"],"security":[{"admin":[]}]}},"/v1/admin/categories/{id}":{"get":{"description":"With its subcategories, for a main category.\n\n**Permission:** `categories.view`.","operationId":"AdminCategories_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View a category","tags":["Admin · Categories"],"security":[{"admin":[]}]},"patch":{"description":"Multipart; send only what changed. `imageFileId` or a description sent empty removes it. A subcategory may move to another active main category.\n\n**Files with the form:** send it as `multipart/form-data` (fields as text; lists and objects in brackets, e.g. `specifications[0][name]`) with `image` as file parts.\n\n**Permission:** `categories.update`.","operationId":"AdminCategories_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"parentId":{"type":"string","description":"A subcategory's new main category (active).","format":"uuid"},"nameAr":{"type":"string"},"nameEn":{"type":"string"},"descriptionAr":{"type":"string","nullable":true,"maxLength":250},"descriptionEn":{"type":"string","nullable":true,"maxLength":250},"imageFileId":{"type":"string","nullable":true,"description":"Leave out to keep the current file; send it empty to remove it. To replace it, send the `image` file instead."},"image":{"type":"string","format":"binary","description":"PNG, JPG, WEBP, up to 5 MB."}},"required":[]}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryDto"}}}},"400":{"description":"CATEGORY_NOT_AVAILABLE, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CATEGORY_NOT_AVAILABLE":{"value":{"code":"CATEGORY_NOT_AVAILABLE","message":"This category is not available. Please choose another category.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FILE_NOT_AVAILABLE":{"value":{"code":"FILE_NOT_AVAILABLE","message":"This file can't be used. Please upload it again.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"CATEGORY_NAME_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CATEGORY_NAME_TAKEN":{"value":{"code":"CATEGORY_NAME_TAKEN","message":"A category with this name already exists. Please enter a different name.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit a category","tags":["Admin · Categories"],"security":[{"admin":[]}]},"delete":{"description":"After the confirmation (BRD). Only when no ad uses it or its subcategories, deleted ads included; otherwise `CATEGORY_HAS_ADS`: deactivate it instead. A main category goes with its subcategories.\n\n**Permission:** `categories.delete`.","operationId":"AdminCategories_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"The category was deleted."},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"CATEGORY_HAS_ADS","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CATEGORY_HAS_ADS":{"value":{"code":"CATEGORY_HAS_ADS","message":"This category has ads, so it cannot be deleted. Deactivate it instead.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete a category","tags":["Admin · Categories"],"security":[{"admin":[]}]}},"/v1/admin/categories/reorder":{"post":{"description":"Every subcategory of `parentId` (`null`: the main categories), in the new order the apps show.\n\n**Permission:** `categories.update`.","operationId":"AdminCategories_reorder","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderCategoriesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Reorder categories","tags":["Admin · Categories"],"security":[{"admin":[]}]}},"/v1/admin/categories/{id}/activate":{"post":{"description":"It can be chosen for new ads again, and a main category’s ads are shown again.\n\n**Permission:** `categories.status`.","operationId":"AdminCategories_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Activate a category","tags":["Admin · Categories"],"security":[{"admin":[]}]}},"/v1/admin/categories/{id}/deactivate":{"post":{"description":"It can’t be chosen for new ads. A main category hides its subcategories and its ads; a subcategory’s ads stay shown through their main category.\n\n**Permission:** `categories.status`.","operationId":"AdminCategories_deactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCategoryDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Deactivate a category","tags":["Admin · Categories"],"security":[{"admin":[]}]}},"/v1/admin/packages":{"get":{"description":"Inactive ones included, in display order, by part of the name and status, with their running subscriptions counted.\n\n**Permission:** `packages.view`.","operationId":"AdminPackages_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"q","required":false,"in":"query","description":"Part of the name, Arabic or English.","schema":{"maxLength":100,"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["active","inactive"]}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPackagePageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search packages","tags":["Admin · Packages"],"security":[{"admin":[]}]},"post":{"description":"Active unless `active: false` (BRD). The name must not be another active package’s.\n\n**Permission:** `packages.create`.","operationId":"AdminPackages_create","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePackageDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPackageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"PACKAGE_NAME_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PACKAGE_NAME_TAKEN":{"value":{"code":"PACKAGE_NAME_TAKEN","message":"An active package already has this name. Please enter a different name.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Add a package","tags":["Admin · Packages"],"security":[{"admin":[]}]}},"/v1/admin/packages/{id}":{"get":{"operationId":"AdminPackages_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPackageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View a package","tags":["Admin · Packages"],"security":[{"admin":[]}],"description":"**Permission:** `packages.view`."},"patch":{"description":"Send only what changed. Running subscriptions keep what they bought; the change applies to new ones.\n\n**Permission:** `packages.update`.","operationId":"AdminPackages_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePackageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPackageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"PACKAGE_NAME_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PACKAGE_NAME_TAKEN":{"value":{"code":"PACKAGE_NAME_TAKEN","message":"An active package already has this name. Please enter a different name.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Edit a package","tags":["Admin · Packages"],"security":[{"admin":[]}]},"delete":{"description":"After the confirmation (BRD). Only a package nobody bought; otherwise `PACKAGE_IN_USE`: deactivate it instead.\n\n**Permission:** `packages.delete`.","operationId":"AdminPackages_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"204":{"description":"The package was deleted."},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"PACKAGE_IN_USE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PACKAGE_IN_USE":{"value":{"code":"PACKAGE_IN_USE","message":"Merchants have subscribed to this package, so it cannot be deleted. Deactivate it instead.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Delete a package","tags":["Admin · Packages"],"security":[{"admin":[]}]}},"/v1/admin/packages/reorder":{"post":{"description":"Every package, in the order merchants see them.\n\n**Permission:** `packages.update`.","operationId":"AdminPackages_reorder","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReorderPackagesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPackagePageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Reorder packages","tags":["Admin · Packages"],"security":[{"admin":[]}]}},"/v1/admin/packages/{id}/activate":{"post":{"description":"Merchants can subscribe to it again. No past subscription is restarted (BRD).\n\n**Permission:** `packages.status`.","operationId":"AdminPackages_activate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPackageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"PACKAGE_NAME_TAKEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"PACKAGE_NAME_TAKEN":{"value":{"code":"PACKAGE_NAME_TAKEN","message":"An active package already has this name. Please enter a different name.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Activate a package","tags":["Admin · Packages"],"security":[{"admin":[]}]}},"/v1/admin/packages/{id}/deactivate":{"post":{"description":"Hidden from merchants for new subscriptions; running ones continue to their end (BRD).\n\n**Permission:** `packages.status`.","operationId":"AdminPackages_deactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPackageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Deactivate a package","tags":["Admin · Packages"],"security":[{"admin":[]}]}},"/v1/admin/settings":{"get":{"description":"The values that apply now (defaults until saved), with when and by whom each was last saved.\n\n**Permission:** `settings.view`.","operationId":"AdminSettings_get","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSettingsDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"The general settings","tags":["Admin · Settings"],"security":[{"admin":[]}]},"patch":{"description":"Only the fields sent change; each applies from the next request (the next ad pays the new fee; a granted trial keeps its dates). Store links show in the apps at once.\n\n**Permission:** `settings.update`.","operationId":"AdminSettings_update","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSettingsDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Save general settings","tags":["Admin · Settings"],"security":[{"admin":[]}]}},"/v1/admin/content/pages":{"get":{"description":"About, Terms and Privacy, with when and by whom saved.\n\n**Permission:** `content.view`.","operationId":"AdminContent_list","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminContentPageSummaryDto"}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"The pages","tags":["Admin · Content"],"security":[{"admin":[]}]}},"/v1/admin/content/pages/{key}":{"get":{"operationId":"AdminContent_get","parameters":[{"name":"key","required":true,"in":"path","schema":{"enum":["about","terms","privacy"],"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminContentPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"A page, in both languages","tags":["Admin · Content"],"security":[{"admin":[]}],"description":"**Permission:** `content.view`."},"put":{"description":"Rich text (HTML) in both languages, both required (BRD: \"Text must be entered\"). Scripts, images and other markup are removed. The apps show it on the next request.\n\n**Permission:** `content.update`.","operationId":"AdminContent_save","parameters":[{"name":"key","required":true,"in":"path","schema":{"enum":["about","terms","privacy"],"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavePageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminContentPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Save a page","tags":["Admin · Content"],"security":[{"admin":[]}]}},"/v1/admin/content/contact-channels":{"get":{"operationId":"AdminContent_contactChannels","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminContactChannelsDto"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"The Contact Us channels","tags":["Admin · Content"],"security":[{"admin":[]}],"description":"**Permission:** `content.view`."},"put":{"description":"The whole set (BRD 4.3.10.1.1): contact mobiles and WhatsApp as `05…`, an email, and links on each platform’s own site. A channel sent empty or left out is hidden in the apps.\n\n**Permission:** `content.update`.","operationId":"AdminContent_saveContactChannels","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveContactChannelsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminContactChannelsDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Save the Contact Us channels","tags":["Admin · Content"],"security":[{"admin":[]}]}},"/v1/admin/contact/messages":{"get":{"description":"Newest first (BRD). By part of the name, mobile (as typed) or email, kind, type, status and sender. `counts.notReplied` is the menu badge.\n\n**Permission:** `contact.view`.","operationId":"AdminContact_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"name","required":false,"in":"query","description":"Part of the sender's name.","schema":{"maxLength":100,"type":"string"}},{"name":"mobile","required":false,"in":"query","description":"Part of the mobile, as typed (`055…`).","schema":{"maxLength":10,"example":"0551","type":"string"}},{"name":"email","required":false,"in":"query","description":"Part of the email.","schema":{"maxLength":100,"type":"string"}},{"name":"kind","required":false,"in":"query","schema":{"type":"string","enum":["message","complaint"]}},{"name":"type","required":false,"in":"query","description":"A message type (BRD: request, suggestion, inquiry, complaint, other) or a complaint type.","schema":{"type":"string","enum":["merchant","app","complaint","ad","payment","request","suggestion","inquiry","other"]}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["not_replied","replied"]}},{"name":"senderType","required":false,"in":"query","description":"Who sent it; `guest` is a sender without an account.","schema":{"type":"string","enum":["customer","merchant","guest"]}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminContactMessagePageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Search contact messages","tags":["Admin · Contact messages"],"security":[{"admin":[]}]}},"/v1/admin/contact/messages/{id}":{"get":{"description":"The whole text, and the reply once sent (read-only).\n\n**Permission:** `contact.view`.","operationId":"AdminContact_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminContactMessageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View a message","tags":["Admin · Contact messages"],"security":[{"admin":[]}]}},"/v1/admin/contact/messages/{id}/reply":{"post":{"description":"Once only (BRD): the reply (3–250) is emailed to the sender in their language and the message becomes replied.\n\n**Permission:** `contact.update`.","operationId":"AdminContact_reply","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplyContactMessageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminContactMessageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"CONTACT_MESSAGE_REPLIED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CONTACT_MESSAGE_REPLIED":{"value":{"code":"CONTACT_MESSAGE_REPLIED","message":"This message has already been replied to.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Reply to a message","tags":["Admin · Contact messages"],"security":[{"admin":[]}]}},"/v1/admin/reports":{"get":{"description":"Newest first; by status, ad, or part of the reason or text. `openCount` is the menu badge. To act on the ad, disable or delete it with `closeReports: true`.\n\n**Permission:** `reports.view`.","operationId":"AdminReports_list","parameters":[{"name":"page","required":false,"in":"query","description":"1-based page number.","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page (1–100).","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["open","reviewed"]}},{"name":"adId","required":false,"in":"query","description":"The reports on one ad.","schema":{"format":"uuid","type":"string"}},{"name":"q","required":false,"in":"query","description":"Part of the reason or the text.","schema":{"maxLength":100,"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportPageDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"List ad reports","tags":["Admin · Reports"],"security":[{"admin":[]}]}},"/v1/admin/reports/{id}":{"get":{"operationId":"AdminReports_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"View an ad report","tags":["Admin · Reports"],"security":[{"admin":[]}],"description":"**Permission:** `reports.view`."}},"/v1/admin/reports/{id}/mark-reviewed":{"post":{"description":"An open report, with an optional `note` (3–500).\n\n**Permission:** `reports.update`.","operationId":"AdminReports_markReviewed","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkReportReviewedDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminReportDto"}}}},"400":{"description":"VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"VALIDATION_FAILED":{"value":{"code":"VALIDATION_FAILED","message":"The request data is invalid","details":[{"field":"mobile","code":"isSaudiMobileRequired","message":"Mobile number must be entered."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"UNAUTHORIZED":{"value":{"code":"UNAUTHORIZED","message":"Please log in to complete this action.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"403":{"description":"ACCOUNT_DISABLED, FORBIDDEN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"ACCOUNT_DISABLED":{"value":{"code":"ACCOUNT_DISABLED","message":"This user is disabled. Please contact the administration.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"FORBIDDEN":{"value":{"code":"FORBIDDEN","message":"You don't have permission to do this","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"404":{"description":"NOT_FOUND","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"NOT_FOUND":{"value":{"code":"NOT_FOUND","message":"The requested item was not found","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"REPORT_ALREADY_REVIEWED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"REPORT_ALREADY_REVIEWED":{"value":{"code":"REPORT_ALREADY_REVIEWED","message":"This report has already been reviewed.","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"500":{"description":"INTERNAL_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"INTERNAL_ERROR":{"value":{"code":"INTERNAL_ERROR","message":"Something went wrong, please try again","requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}}},"summary":"Mark a report reviewed","tags":["Admin · Reports"],"security":[{"admin":[]}]}}},"info":{"title":"Mashhour API","description":"One API for the three Mashhour clients: the customer app (`/v1/customer`), the merchant app (`/v1/merchant`), and the admin control panel (`/v1/admin`).\n\n**Authentication.** Each namespace has its own opaque session token, sent as `Authorization: Bearer <token>`. Tokens are revocable server-side; a token from one namespace is rejected by the others. Routes without a lock are public: guests can call them, and some recognise a signed-in caller too.\n\n**Errors.** Every error has the same shape: `{ code, message, details?, requestId }`. Branch on `code`, which is stable; `message` is translated for display. For `VALIDATION_FAILED`, `details` lists each field problem as `{ field, code, message }`, where `code` is the rule that failed (e.g. `isSaudiMobileRequired` for an empty mobile, `isSaudiMobile` for an invalid one), and `message` is the first of them, ready to show, with the field's name in front when the text doesn't say it (\"Mobile number: A valid number must be entered.\").\n\n**Mobile numbers** are accepted as typed (`05XXXXXXXX`, `+9665…`, Arabic-Indic digits) and returned in E.164 (`+9665XXXXXXXX`).\n\n**Language.** Messages are Arabic by default. Send `Accept-Language: en` (or `?lang=en`) for English. When signed in, the account's saved language is used if the request names none. Error responses carry `Content-Language`.\n\n**Request IDs.** Every response has an `X-Request-Id` header; quote it when reporting a problem.","version":"0.0.1","contact":{}},"tags":[{"name":"Customer · Account"},{"name":"Customer · Ads"},{"name":"Customer · Auth"},{"name":"Customer · Categories"},{"name":"Customer · Cities"},{"name":"Customer · Contact"},{"name":"Customer · Content"},{"name":"Customer · Devices"},{"name":"Customer · Favorites"},{"name":"Customer · Home"},{"name":"Customer · Notifications"},{"name":"Customer · Profile"},{"name":"Customer · Settings"},{"name":"Merchant · Account"},{"name":"Merchant · Ads"},{"name":"Merchant · Auth"},{"name":"Merchant · Categories"},{"name":"Merchant · Cities"},{"name":"Merchant · Contact"},{"name":"Merchant · Content"},{"name":"Merchant · Devices"},{"name":"Merchant · Home"},{"name":"Merchant · Notifications"},{"name":"Merchant · Packages"},{"name":"Merchant · Payments"},{"name":"Merchant · Profile"},{"name":"Merchant · Settings"},{"name":"Merchant · Subscriptions"},{"name":"Merchant · Wallet"},{"name":"Admin · Admins"},{"name":"Admin · Ads"},{"name":"Admin · Audit"},{"name":"Admin · Auth"},{"name":"Admin · Categories"},{"name":"Admin · Contact messages"},{"name":"Admin · Content"},{"name":"Admin · Customers"},{"name":"Admin · Merchants"},{"name":"Admin · Packages"},{"name":"Admin · Profile"},{"name":"Admin · Reports"},{"name":"Admin · Roles"},{"name":"Admin · Settings"},{"name":"System"}],"servers":[],"components":{"securitySchemes":{"customer":{"scheme":"bearer","bearerFormat":"opaque session token","type":"http","description":"Session token from the customer sign-in."},"merchant":{"scheme":"bearer","bearerFormat":"opaque session token","type":"http","description":"Session token from the merchant sign-in."},"admin":{"scheme":"bearer","bearerFormat":"opaque session token","type":"http","description":"Session token from the admin sign-in."}},"schemas":{"DependencyCheckDto":{"type":"object","properties":{"status":{"type":"string","description":"Whether the dependency answered within the timeout.","example":"up","enum":["up","down"]},"latencyMs":{"type":"number","description":"How long the check took, in milliseconds.","example":1.8}},"required":["status","latencyMs"]},"HealthChecksDto":{"type":"object","properties":{"database":{"description":"MySQL (`select 1`). The API can't serve requests without it.","allOf":[{"$ref":"#/components/schemas/DependencyCheckDto"}]},"cache":{"description":"Redis (`PING`). Without it the API still works, uncached.","allOf":[{"$ref":"#/components/schemas/DependencyCheckDto"}]}},"required":["database","cache"]},"HealthResponseDto":{"type":"object","properties":{"status":{"description":"`ok` when everything is up; `degraded` when only the cache is down\n(still 200); `down` when the database is down (503).","example":"ok","enum":["down","ok","degraded"],"type":"string"},"checks":{"$ref":"#/components/schemas/HealthChecksDto"}},"required":["status","checks"]},"LivenessResponseDto":{"type":"object","properties":{"status":{"type":"string","description":"Always `ok` while the process is serving requests.","example":"ok","enum":["ok"]}},"required":["status"]},"NotificationTargetDto":{"type":"object","properties":{"type":{"type":"string","description":"The screen a tap opens: `ad` (the ad's details), `subscription` (my\nsubscription), `packages`, `wallet`, `payment` (the payment result),\n`account` (my profile), `category` (its ads).","example":"ad","enum":["subscription","wallet","account","packages","ad","payment","category"]},"id":{"type":"string","nullable":true,"description":"Null for `packages`, `wallet` and `account`."}},"required":["type","id"]},"NotificationDto":{"type":"object","properties":{"type":{"type":"string","description":"What happened. Types may be added, so don't require a known one.","example":"ad_approved","enum":["account_approved","account_rejected","ad_approved","ad_rejected","ad_disabled","ad_expired","trial_expiring","trial_ended","subscription_activated","subscription_expiring","subscription_expired","payment_succeeded","payment_failed","admin_broadcast"]},"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"group":{"type":"string","description":"Which icon to show: `account`, `ad`, `subscription`, `payment`, `admin`.","example":"ad","enum":["admin","subscription","account","ad","payment"]},"title":{"type":"string","description":"In the request language.","example":"Your ad is published"},"body":{"type":"string","example":"Your ad \\Mixed grill\\ was approved and is now visible to customers."},"target":{"nullable":true,"description":"Null: nothing to open, just show the text.","type":"object","allOf":[{"$ref":"#/components/schemas/NotificationTargetDto"}]},"read":{"type":"boolean","description":"Unread ones are shown apart (BRD)."},"createdAt":{"format":"date-time","type":"string","description":"The date and time it was sent."}},"required":["type","id","group","title","body","target","read","createdAt"]},"NotificationPageDto":{"type":"object","properties":{"items":{"description":"Newest first. Empty: \"No notifications currently available\".","type":"array","items":{"$ref":"#/components/schemas/NotificationDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":4}},"required":["items","page","limit","total"]},"UnreadCountDto":{"type":"object","properties":{"count":{"type":"number","description":"For the bell badge.","example":3}},"required":["count"]},"ReadAllDto":{"type":"object","properties":{"updated":{"type":"number","description":"How many were unread.","example":3}},"required":["updated"]},"RegisterDeviceDto":{"type":"object","properties":{"token":{"type":"string","description":"The FCM registration token from the app's messaging SDK.","minLength":1,"maxLength":4096},"platform":{"example":"android","enum":["ios","android"],"type":"string"},"locale":{"description":"The app's current language; pushes are written in it.","example":"ar","enum":["ar","en"],"type":"string"}},"required":["token","platform","locale"]},"RegisterDto":{"type":"object","properties":{"name":{"type":"string","description":"Letters and numbers only, 2–100 characters.","example":"سارة أحمد"},"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX`.","example":"0551234567"},"email":{"type":"string","description":"Optional; unique across accounts, at most 100 characters.","example":"sara@example.com"},"acceptTerms":{"type":"boolean","description":"The Terms and Conditions checkbox; must be `true`."}},"required":["name","mobile","acceptTerms"]},"VerificationSentDto":{"type":"object","properties":{"verificationId":{"type":"string","description":"Send it back with the code, and to resend the code.","example":"vrf_Zk3n0x8Qy1u4b2V7s9Lr5mT6pWcA0dEfGhIjKlMnOpQ"},"expiresAt":{"format":"date-time","type":"string","description":"When the code stops working (BRD: 60 seconds)."},"resendAfterSeconds":{"type":"number","description":"Seconds until \"resend\" may be offered (the app's countdown).","example":60},"verificationExpiresAt":{"format":"date-time","type":"string","description":"When `verificationId` stops working (10 minutes): after that, start\nagain from the first step."}},"required":["verificationId","expiresAt","resendAfterSeconds","verificationExpiresAt"]},"ResendCodeDto":{"type":"object","properties":{"verificationId":{"type":"string","description":"From the first step's answer."}},"required":["verificationId"]},"VerifyCodeDto":{"type":"object","properties":{"verificationId":{"type":"string","description":"From the first step's answer.","example":"vrf_Zk3n0x8Qy1u4b2V7s9Lr5mT6pWcA0dEfGhIjKlMnOpQ"},"code":{"type":"string","description":"The code from the SMS (`1234` while the fake SMS sender is on).","example":"1234"}},"required":["verificationId","code"]},"CustomerDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","nullable":true,"example":"سارة أحمد"},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","nullable":true,"example":"sara@example.com"},"avatarUrl":{"type":"string","nullable":true,"description":"The profile photo; set from the profile (API-026)."},"language":{"description":"Used when a request names no language, and for SMS.","example":"ar","enum":["ar","en"],"type":"string"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","name","mobile","email","avatarUrl","language","createdAt"]},"CustomerSessionDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"The session token, shown only once. Send it as `Authorization: Bearer …`.","example":"mh_cus_3q2-7wEvxN1c9kP0YyR5bA8dF6gH4jL2mZ1xV7sT0uQ"},"customer":{"$ref":"#/components/schemas/CustomerDto"}},"required":["accessToken","customer"]},"RequestOtpDto":{"type":"object","properties":{"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX` (`5…` and `+9665…` are accepted too).","example":"0551234567"}},"required":["mobile"]},"UpdateAccountDto":{"type":"object","properties":{"language":{"description":"The app's language. Requests without `Accept-Language` or `?lang=` are\nanswered in it, and SMS messages are sent in it.","example":"en","enum":["ar","en"],"type":"string"}},"required":["language"]},"ChangeMobileOtpDto":{"type":"object","properties":{"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX` (`5…` and `+9665…` are accepted too).","example":"0551234567"}},"required":["mobile"]},"ChangeMobileDto":{"type":"object","properties":{"verificationId":{"type":"string","description":"From the first step's answer.","example":"vrf_Zk3n0x8Qy1u4b2V7s9Lr5mT6pWcA0dEfGhIjKlMnOpQ"},"code":{"type":"string","description":"The code from the SMS (`1234` while the fake SMS sender is on).","example":"1234"}},"required":["verificationId","code"]},"UpdateCustomerProfileDto":{"type":"object","properties":{"name":{"type":"string","description":"Letters and digits, 2–100 characters.","example":"سارة أحمد"},"email":{"type":"string","nullable":true,"description":"Unique; sent empty, removes it.","example":"sara@example.com"},"avatarFileId":{"type":"string","nullable":true,"description":"Sent empty, removes the photo; a new `avatar` part replaces it."}}},"RegionDto":{"type":"object","properties":{"code":{"type":"string","example":"riyadh"},"name":{"type":"string","description":"In the request language.","example":"منطقة الرياض"}},"required":["code","name"]},"CityDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","description":"In the request language.","example":"الرياض"},"region":{"$ref":"#/components/schemas/RegionDto"}},"required":["id","name","region"]},"CityListDto":{"type":"object","properties":{"items":{"description":"Active cities, sorted by name in the request language.","type":"array","items":{"$ref":"#/components/schemas/CityDto"}}},"required":["items"]},"CategoryDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","description":"In the request language.","example":"مطاعم"},"description":{"type":"string","nullable":true,"description":"The line under the name on the home cards, in the request language;\nnull when none.","example":"اكتشف أحدث المطاعم وابحث عن أقرب المطاعم منك."},"imageUrl":{"type":"string","nullable":true,"description":"Null until the control panel adds one; the app shows its fallback."},"level":{"type":"number","description":"1 main category, 2 subcategory.","example":1,"enum":[2,1]},"hasChildren":{"type":"boolean","description":"False means the app goes straight to the ads (BRD: a main category\nwithout subcategories opens its ads)."}},"required":["id","name","description","imageUrl","level","hasChildren"]},"CategoryListDto":{"type":"object","properties":{"items":{"description":"Active categories, in display order.","type":"array","items":{"$ref":"#/components/schemas/CategoryDto"}}},"required":["items"]},"CategoryNodeDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","description":"In the request language.","example":"مطاعم"},"description":{"type":"string","nullable":true,"description":"The line under the name on the home cards, in the request language;\nnull when none.","example":"اكتشف أحدث المطاعم وابحث عن أقرب المطاعم منك."},"imageUrl":{"type":"string","nullable":true,"description":"Null until the control panel adds one; the app shows its fallback."},"level":{"description":"1 main category, 2 subcategory.","example":1,"enum":[2,1],"type":"number"},"hasChildren":{"type":"boolean","description":"False means the app goes straight to the ads (BRD: a main category\nwithout subcategories opens its ads)."},"children":{"description":"Active children, in display order; empty for a leaf.","type":"array","items":{"$ref":"#/components/schemas/CategoryNodeDto"}}},"required":["id","name","description","imageUrl","level","hasChildren","children"]},"CategoryTreeDto":{"type":"object","properties":{"items":{"description":"Active main categories, each with its active descendants.","type":"array","items":{"$ref":"#/components/schemas/CategoryNodeDto"}}},"required":["items"]},"CategoryDetailDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","description":"In the request language.","example":"مطاعم"},"description":{"type":"string","nullable":true,"description":"The line under the name on the home cards, in the request language;\nnull when none.","example":"اكتشف أحدث المطاعم وابحث عن أقرب المطاعم منك."},"imageUrl":{"type":"string","nullable":true,"description":"Null until the control panel adds one; the app shows its fallback."},"level":{"description":"1 main category, 2 subcategory.","example":1,"enum":[2,1],"type":"number"},"hasChildren":{"type":"boolean","description":"False means the app goes straight to the ads (BRD: a main category\nwithout subcategories opens its ads)."},"path":{"description":"The main category above a subcategory (breadcrumbs); empty for a main one.","type":"array","items":{"$ref":"#/components/schemas/CategoryDto"}}},"required":["id","name","description","imageUrl","level","hasChildren","path"]},"ContactChannelsDto":{"type":"object","properties":{"phones":{"description":"E.164; empty when none.","example":["+966501234567"],"type":"array","items":{"type":"string"}},"email":{"type":"string","example":"support@mashhour.sa"},"whatsapp":{"type":"string","example":"+966509876543"},"facebook":{"type":"string","example":"https://facebook.com/mashhour"},"x":{"type":"string","example":"https://x.com/mashhour"},"instagram":{"type":"string","example":"https://instagram.com/mashhour"},"snapchat":{"type":"string","example":"https://snapchat.com/add/mashhour"},"tiktok":{"type":"string","example":"https://tiktok.com/@mashhour"},"youtube":{"type":"string","example":"https://youtube.com/@mashhour"}},"required":["phones"]},"StoreLinksDto":{"type":"object","properties":{"ios":{"type":"string","nullable":true,"example":"https://apps.apple.com/app/id0000000000"},"android":{"type":"string","nullable":true,"example":"https://play.google.com/store/apps/details?id=sa.mashhour.customer"}},"required":["ios","android"]},"AppLinksDto":{"type":"object","properties":{"customer":{"$ref":"#/components/schemas/StoreLinksDto"},"merchant":{"$ref":"#/components/schemas/StoreLinksDto"}},"required":["customer","merchant"]},"AppSettingsDto":{"type":"object","properties":{"contactChannels":{"$ref":"#/components/schemas/ContactChannelsDto"},"appLinks":{"$ref":"#/components/schemas/AppLinksDto"},"appShareUrl":{"type":"string","description":"\"Share the app\": a page with the store buttons (API-085).","example":"https://api.mashhour.sa/s/app"}},"required":["contactChannels","appLinks","appShareUrl"]},"AppPageDto":{"type":"object","properties":{"key":{"description":"One of `about`, `terms`, `privacy`.","enum":["about","terms","privacy"],"type":"string"},"title":{"type":"string","description":"In the request language.","example":"الشروط والأحكام"},"content":{"type":"string","description":"Rich text (HTML), in the request language, or the other language when\nit is empty there; empty until the control panel writes it.","example":"<p>…</p>"},"updatedAt":{"format":"date-time","type":"string"}},"required":["key","title","content","updatedAt"]},"ContactTypeDto":{"type":"object","properties":{"key":{"type":"string","example":"inquiry","enum":["merchant","app","complaint","ad","payment","request","suggestion","inquiry","other"]},"label":{"type":"string","example":"استفسار"}},"required":["key","label"]},"AppContactDto":{"type":"object","properties":{"channels":{"description":"Configured channels only (the same as `GET settings`).","allOf":[{"$ref":"#/components/schemas/ContactChannelsDto"}]},"messageTypes":{"description":"The `message` kind's types, in the request language (BRD order).","type":"array","items":{"$ref":"#/components/schemas/ContactTypeDto"}},"complaintTypes":{"description":"The `complaint` kind's types, in the request language.","type":"array","items":{"$ref":"#/components/schemas/ContactTypeDto"}}},"required":["channels","messageTypes","complaintTypes"]},"SendContactMessageDto":{"type":"object","properties":{"kind":{"description":"`message` (default) or `complaint`; picks the `type` list.","example":"message","enum":["message","complaint"],"type":"string"},"type":{"description":"One of the kind's types from `GET contact`; optional (BRD).","example":"inquiry","enum":["merchant","app","complaint","ad","payment","request","suggestion","inquiry","other"],"type":"string"},"name":{"type":"string","description":"2–50 letters and numbers (BRD).","example":"سارة العتيبي"},"email":{"type":"string","example":"sara@example.com"},"mobile":{"type":"string","description":"Saudi mobile, 05XXXXXXXX (BRD).","example":"0551234567"},"message":{"type":"string","description":"10–500 characters (BRD).","example":"كيف أضيف إعلانًا لمتجري في قسم المطاعم؟"}},"required":["name","email","mobile","message"]},"MessageSentDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"message":{"type":"string","description":"What the app shows, in the request language.","example":"تم إرسال رسالتك بنجاح"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","message","createdAt"]},"CustomerHomeHeaderDto":{"type":"object","properties":{"name":{"type":"string","example":"سارة أحمد"},"unreadNotifications":{"type":"number","description":"Unread notifications, for the bell badge."}},"required":["name","unreadNotifications"]},"AdRefDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","description":"In the request language.","example":"مطاعم"}},"required":["id","name"]},"AdLocationDto":{"type":"object","properties":{"latitude":{"type":"number","example":24.7136},"longitude":{"type":"number","example":46.6753},"address":{"type":"string","nullable":true,"example":"حي العليا، طريق الملك فهد"},"mapsUrl":{"type":"string","description":"Opens Google Maps at the pin (BRD: the location as a Google Maps link).","example":"https://www.google.com/maps/search/?api=1&query=24.7136,46.6753"}},"required":["latitude","longitude","address","mapsUrl"]},"AdStoreDto":{"type":"object","properties":{"merchantId":{"type":"string","description":"Opens the activity page (`GET merchants/{id}`)."},"storeName":{"type":"string","example":"مطعم البيت الشامي"},"storeLogoUrl":{"type":"string","nullable":true}},"required":["merchantId","storeName","storeLogoUrl"]},"AdCallDto":{"type":"object","properties":{"mobile":{"type":"string","example":"+966551234567"},"whatsappUrl":{"type":"string","example":"https://wa.me/966551234567"}},"required":["mobile","whatsappUrl"]},"CustomerAdCardDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"title":{"type":"string","example":"عرض المشويات المشكلة لشخصين"},"imageUrl":{"type":"string","nullable":true,"description":"Null: the app shows its default image."},"category":{"$ref":"#/components/schemas/AdRefDto"},"shortDescription":{"type":"string","example":"مشويات مشكلة مع مقبلات وخبز طازج…"},"city":{"$ref":"#/components/schemas/AdRefDto"},"areaLabel":{"type":"string","description":"The city and the address, as the card shows them.","example":"الرياض – حي العليا"},"location":{"$ref":"#/components/schemas/AdLocationDto"},"distanceKm":{"type":"number","nullable":true,"description":"Kilometres from the location sent, one decimal; null without one.","example":2.4},"price":{"type":"number","description":"SAR.","example":50},"previousPrice":{"type":"number","nullable":true,"example":60},"discountPercent":{"type":"number","nullable":true,"example":17},"currency":{"type":"string","example":"SAR","enum":["SAR"]},"expiresAt":{"format":"date-time","type":"string"},"publishedAt":{"format":"date-time","type":"string","nullable":true},"store":{"$ref":"#/components/schemas/AdStoreDto"},"contact":{"$ref":"#/components/schemas/AdCallDto"},"isFavorite":{"type":"boolean","description":"Saved by the signed-in customer; always false for guests."}},"required":["id","title","imageUrl","category","shortDescription","city","areaLabel","location","distanceKm","price","previousPrice","discountPercent","currency","expiresAt","publishedAt","store","contact","isFavorite"]},"CustomerAdCardPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CustomerAdCardDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":12}},"required":["items","page","limit","total"]},"CustomerHomeDto":{"type":"object","properties":{"header":{"nullable":true,"description":"Null for guests (the app shows sign in / sign up).","type":"object","allOf":[{"$ref":"#/components/schemas/CustomerHomeHeaderDto"}]},"categories":{"description":"Active main categories. Empty: \"No sections are currently available\".","type":"array","items":{"$ref":"#/components/schemas/CategoryDto"}},"adSpace":{"description":"The advertising space (D16): up to 10 live ads, nearest first.","type":"array","items":{"$ref":"#/components/schemas/CustomerAdCardDto"}},"latestAds":{"description":"The 3 newest ads (BRD \"Recent announcements\").","type":"array","items":{"$ref":"#/components/schemas/CustomerAdCardDto"}},"categoryAds":{"description":"\"Mashhour ads\": the chosen category's tab (all by default), first page.","allOf":[{"$ref":"#/components/schemas/CustomerAdCardPageDto"}]}},"required":["header","categories","adSpace","latestAds","categoryAds"]},"AdImageDto":{"type":"object","properties":{"id":{"type":"string","description":"The file id; send it back in `imageFileIds` to keep it when editing."},"url":{"type":"string"}},"required":["id","url"]},"AdVideoDto":{"type":"object","properties":{"id":{"type":"string","description":"The file id; send `videoFileId: \"\"` to remove it when editing."},"url":{"type":"string"},"posterUrl":{"type":"string","nullable":true,"description":"A frame of the video, when it could be made."}},"required":["id","url","posterUrl"]},"CustomerAdDetailDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"title":{"type":"string","example":"عرض المشويات المشكلة لشخصين"},"imageUrl":{"type":"string","nullable":true,"description":"Null: the app shows its default image."},"category":{"$ref":"#/components/schemas/AdRefDto"},"shortDescription":{"type":"string","example":"مشويات مشكلة مع مقبلات وخبز طازج…"},"city":{"$ref":"#/components/schemas/AdRefDto"},"areaLabel":{"type":"string","description":"The city and the address, as the card shows them.","example":"الرياض – حي العليا"},"location":{"$ref":"#/components/schemas/AdLocationDto"},"distanceKm":{"type":"number","nullable":true,"description":"Kilometres from the location sent, one decimal; null without one.","example":2.4},"price":{"type":"number","description":"SAR.","example":50},"previousPrice":{"type":"number","nullable":true,"example":60},"discountPercent":{"type":"number","nullable":true,"example":17},"currency":{"example":"SAR","enum":["SAR"],"type":"string"},"expiresAt":{"format":"date-time","type":"string"},"publishedAt":{"format":"date-time","type":"string","nullable":true},"store":{"$ref":"#/components/schemas/AdStoreDto"},"contact":{"$ref":"#/components/schemas/AdCallDto"},"isFavorite":{"type":"boolean","description":"Saved by the signed-in customer; always false for guests."},"description":{"type":"string"},"subcategories":{"type":"array","items":{"$ref":"#/components/schemas/AdRefDto"}},"images":{"type":"array","items":{"$ref":"#/components/schemas/AdImageDto"}},"video":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/AdVideoDto"}]},"views":{"type":"number","example":120},"email":{"type":"string","nullable":true,"description":"The store's email when it has one.","example":"store@example.com"},"shareUrl":{"type":"string","description":"The link to share (and to draw the QR code from, D22).","example":"https://api.mashhour.sa/s/ads/0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"required":["id","title","imageUrl","category","shortDescription","city","areaLabel","location","distanceKm","price","previousPrice","discountPercent","currency","expiresAt","publishedAt","store","contact","isFavorite","description","subcategories","images","video","views","email","shareUrl"]},"AdEventDto":{"type":"object","properties":{"type":{"type":"string","description":"`call` (the call button), `whatsapp`, or `share` (the share sheet).","example":"call","enum":["share","call","whatsapp"]}},"required":["type"]},"MerchantPageDto":{"type":"object","properties":{"merchantId":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"storeName":{"type":"string","example":"مطعم البيت الشامي"},"storeLogoUrl":{"type":"string","nullable":true},"mobile":{"type":"string","nullable":true,"example":"+966559876543"},"whatsappUrl":{"type":"string","nullable":true,"example":"https://wa.me/966559876543"},"email":{"type":"string","nullable":true,"example":"store@example.com"},"shareUrl":{"type":"string","description":"The store's link to share (API-085).","example":"https://api.mashhour.sa/s/merchants/0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"ads":{"description":"The store's live ads, nearest first with a location.","allOf":[{"$ref":"#/components/schemas/CustomerAdCardPageDto"}]}},"required":["merchantId","storeName","storeLogoUrl","mobile","whatsappUrl","email","shareUrl","ads"]},"ReportAdDto":{"type":"object","properties":{"reason":{"type":"string","description":"3–100 characters (D11: free text).","example":"سعر مضلل"},"text":{"type":"string","description":"10–500 characters.","example":"السعر في الإعلان يختلف عن السعر في المحل."}},"required":["reason","text"]},"ReportSentDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"message":{"type":"string","description":"What the app shows, in the request language.","example":"تم إرسال البلاغ بنجاح"}},"required":["id","message"]},"MerchantRegisterDto":{"type":"object","properties":{"name":{"type":"string","description":"Letters and numbers only, 2–100 characters.","example":"محمد عبدالله"},"username":{"type":"string","description":"Used to log in: 3–30 English letters, numbers, `.` or `_`; unique,\ncase-insensitive (stored lowercased).","example":"albait.alshami"},"password":{"type":"string","description":"At least 8 characters with a number.","example":"mashhour2026"},"passwordConfirmation":{"type":"string","description":"Must equal `password`.","example":"mashhour2026"},"mobile":{"type":"string","description":"Saudi mobile, `05XXXXXXXX`; a code is sent to it.","example":"0551234567"},"email":{"type":"string","description":"Unique, at most 100 characters.","example":"store@example.com"},"storeName":{"type":"string","description":"2–100 characters.","example":"مطعم البيت الشامي للمشاويات"},"crNumber":{"type":"string","description":"Commercial registration number, 10 digits, unique. Required unless a\n`workDocument` part is sent.","example":"1010123456"},"acceptTerms":{"type":"boolean","description":"The Terms and Conditions checkbox; must be `true`."},"storeLogoFileId":{"type":"string","description":"Filled from the `storeLogo` part.","format":"uuid"},"crImageFileId":{"type":"string","description":"Filled from the `crImage` part.","format":"uuid"},"workDocumentFileId":{"type":"string","description":"Filled from the `workDocument` part.","format":"uuid"}},"required":["name","username","password","passwordConfirmation","mobile","email","storeName","acceptTerms"]},"RegistrationVerifiedDto":{"type":"object","properties":{"reviewStatus":{"type":"string","description":"`under_review` until an admin approves the application, then the\nmerchant can log in. `approved` at once on a dev server with\n`MERCHANT_AUTO_APPROVE`.","example":"under_review","enum":["under_review","approved","rejected"]}},"required":["reviewStatus"]},"MerchantLoginDto":{"type":"object","properties":{"username":{"type":"string","description":"Not case-sensitive.","example":"albait.alshami"},"password":{"type":"string","example":"mashhour2026"}},"required":["username","password"]},"MerchantDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","example":"محمد عبدالله"},"username":{"type":"string","example":"albait.alshami"},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","example":"store@example.com"},"storeName":{"type":"string","example":"مطعم البيت الشامي للمشاويات"},"storeLogoUrl":{"type":"string","nullable":true},"crNumber":{"type":"string","nullable":true,"example":"1010123456"},"crImageUrl":{"type":"string","nullable":true,"description":"A signed link that expires; ask again for a fresh one."},"workDocumentUrl":{"type":"string","nullable":true,"description":"A signed link that expires; ask again for a fresh one."},"reviewStatus":{"enum":["under_review","approved","rejected"],"type":"string"},"language":{"example":"ar","enum":["ar","en"],"type":"string"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","name","username","mobile","email","storeName","storeLogoUrl","crNumber","crImageUrl","workDocumentUrl","reviewStatus","language","createdAt"]},"MerchantSessionDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"The session token, shown only once. Send it as `Authorization: Bearer …`.","example":"mh_mer_3q2-7wEvxN1c9kP0YyR5bA8dF6gH4jL2mZ1xV7sT0uQ"},"merchant":{"$ref":"#/components/schemas/MerchantDto"}},"required":["accessToken","merchant"]},"ResetTokenDto":{"type":"object","properties":{"resetToken":{"type":"string","description":"Send it to `password/reset` with the new password."}},"required":["resetToken"]},"ResetPasswordDto":{"type":"object","properties":{"resetToken":{"type":"string","description":"From `password/forgot/verify`; works once, for 10 minutes."},"password":{"type":"string","description":"At least 8 characters with a number.","example":"mashhour2027"},"passwordConfirmation":{"type":"string","description":"Must equal `password`.","example":"mashhour2027"}},"required":["resetToken","password","passwordConfirmation"]},"UpdateMerchantProfileDto":{"type":"object","properties":{"name":{"type":"string","description":"Letters and digits, 2–100 characters.","example":"محمد عبدالله"},"email":{"type":"string","description":"Required and unique.","example":"store@example.com"},"storeName":{"type":"string","description":"2–100 characters.","example":"مطعم البيت الشامي للمشاويات"},"crNumber":{"type":"string","nullable":true,"description":"10 digits, unique; sent empty, removes it (then a work document must\nremain).","example":"1010123456"},"storeLogoFileId":{"type":"string","nullable":true,"description":"Sent empty, removes the logo; a new `storeLogo` part replaces it."},"crImageFileId":{"type":"string","nullable":true,"description":"Sent empty, removes the CR image; a new `crImage` part replaces it."},"workDocumentFileId":{"type":"string","nullable":true,"description":"Sent empty, removes it; a new `workDocument` part replaces it."}}},"ChangePasswordDto":{"type":"object","properties":{"currentPassword":{"type":"string","description":"The password used now."},"password":{"type":"string","description":"At least 8 characters with a number.","example":"mashhour2027"},"passwordConfirmation":{"type":"string","description":"Must equal `password`.","example":"mashhour2027"}},"required":["currentPassword","password","passwordConfirmation"]},"PaymentDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"purpose":{"type":"string","description":"`wallet_topup`, `subscription` or `ad_fee`.","enum":["wallet_topup","subscription","ad_fee"]},"method":{"type":"string","description":"`wallet` (from the balance) or `gateway` (PayMob).","enum":["wallet","gateway"]},"amount":{"type":"number","description":"SAR.","example":100},"currency":{"type":"string","example":"SAR","enum":["SAR"]},"status":{"type":"string","description":"`pending` until the gateway confirms it; then `paid`, or `failed` /\n`cancelled`. Retry only after `failed` or `cancelled`.","enum":["pending","paid","failed","cancelled"]},"checkoutUrl":{"type":"string","nullable":true,"description":"Open it to pay when set (PayMob, API-121); null when nothing is left to\ndo (always with the fake gateway, which confirms at once)."},"createdAt":{"format":"date-time","type":"string"},"paidAt":{"format":"date-time","type":"string","nullable":true}},"required":["id","purpose","method","amount","currency","status","checkoutUrl","createdAt","paidAt"]},"WalletTransactionDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"type":{"type":"string","description":"`topup`, `ad_fee` or `subscription`.","enum":["subscription","ad_fee","topup"]},"typeLabel":{"type":"string","description":"In the request language.","example":"شحن المحفظة"},"amount":{"type":"number","description":"SAR; positive for a top-up, negative for a payment.","example":-250},"status":{"type":"string","description":"`pending` (a top-up waiting for the gateway), `completed` or `failed`.","enum":["pending","failed","completed"]},"balanceAfter":{"type":"number","nullable":true,"description":"SAR, once completed; null while pending or after a failure.","example":50},"paymentId":{"type":"string","description":"The payment it belongs to (`GET payments/:id`)."},"createdAt":{"format":"date-time","type":"string"}},"required":["id","type","typeLabel","amount","status","balanceAfter","paymentId","createdAt"]},"WalletTransactionPageDto":{"type":"object","properties":{"items":{"description":"Newest first.","type":"array","items":{"$ref":"#/components/schemas/WalletTransactionDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":3}},"required":["items","page","limit","total"]},"WalletDto":{"type":"object","properties":{"balance":{"type":"number","description":"SAR.","example":50},"currency":{"type":"string","example":"SAR","enum":["SAR"]},"transactions":{"$ref":"#/components/schemas/WalletTransactionPageDto"}},"required":["balance","currency","transactions"]},"TopUpDto":{"type":"object","properties":{"amount":{"type":"number","description":"SAR, 10–10,000, at most two decimals.","example":100}},"required":["amount"]},"TopUpResultDto":{"type":"object","properties":{"payment":{"description":"Open `payment.checkoutUrl` when set; with the fake gateway it is already `paid`.","allOf":[{"$ref":"#/components/schemas/PaymentDto"}]},"balance":{"type":"number","description":"SAR, after the top-up when it is confirmed already.","example":150}},"required":["payment","balance"]},"PackageDurationDto":{"type":"object","properties":{"value":{"type":"number","example":3},"unit":{"type":"string","description":"`day`, `month` or `year`.","enum":["day","month","year"]},"label":{"type":"string","description":"In the request language.","example":"3 أشهر"}},"required":["value","unit","label"]},"PackageDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","example":"الباقة الربع سنوية"},"price":{"type":"number","description":"SAR.","example":250},"previousPrice":{"type":"number","nullable":true,"description":"SAR, struck through on the card (Figma); null when none.","example":300},"currency":{"type":"string","example":"SAR","enum":["SAR"]},"duration":{"$ref":"#/components/schemas/PackageDurationDto"},"benefits":{"description":"One line per benefit, in the request language.","type":"array","items":{"type":"string"}},"recommended":{"type":"boolean","description":"Figma's \"Recommended\" badge."},"isCurrent":{"type":"boolean","description":"The package of your active subscription (BRD: shown apart)."}},"required":["id","name","price","previousPrice","currency","duration","benefits","recommended","isCurrent"]},"PackageListDto":{"type":"object","properties":{"items":{"description":"Active packages, in display order.","type":"array","items":{"$ref":"#/components/schemas/PackageDto"}},"walletBalance":{"type":"number","description":"Your wallet balance in SAR, shown before you confirm (BRD).","example":150}},"required":["items","walletBalance"]},"SubscriptionDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"packageId":{"type":"string","description":"The package it bought (`GET packages`)."},"name":{"type":"string","description":"As bought, in the request language.","example":"الباقة الربع سنوية"},"price":{"type":"number","description":"The fee paid, SAR.","example":250},"currency":{"type":"string","example":"SAR","enum":["SAR"]},"duration":{"$ref":"#/components/schemas/PackageDurationDto"},"benefits":{"description":"As bought, in the request language.","type":"array","items":{"type":"string"}},"status":{"type":"string","description":"`active` or `expired` (BRD); `pending_payment` only while a card\npayment is open.","enum":["active","cancelled","pending_payment","expired"]},"method":{"type":"string","description":"How it was paid.","enum":["wallet","gateway"]},"startsAt":{"format":"date-time","type":"string","nullable":true,"description":"Null until it starts."},"endsAt":{"format":"date-time","type":"string","nullable":true},"remainingDays":{"type":"number","description":"Whole days left; 0 once expired.","example":90},"canRenew":{"type":"boolean","description":"Expired: the app shows \"Renew subscription\" (opens the packages)."}},"required":["id","packageId","name","price","currency","duration","benefits","status","method","startsAt","endsAt","remainingDays","canRenew"]},"TrialDto":{"type":"object","properties":{"status":{"type":"string","description":"`active`, `ended`, or `none` (not among the first approved merchants).","example":"active","enum":["active","none","ended"]},"startsAt":{"format":"date-time","type":"string","nullable":true},"endsAt":{"format":"date-time","type":"string","nullable":true},"remainingDays":{"type":"number","description":"Whole days left; 0 unless active.","example":21}},"required":["status","startsAt","endsAt","remainingDays"]},"CurrentSubscriptionDto":{"type":"object","properties":{"subscription":{"nullable":true,"description":"Null: the app shows \"No active subscription\" and \"View packages\".","type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionDto"}]},"trial":{"description":"The free trial (one month from approval, first 100 merchants).","allOf":[{"$ref":"#/components/schemas/TrialDto"}]}},"required":["subscription","trial"]},"SubscriptionPageDto":{"type":"object","properties":{"items":{"description":"Active and expired subscriptions, newest first.","type":"array","items":{"$ref":"#/components/schemas/SubscriptionDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":2}},"required":["items","page","limit","total"]},"SubscribeDto":{"type":"object","properties":{"packageId":{"type":"string","description":"One of `GET packages`.","format":"uuid"},"method":{"type":"string","description":"`wallet` (from the balance) or `gateway` (PayMob).","example":"wallet","enum":["wallet","gateway"]}},"required":["packageId","method"]},"PurchaseDto":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/SubscriptionDto"},"payment":{"description":"Open `payment.checkoutUrl` when set; with the wallet or the fake gateway it is already `paid`.","allOf":[{"$ref":"#/components/schemas/PaymentDto"}]}},"required":["subscription","payment"]},"PublishGateDto":{"type":"object","properties":{"mode":{"type":"string","description":"`trial` and `subscription`: free; `fee_required`: pay `fee` from the\nwallet or by card when publishing.","example":"fee_required","enum":["subscription","trial","fee_required"]},"endsAt":{"format":"date-time","type":"string","nullable":true,"description":"When the free trial or the subscription ends; null for a fee."},"fee":{"type":"number","nullable":true,"description":"SAR, with `fee_required`; else null.","example":10},"currency":{"type":"string","example":"SAR","enum":["SAR"]},"walletBalance":{"type":"number","description":"SAR, so the app can offer a top-up before paying from the wallet.","example":50}},"required":["mode","endsAt","fee","currency","walletBalance"]},"AdCardDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"title":{"type":"string","example":"عرض المشويات المشكلة لشخصين"},"imageUrl":{"type":"string","nullable":true,"description":"The main image; null if none (the app shows its default)."},"category":{"description":"The main category.","allOf":[{"$ref":"#/components/schemas/AdRefDto"}]},"shortDescription":{"type":"string","description":"The start of the description, for the card (BRD: a brief excerpt).","example":"مشويات مشكلة مع مقبلات وخبز طازج…"},"city":{"$ref":"#/components/schemas/AdRefDto"},"location":{"$ref":"#/components/schemas/AdLocationDto"},"price":{"type":"number","description":"SAR.","example":50},"previousPrice":{"type":"number","nullable":true,"description":"SAR, or null without a discount.","example":60},"discountPercent":{"type":"number","nullable":true,"example":17},"currency":{"type":"string","example":"SAR","enum":["SAR"]},"status":{"type":"string","description":"`pending_review`, `rejected`, `active`, `expired` or `disabled`\n(an active ad past its date reads as `expired`).","enum":["active","disabled","rejected","pending_payment","pending_review","expired","deleted"]},"expiresAt":{"format":"date-time","type":"string","description":"The end of the last day it runs."},"createdAt":{"format":"date-time","type":"string"}},"required":["id","title","imageUrl","category","shortDescription","city","location","price","previousPrice","discountPercent","currency","status","expiresAt","createdAt"]},"AdCardPageDto":{"type":"object","properties":{"items":{"description":"Newest first. Empty: \"There are no ads currently\".","type":"array","items":{"$ref":"#/components/schemas/AdCardDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":4}},"required":["items","page","limit","total"]},"AdContactDto":{"type":"object","properties":{"storeName":{"type":"string","description":"The store, as customers see it.","example":"مطعم البيت الشامي"},"storeLogoUrl":{"type":"string","nullable":true},"mobile":{"type":"string","example":"+966551234567"},"email":{"type":"string","nullable":true,"example":"store@example.com"}},"required":["storeName","storeLogoUrl","mobile","email"]},"AdStatsDto":{"type":"object","properties":{"views":{"type":"number"},"profileVisits":{"type":"number"},"callClicks":{"type":"number"},"whatsappClicks":{"type":"number"},"shares":{"type":"number"},"saves":{"type":"number"}},"required":["views","profileVisits","callClicks","whatsappClicks","shares","saves"]},"AdActionsDto":{"type":"object","properties":{"canEdit":{"type":"boolean"},"canDelete":{"type":"boolean"},"canRepost":{"type":"boolean","description":"Expired: the \"Repost ad\" button."},"canShare":{"type":"boolean"}},"required":["canEdit","canDelete","canRepost","canShare"]},"AdDetailDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"title":{"type":"string","example":"عرض المشويات المشكلة لشخصين"},"imageUrl":{"type":"string","nullable":true,"description":"The main image; null if none (the app shows its default)."},"category":{"description":"The main category.","allOf":[{"$ref":"#/components/schemas/AdRefDto"}]},"shortDescription":{"type":"string","description":"The start of the description, for the card (BRD: a brief excerpt).","example":"مشويات مشكلة مع مقبلات وخبز طازج…"},"city":{"$ref":"#/components/schemas/AdRefDto"},"location":{"$ref":"#/components/schemas/AdLocationDto"},"price":{"type":"number","description":"SAR.","example":50},"previousPrice":{"type":"number","nullable":true,"description":"SAR, or null without a discount.","example":60},"discountPercent":{"type":"number","nullable":true,"example":17},"currency":{"example":"SAR","enum":["SAR"],"type":"string"},"status":{"description":"`pending_review`, `rejected`, `active`, `expired` or `disabled`\n(an active ad past its date reads as `expired`).","enum":["active","disabled","rejected","pending_payment","pending_review","expired","deleted"],"type":"string"},"expiresAt":{"format":"date-time","type":"string","description":"The end of the last day it runs."},"createdAt":{"format":"date-time","type":"string"},"description":{"type":"string"},"subcategories":{"type":"array","items":{"$ref":"#/components/schemas/AdRefDto"}},"images":{"description":"In order; the first is the main image.","type":"array","items":{"$ref":"#/components/schemas/AdImageDto"}},"video":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/AdVideoDto"}]},"contact":{"$ref":"#/components/schemas/AdContactDto"},"statusReason":{"type":"string","nullable":true,"description":"Why it was rejected or disabled; else null."},"stats":{"$ref":"#/components/schemas/AdStatsDto"},"publishMode":{"type":"string","description":"How publishing was covered: `trial`, `subscription` or `fee`.","enum":["subscription","trial","fee"]},"publishedAt":{"format":"date-time","type":"string","nullable":true},"actions":{"$ref":"#/components/schemas/AdActionsDto"},"shareUrl":{"type":"string","nullable":true,"description":"The link to share while the ad is live (`actions.canShare`); null\notherwise (API-085)."}},"required":["id","title","imageUrl","category","shortDescription","city","location","price","previousPrice","discountPercent","currency","status","expiresAt","createdAt","description","subcategories","images","video","contact","statusReason","stats","publishMode","publishedAt","actions","shareUrl"]},"CreateAdDto":{"type":"object","properties":{"title":{"type":"string","description":"Up to 100 characters (BRD).","example":"عرض المشويات المشكلة لشخصين"},"description":{"type":"string","description":"Up to 500 characters; line breaks kept.","example":"مشويات مشكلة مع مقبلات وخبز طازج، العرض ساري حتى نهاية الشهر."},"price":{"type":"number","description":"SAR, at most two decimals.","example":50},"previousPrice":{"type":"number","description":"The price before the discount, SAR (D3); above `price`. The discount\npercent is computed.","example":60},"categoryId":{"type":"string","description":"The main category (`GET categories`)."},"subcategoryIds":{"description":"One or more of the main category's subcategories (D4); required when\nit has any. Multipart: repeat `subcategoryIds[]`.","maxItems":20,"type":"array","items":{"type":"string","format":"uuid"}},"cityId":{"type":"string","description":"`GET cities`."},"latitude":{"type":"number","description":"The map pin (BRD: the ad's location).","example":24.7136},"longitude":{"type":"number","example":46.6753},"address":{"type":"string","description":"The address line under the map; optional, up to 200 characters.","example":"حي العليا، طريق الملك فهد"},"contactMobile":{"type":"string","description":"The phone customers call (BRD: required, Saudi `05XXXXXXXX`).","example":"0551234567"},"contactEmail":{"type":"string","description":"Optional (Figma).","example":"store@example.com"},"expiresOn":{"type":"string","description":"The last day the ad runs, `YYYY-MM-DD` (Saudi calendar), today or\nlater; optional (BRD), 30 days by default (D14).","example":"2026-12-31"},"paymentMethod":{"type":"string","description":"How to pay the ad fee when there is no trial or subscription\n(`GET publish-gate` says `fee_required`): `wallet` or `gateway`.\nIgnored otherwise.","enum":["wallet","gateway"]},"imageFileIds":{"description":"Filled from the `images` parts, in order.","type":"array","items":{"type":"string","format":"uuid"}},"videoFileId":{"type":"string","description":"Filled from the `video` part.","format":"uuid"}},"required":["title","description","price","categoryId","cityId","latitude","longitude","contactMobile","imageFileIds"]},"AdSavedDto":{"type":"object","properties":{"ad":{"$ref":"#/components/schemas/AdDetailDto"},"message":{"type":"string","description":"What the app shows, in the request language.","example":"تم إرسال إعلانك للمراجعة!"},"payment":{"nullable":true,"description":"The fee's payment when there was one; open `checkoutUrl` when set.","type":"object","allOf":[{"$ref":"#/components/schemas/PaymentDto"}]}},"required":["ad","message","payment"]},"UpdateAdDto":{"type":"object","properties":{"title":{"type":"string","example":"عرض المشويات المشكلة لأربعة أشخاص"},"description":{"type":"string"},"price":{"type":"number","description":"SAR."},"previousPrice":{"type":"number","nullable":true,"description":"SAR; sent empty, removes the discount."},"categoryId":{"type":"string"},"subcategoryIds":{"description":"Replaces the subcategories; they must belong to the main category.","maxItems":20,"type":"array","items":{"type":"string","format":"uuid"}},"cityId":{"type":"string"},"latitude":{"type":"number"},"longitude":{"type":"number"},"address":{"type":"string","nullable":true,"description":"Sent empty, removes it."},"contactMobile":{"type":"string"},"contactEmail":{"type":"string","nullable":true,"description":"Sent empty, removes it."},"expiresOn":{"type":"string","description":"`YYYY-MM-DD`, today or later."},"imageFileIds":{"description":"The images to keep, in order, then the new `images` parts. Multipart:\nrepeat `imageFileIds[]`.","type":"array","items":{"type":"string","format":"uuid"}},"videoFileId":{"type":"string","nullable":true,"description":"Sent empty, removes the video; a `video` part replaces it.","format":"uuid"}}},"RepostAdDto":{"type":"object","properties":{"expiresOn":{"type":"string","description":"The new last day, `YYYY-MM-DD`, today or later; 30 days by default.","example":"2027-01-31"},"paymentMethod":{"type":"string","description":"With `fee_required` (`GET publish-gate`): `wallet` or `gateway`.","enum":["wallet","gateway"]}}},"MerchantHomeHeaderDto":{"type":"object","properties":{"name":{"type":"string","example":"محمد عبدالله"},"storeName":{"type":"string","example":"مطعم البيت الشامي"},"storeLogoUrl":{"type":"string","nullable":true,"description":"Null: the app shows the default avatar (BRD)."},"unreadNotifications":{"type":"number","description":"Unread notifications, for the bell badge."}},"required":["name","storeName","storeLogoUrl","unreadNotifications"]},"MerchantHomeStatsDto":{"type":"object","properties":{"totalAds":{"type":"number","example":4},"totalViews":{"type":"number","example":120},"totalProfileVisits":{"type":"number","description":"Visits to your activity page from your ads.","example":18},"totalShares":{"type":"number","example":7},"totalSaves":{"type":"number","example":11}},"required":["totalAds","totalViews","totalProfileVisits","totalShares","totalSaves"]},"MerchantHomeSubscriptionDto":{"type":"object","properties":{"name":{"type":"string","example":"الباقة الربع سنوية"},"endsAt":{"format":"date-time","type":"string","nullable":true},"remainingDays":{"type":"number","example":80}},"required":["name","endsAt","remainingDays"]},"MerchantHomeBillingDto":{"type":"object","properties":{"trial":{"$ref":"#/components/schemas/TrialDto"},"subscription":{"nullable":true,"description":"Null without an active subscription.","type":"object","allOf":[{"$ref":"#/components/schemas/MerchantHomeSubscriptionDto"}]},"publishMode":{"type":"string","description":"`trial`, `subscription` or `fee_required` (`GET publish-gate`).","example":"trial","enum":["subscription","trial","fee_required"]}},"required":["trial","subscription","publishMode"]},"MerchantHomeDto":{"type":"object","properties":{"header":{"$ref":"#/components/schemas/MerchantHomeHeaderDto"},"stats":{"$ref":"#/components/schemas/MerchantHomeStatsDto"},"recentAds":{"description":"Your 3 latest ads; empty when there are none (\"View all\" opens My ads).","type":"array","items":{"$ref":"#/components/schemas/AdCardDto"}},"billing":{"$ref":"#/components/schemas/MerchantHomeBillingDto"}},"required":["header","stats","recentAds","billing"]},"AdminLoginDto":{"type":"object","properties":{"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX` (`5…` and `+9665…` are accepted too).","example":"0551234567"},"password":{"type":"string","example":"Mashhour2026","maxLength":100}},"required":["mobile","password"]},"AdminRoleDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","description":"In the request's language.","example":"Super Admin"},"isSystem":{"type":"boolean","description":"The Super Admin role: every permission, can't be changed."}},"required":["id","name","isSystem"]},"AdminDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","example":"سارة العتيبي"},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","nullable":true,"example":"admin@mashhour.sa"},"status":{"example":"active","enum":["active","disabled"],"type":"string"},"disabledReason":{"type":"string","nullable":true,"description":"Why it was deactivated; null while active."},"language":{"description":"Used when a request sends no language, and for SMS.","example":"ar","enum":["ar","en"],"type":"string"},"avatarUrl":{"type":"string","nullable":true,"description":"The profile picture; null when none."},"role":{"$ref":"#/components/schemas/AdminRoleDto"},"permissions":{"description":"What this admin may do: `[\"*\"]` for everything, otherwise catalogue\nnames such as `packages.create` (every action includes its `view`).","example":["packages.view","packages.create"],"type":"array","items":{"type":"string"}},"lastSignInAt":{"format":"date-time","type":"string","nullable":true},"signInCount":{"type":"number","description":"Successful logins to the control panel.","example":12},"createdAt":{"format":"date-time","type":"string"}},"required":["id","name","mobile","email","status","disabledReason","language","avatarUrl","role","permissions","lastSignInAt","signInCount","createdAt"]},"AdminSessionDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"The session token, shown only once. Send it as `Authorization: Bearer …`.","example":"mh_adm_3q2-7wEvxN1c9kP0YyR5bA8dF6gH4jL2mZ1xV7sT0uQ"},"admin":{"$ref":"#/components/schemas/AdminDto"}},"required":["accessToken","admin"]},"ForgotPasswordDto":{"type":"object","properties":{"mobile":{"type":"string","example":"0551234567"}},"required":["mobile"]},"VerifyResetCodeDto":{"type":"object","properties":{"verificationId":{"type":"string","description":"From the first step's answer.","example":"vrf_Zk3n0x8Qy1u4b2V7s9Lr5mT6pWcA0dEfGhIjKlMnOpQ"},"code":{"type":"string","description":"The code from the SMS (`1234` while the fake SMS sender is on).","example":"1234"}},"required":["verificationId","code"]},"AdminResetTokenDto":{"type":"object","properties":{"resetToken":{"type":"string","description":"Sets the new password with `POST /auth/password/reset`, once, within\n10 minutes.","example":"q2-7wEvxN1c9kP0YyR5bA8dF6gH4jL2mZ1xV7sT0uQ"}},"required":["resetToken"]},"AdminResetPasswordDto":{"type":"object","properties":{"resetToken":{"type":"string","description":"The `resetToken` from `POST /auth/password/forgot/verify`.","maxLength":100},"password":{"type":"string","description":"8–25 characters with a number, an uppercase and a lowercase letter, no spaces (BRD).","example":"Mashhour2027"},"passwordConfirmation":{"type":"string","description":"The same password again.","example":"Mashhour2027"}},"required":["resetToken","password","passwordConfirmation"]},"PermissionDto":{"type":"object","properties":{"key":{"type":"string","example":"packages.create"},"label":{"type":"string","example":"Add"}},"required":["key","label"]},"PermissionAreaDto":{"type":"object","properties":{"area":{"type":"string","example":"packages"},"label":{"type":"string","example":"Packages"},"permissions":{"type":"array","items":{"$ref":"#/components/schemas/PermissionDto"}}},"required":["area","label","permissions"]},"PermissionCatalogueDto":{"type":"object","properties":{"items":{"description":"Control panel areas in menu order, each with its permissions.","type":"array","items":{"$ref":"#/components/schemas/PermissionAreaDto"}}},"required":["items"]},"UpdateProfileDto":{"type":"object","properties":{"name":{"type":"string","example":"سارة العتيبي"},"email":{"type":"string","description":"Needs `currentPassword`.","example":"sara@mashhour.sa","maxLength":100,"format":"email"},"mobile":{"type":"string","description":"Your login number; needs `currentPassword`, and signs out your other\ndevices.","example":"0551234567"},"currentPassword":{"type":"string","description":"Required when the `mobile` or `email` sent differs from the saved one\n(the form can resend unchanged values without it).","maxLength":100},"avatarFileId":{"type":"string","nullable":true,"description":"Filled from the `avatar` part; sent empty, removes the photo."},"language":{"type":"string","description":"The control panel's language.","example":"en","enum":["ar","en"]}}},"AdminChangePasswordDto":{"type":"object","properties":{"currentPassword":{"type":"string","example":"Mashhour2026","maxLength":100},"password":{"type":"string","description":"8–25 characters with a number, an uppercase and a lowercase letter, no\nspaces (BRD).","example":"Mashhour2027"},"passwordConfirmation":{"type":"string","example":"Mashhour2027"}},"required":["currentPassword","password","passwordConfirmation"]},"AuditAdminDto":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Null once the admin was removed from the database."},"name":{"type":"string","nullable":true,"description":"As it was when they acted.","example":"سارة العتيبي"}},"required":["id","name"]},"AuditEntityDto":{"type":"object","properties":{"type":{"type":"string","example":"role"},"id":{"type":"string","nullable":true,"example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}},"required":["type","id"]},"AuditEntryDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"admin":{"nullable":true,"description":"Who did it; null for the system (jobs).","type":"object","allOf":[{"$ref":"#/components/schemas/AuditAdminDto"}]},"action":{"type":"string","description":"`<entity>.<verb>`.","example":"role.update"},"entity":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/AuditEntityDto"}]},"changes":{"type":"object","additionalProperties":true,"description":"The fields that changed, `{ field: { from, to } }`: only `to` on\ncreation, only `from` on deletion. Passwords show as `********`.","example":{"nameEn":{"from":"Editor","to":"Senior editor"}}},"reason":{"type":"string","nullable":true,"description":"The reason given (deactivations, suspensions)."},"ip":{"type":"string","nullable":true,"example":"203.0.113.7"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","admin","action","entity","changes","reason","ip","createdAt"]},"AuditPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntryDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42}},"required":["items","page","limit","total"]},"RoleDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"nameAr":{"type":"string","example":"مشرف الباقات"},"nameEn":{"type":"string","example":"Packages manager"},"name":{"type":"string","description":"The name in the request's language.","example":"Packages manager"},"permissions":{"description":"As chosen, in catalogue order (`[\"*\"]` for the Super Admin role). Each\naction also grants its area's `view`.","example":["packages.view","packages.create"],"type":"array","items":{"type":"string"}},"status":{"example":"active","enum":["active","disabled"],"type":"string"},"isSystem":{"type":"boolean","description":"The Super Admin role, which can't be changed or deleted."},"adminCount":{"type":"number","description":"Admins with this role (for \"The role is assigned to a System\nAdministrator…\" before deactivating).","example":3},"createdAt":{"format":"date-time","type":"string"}},"required":["id","nameAr","nameEn","name","permissions","status","isSystem","adminCount","createdAt"]},"RolePageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RoleDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42}},"required":["items","page","limit","total"]},"CreateRoleDto":{"type":"object","properties":{"nameAr":{"type":"string","description":"Letters and numbers, 2–100 characters, unique.","example":"مشرف الباقات"},"nameEn":{"type":"string","description":"Letters and numbers, 2–100 characters, unique.","example":"Packages manager"},"permissions":{"description":"At least one permission from `GET /v1/admin/auth/permissions`. You can\nonly grant permissions you have yourself.","example":["packages.view","packages.create","packages.update"],"uniqueItems":true,"minItems":1,"type":"array","items":{"type":"string"}}},"required":["nameAr","nameEn","permissions"]},"UpdateRoleDto":{"type":"object","properties":{"nameAr":{"type":"string","example":"مشرف الباقات"},"nameEn":{"type":"string","example":"Packages manager"},"permissions":{"description":"Replaces the role's permissions.","example":["packages.view","packages.update"],"uniqueItems":true,"minItems":1,"type":"array","items":{"type":"string"}}}},"AdminPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42}},"required":["items","page","limit","total"]},"CreateAdminDto":{"type":"object","properties":{"name":{"type":"string","description":"Letters and numbers, 2–100 characters.","example":"سارة العتيبي"},"email":{"type":"string","description":"Unique; notices are sent here.","example":"sara@maqsed.sa","maxLength":100,"format":"email"},"mobile":{"type":"string","description":"Saudi mobile, unique; the admin logs in with it.","example":"0551234567"},"password":{"type":"string","description":"8–25 characters with an uppercase letter, a lowercase letter, a number\nand a symbol, no spaces.","example":"Maqsed@2026"},"passwordConfirmation":{"type":"string","example":"Maqsed@2026"},"roleId":{"type":"string","description":"An active role from `GET /v1/admin/roles`, not the Super Admin."},"avatarFileId":{"type":"string","description":"The `id` from `POST /v1/admin/files?purpose=admin_avatar`."},"status":{"type":"string","description":"`disabled` creates the account without letting it log in yet.","example":"active","enum":["active","disabled"]}},"required":["name","email","mobile","password","passwordConfirmation","roleId"]},"UpdateAdminDto":{"type":"object","properties":{"name":{"type":"string","example":"سارة العتيبي"},"email":{"type":"string","example":"sara@maqsed.sa","maxLength":100,"format":"email"},"mobile":{"type":"string","description":"Their login number; changing it signs them out.","example":"0551234567"},"password":{"type":"string","description":"Changing it signs them out everywhere."},"passwordConfirmation":{"type":"string"},"roleId":{"type":"string","description":"Their permissions change on their next request."},"avatarFileId":{"type":"string","nullable":true,"description":"A new photo; `null` removes it."}}},"DeactivateDto":{"type":"object","properties":{"reason":{"type":"string","description":"Kept on the account and emailed to it.","example":"Repeated policy violations"}},"required":["reason"]},"AdminCustomerRowDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","nullable":true,"example":"سارة أحمد"},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","nullable":true},"avatarUrl":{"type":"string","nullable":true},"language":{"type":"string","example":"ar","enum":["ar","en"]},"status":{"type":"string","example":"active","enum":["active","disabled"]},"disabledReason":{"type":"string","nullable":true,"description":"Why it was deactivated; null while active."},"lastSignInAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"The join date."}},"required":["id","name","mobile","email","avatarUrl","language","status","disabledReason","lastSignInAt","createdAt"]},"AdminCustomerPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminCustomerRowDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42}},"required":["items","page","limit","total"]},"AdminCustomerCountsDto":{"type":"object","properties":{"favorites":{"type":"number","description":"Ads saved to favorites.","example":4},"reports":{"type":"number","description":"Ads reported.","example":1}},"required":["favorites","reports"]},"AdminCustomerDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","nullable":true,"example":"سارة أحمد"},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","nullable":true},"avatarUrl":{"type":"string","nullable":true},"language":{"example":"ar","enum":["ar","en"],"type":"string"},"status":{"example":"active","enum":["active","disabled"],"type":"string"},"disabledReason":{"type":"string","nullable":true,"description":"Why it was deactivated; null while active."},"lastSignInAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"The join date."},"counts":{"$ref":"#/components/schemas/AdminCustomerCountsDto"},"termsAcceptedAt":{"format":"date-time","type":"string","nullable":true,"description":"When they accepted the terms, at registration."}},"required":["id","name","mobile","email","avatarUrl","language","status","disabledReason","lastSignInAt","createdAt","counts","termsAcceptedAt"]},"AdminUpdateCustomerDto":{"type":"object","properties":{"name":{"type":"string","example":"سارة أحمد"},"email":{"type":"string","nullable":true,"description":"Unique; `null` or empty removes it.","example":"sara@example.com"},"mobile":{"type":"string","description":"Their login number, unique; changing it signs them out.","example":"0551234567"}}},"AdminMerchantRowDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","example":"محمد عبدالله"},"username":{"type":"string","example":"albait.alshami"},"storeName":{"type":"string","example":"مطعم البيت الشامي للمشاويات"},"storeLogoUrl":{"type":"string","nullable":true},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","example":"store@example.com"},"reviewStatus":{"type":"string","example":"under_review","enum":["under_review","approved","rejected"]},"status":{"type":"string","example":"active","enum":["active","disabled"]},"disabledReason":{"type":"string","nullable":true,"description":"Why it was deactivated; null while active."},"lastSignInAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"The registration date."}},"required":["id","name","username","storeName","storeLogoUrl","mobile","email","reviewStatus","status","disabledReason","lastSignInAt","createdAt"]},"AdminMerchantCountsDto":{"type":"object","properties":{"under_review":{"type":"number","example":3},"approved":{"type":"number","example":40},"rejected":{"type":"number","example":2}},"required":["under_review","approved","rejected"]},"AdminMerchantPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminMerchantRowDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42},"counts":{"description":"Per review status, with the other filters applied: the joining\nrequests badge is `counts.under_review`.","allOf":[{"$ref":"#/components/schemas/AdminMerchantCountsDto"}]}},"required":["items","page","limit","total","counts"]},"AdminMerchantDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","example":"محمد عبدالله"},"username":{"type":"string","example":"albait.alshami"},"storeName":{"type":"string","example":"مطعم البيت الشامي للمشاويات"},"storeLogoUrl":{"type":"string","nullable":true},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","example":"store@example.com"},"reviewStatus":{"example":"under_review","enum":["under_review","approved","rejected"],"type":"string"},"status":{"example":"active","enum":["active","disabled"],"type":"string"},"disabledReason":{"type":"string","nullable":true,"description":"Why it was deactivated; null while active."},"lastSignInAt":{"format":"date-time","type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string","description":"The registration date."},"crNumber":{"type":"string","nullable":true,"example":"1010123456"},"crImageUrl":{"type":"string","nullable":true,"description":"A signed link that expires; ask again for a fresh one."},"workDocumentUrl":{"type":"string","nullable":true,"description":"A signed link that expires; ask again for a fresh one."},"rejectionReason":{"type":"string","nullable":true,"description":"Why the application was rejected; null otherwise."},"reviewedAt":{"format":"date-time","type":"string","nullable":true,"description":"When it was last approved or rejected."},"termsAcceptedAt":{"format":"date-time","type":"string","nullable":true},"language":{"example":"ar","enum":["ar","en"],"type":"string"},"resubmittedAt":{"format":"date-time","type":"string","nullable":true,"description":"A rejected merchant's new application waiting for its mobile code\n(D5); applied, and back under review, once verified."},"adsCount":{"type":"number","description":"Ads not deleted, in any status.","example":12},"trial":{"$ref":"#/components/schemas/TrialDto"},"subscription":{"nullable":true,"description":"The active subscription, or null.","type":"object","allOf":[{"$ref":"#/components/schemas/SubscriptionDto"}]}},"required":["id","name","username","storeName","storeLogoUrl","mobile","email","reviewStatus","status","disabledReason","lastSignInAt","createdAt","crNumber","crImageUrl","workDocumentUrl","rejectionReason","reviewedAt","termsAcceptedAt","language","resubmittedAt","adsCount","trial","subscription"]},"RejectMerchantDto":{"type":"object","properties":{"reason":{"type":"string","description":"3–250 characters, letters and numbers."}},"required":["reason"]},"AdminUpdateMerchantDto":{"type":"object","properties":{"name":{"type":"string","example":"محمد عبدالله"},"email":{"type":"string","description":"Required and unique.","example":"store@example.com"},"storeName":{"type":"string","example":"مطعم البيت الشامي للمشاويات"},"crNumber":{"type":"string","nullable":true,"description":"10 digits, unique; `null` or empty removes it (then a work document\nmust remain).","example":"1010123456"}}},"AdminAdMerchantDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"storeName":{"type":"string","example":"مطعم البيت الشامي"}},"required":["id","storeName"]},"AdminAdRowDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"title":{"type":"string","example":"عرض المشويات المشكلة لشخصين"},"imageUrl":{"type":"string","nullable":true,"description":"The main image; null if none (the app shows its default)."},"category":{"description":"The main category.","allOf":[{"$ref":"#/components/schemas/AdRefDto"}]},"shortDescription":{"type":"string","description":"The start of the description, for the card (BRD: a brief excerpt).","example":"مشويات مشكلة مع مقبلات وخبز طازج…"},"city":{"$ref":"#/components/schemas/AdRefDto"},"location":{"$ref":"#/components/schemas/AdLocationDto"},"price":{"type":"number","description":"SAR.","example":50},"previousPrice":{"type":"number","nullable":true,"description":"SAR, or null without a discount.","example":60},"discountPercent":{"type":"number","nullable":true,"example":17},"currency":{"example":"SAR","enum":["SAR"],"type":"string"},"status":{"description":"`pending_review`, `rejected`, `active`, `expired` or `disabled`\n(an active ad past its date reads as `expired`).","enum":["active","disabled","rejected","pending_payment","pending_review","expired","deleted"],"type":"string"},"expiresAt":{"format":"date-time","type":"string","description":"The end of the last day it runs."},"createdAt":{"format":"date-time","type":"string"},"merchant":{"$ref":"#/components/schemas/AdminAdMerchantDto"},"openReports":{"type":"number","description":"Open reports on it.","example":0}},"required":["id","title","imageUrl","category","shortDescription","city","location","price","previousPrice","discountPercent","currency","status","expiresAt","createdAt","merchant","openReports"]},"AdminAdCategoryTotalDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","description":"In the request language.","example":"مطاعم"},"count":{"type":"number","example":12}},"required":["id","name","count"]},"AdminAdTotalsDto":{"type":"object","properties":{"all":{"type":"number","description":"Every ad matching the filters but the category.","example":40},"byCategory":{"description":"Per main category, largest first.","type":"array","items":{"$ref":"#/components/schemas/AdminAdCategoryTotalDto"}}},"required":["all","byCategory"]},"AdminAdPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminAdRowDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42},"totals":{"description":"The totals cards, with every filter but the category.","allOf":[{"$ref":"#/components/schemas/AdminAdTotalsDto"}]}},"required":["items","page","limit","total","totals"]},"AdminAdOwnerDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"storeName":{"type":"string","example":"مطعم البيت الشامي"},"name":{"type":"string","example":"محمد عبدالله"},"mobile":{"type":"string","nullable":true,"description":"E.164.","example":"+966551234567"},"email":{"type":"string","nullable":true},"status":{"type":"string","description":"The merchant's account status: their ads are hidden while disabled."}},"required":["id","storeName","name","mobile","email","status"]},"AdminAdActionsDto":{"type":"object","properties":{"canApprove":{"type":"boolean"},"canReject":{"type":"boolean"},"canDisable":{"type":"boolean"},"canEnable":{"type":"boolean"},"canDelete":{"type":"boolean"}},"required":["canApprove","canReject","canDisable","canEnable","canDelete"]},"AdminAdEventDto":{"type":"object","properties":{"action":{"type":"string","description":"`create`, `edit`, `approve`, `reject`, `disable`, `repost`…"},"actorType":{"type":"string","example":"admin","enum":["admin","merchant","system"]},"actorId":{"type":"string","nullable":true},"fromStatus":{"type":"string","nullable":true,"enum":["active","disabled","rejected","pending_payment","pending_review","expired","deleted"]},"toStatus":{"type":"string","enum":["active","disabled","rejected","pending_payment","pending_review","expired","deleted"]},"reason":{"type":"string","nullable":true},"createdAt":{"format":"date-time","type":"string"}},"required":["action","actorType","actorId","fromStatus","toStatus","reason","createdAt"]},"AdminAdDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"title":{"type":"string","example":"عرض المشويات المشكلة لشخصين"},"imageUrl":{"type":"string","nullable":true,"description":"The main image; null if none (the app shows its default)."},"category":{"description":"The main category.","allOf":[{"$ref":"#/components/schemas/AdRefDto"}]},"shortDescription":{"type":"string","description":"The start of the description, for the card (BRD: a brief excerpt).","example":"مشويات مشكلة مع مقبلات وخبز طازج…"},"city":{"$ref":"#/components/schemas/AdRefDto"},"location":{"$ref":"#/components/schemas/AdLocationDto"},"price":{"type":"number","description":"SAR.","example":50},"previousPrice":{"type":"number","nullable":true,"description":"SAR, or null without a discount.","example":60},"discountPercent":{"type":"number","nullable":true,"example":17},"currency":{"example":"SAR","enum":["SAR"],"type":"string"},"status":{"description":"`pending_review`, `rejected`, `active`, `expired` or `disabled`\n(an active ad past its date reads as `expired`).","enum":["active","disabled","rejected","pending_payment","pending_review","expired","deleted"],"type":"string"},"expiresAt":{"format":"date-time","type":"string","description":"The end of the last day it runs."},"createdAt":{"format":"date-time","type":"string"},"description":{"type":"string"},"subcategories":{"type":"array","items":{"$ref":"#/components/schemas/AdRefDto"}},"images":{"description":"In order; the first is the main image.","type":"array","items":{"$ref":"#/components/schemas/AdImageDto"}},"video":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/AdVideoDto"}]},"contact":{"$ref":"#/components/schemas/AdContactDto"},"statusReason":{"type":"string","nullable":true,"description":"Why it was rejected or disabled; else null."},"stats":{"$ref":"#/components/schemas/AdStatsDto"},"publishMode":{"description":"How publishing was covered: `trial`, `subscription` or `fee`.","enum":["subscription","trial","fee"],"type":"string"},"publishedAt":{"format":"date-time","type":"string","nullable":true},"actions":{"$ref":"#/components/schemas/AdActionsDto"},"shareUrl":{"type":"string","nullable":true,"description":"The link to share while the ad is live (`actions.canShare`); null\notherwise (API-085)."},"merchant":{"$ref":"#/components/schemas/AdminAdOwnerDto"},"openReports":{"type":"number","description":"Open reports on it.","example":0},"adminActions":{"$ref":"#/components/schemas/AdminAdActionsDto"},"history":{"type":"array","items":{"$ref":"#/components/schemas/AdminAdEventDto"}}},"required":["id","title","imageUrl","category","shortDescription","city","location","price","previousPrice","discountPercent","currency","status","expiresAt","createdAt","description","subcategories","images","video","contact","statusReason","stats","publishMode","publishedAt","actions","shareUrl","merchant","openReports","adminActions","history"]},"RejectAdDto":{"type":"object","properties":{"reason":{"type":"string","description":"3–500 characters."}},"required":["reason"]},"AdminAdActionDto":{"type":"object","properties":{"reason":{"type":"string","description":"Optional; 3–500 characters, sent to the merchant when disabling."},"closeReports":{"type":"boolean","description":"Also mark the ad's open reports reviewed (when acting on a report).","example":true}}},"AdminCategoryParentDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"nameAr":{"type":"string","example":"مطاعم"},"nameEn":{"type":"string","example":"Restaurants"},"active":{"type":"boolean"}},"required":["id","nameAr","nameEn","active"]},"AdminCategoryRowDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"parent":{"nullable":true,"description":"The main category, for a subcategory; else null.","type":"object","allOf":[{"$ref":"#/components/schemas/AdminCategoryParentDto"}]},"nameAr":{"type":"string","example":"مطاعم"},"nameEn":{"type":"string","example":"Restaurants"},"descriptionAr":{"type":"string","nullable":true},"descriptionEn":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"status":{"type":"string","example":"active","enum":["active","inactive"]},"visible":{"type":"boolean","description":"Shown in the apps: it and its main category are active. A subcategory's\nads stay visible while their main category is (your decision)."},"position":{"type":"number","description":"Display order among its siblings.","example":0},"adsCount":{"type":"number","description":"Ads not deleted.","example":12},"subcategoriesCount":{"type":"number","description":"For a main category.","example":5},"createdAt":{"format":"date-time","type":"string"}},"required":["id","parent","nameAr","nameEn","descriptionAr","descriptionEn","imageUrl","status","visible","position","adsCount","subcategoriesCount","createdAt"]},"AdminCategoryPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminCategoryRowDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":4}},"required":["items","page","limit","total"]},"AdminCategoryDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"parent":{"nullable":true,"description":"The main category, for a subcategory; else null.","type":"object","allOf":[{"$ref":"#/components/schemas/AdminCategoryParentDto"}]},"nameAr":{"type":"string","example":"مطاعم"},"nameEn":{"type":"string","example":"Restaurants"},"descriptionAr":{"type":"string","nullable":true},"descriptionEn":{"type":"string","nullable":true},"imageUrl":{"type":"string","nullable":true},"status":{"example":"active","enum":["active","inactive"],"type":"string"},"visible":{"type":"boolean","description":"Shown in the apps: it and its main category are active. A subcategory's\nads stay visible while their main category is (your decision)."},"position":{"type":"number","description":"Display order among its siblings.","example":0},"adsCount":{"type":"number","description":"Ads not deleted.","example":12},"subcategoriesCount":{"type":"number","description":"For a main category.","example":5},"createdAt":{"format":"date-time","type":"string"},"subcategories":{"type":"array","items":{"$ref":"#/components/schemas/AdminCategoryRowDto"}}},"required":["id","parent","nameAr","nameEn","descriptionAr","descriptionEn","imageUrl","status","visible","position","adsCount","subcategoriesCount","createdAt","subcategories"]},"CreateCategoryDto":{"type":"object","properties":{"parentId":{"type":"string","description":"The main category, for a subcategory.","format":"uuid"},"nameAr":{"type":"string","description":"Unique among its siblings.","example":"مطاعم"},"nameEn":{"type":"string","description":"Unique among its siblings.","example":"Restaurants"},"descriptionAr":{"type":"string","nullable":true,"description":"The line under the name on the home cards.","maxLength":250},"descriptionEn":{"type":"string","nullable":true,"maxLength":250},"imageFileId":{"type":"string","nullable":true,"description":"Filled from the `image` part."}},"required":["nameAr","nameEn"]},"ReorderCategoriesDto":{"type":"object","properties":{"parentId":{"type":"string","nullable":true,"description":"Whose subcategories these are; `null` for the main categories.","format":"uuid"},"ids":{"description":"Every sibling, in the new order.","uniqueItems":true,"minItems":1,"type":"array","items":{"type":"string","format":"uuid"}}},"required":["parentId","ids"]},"UpdateCategoryDto":{"type":"object","properties":{"parentId":{"type":"string","description":"A subcategory's new main category (active).","format":"uuid"},"nameAr":{"type":"string"},"nameEn":{"type":"string"},"descriptionAr":{"type":"string","nullable":true,"maxLength":250},"descriptionEn":{"type":"string","nullable":true,"maxLength":250},"imageFileId":{"type":"string","nullable":true}}},"AdminPackageDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"nameAr":{"type":"string","example":"الباقة الشهرية"},"nameEn":{"type":"string","example":"Monthly package"},"price":{"type":"number","description":"SAR.","example":100},"previousPrice":{"type":"number","nullable":true,"description":"SAR, or null.","example":120},"currency":{"example":"SAR","enum":["SAR"],"type":"string"},"duration":{"description":"The label in the request language.","allOf":[{"$ref":"#/components/schemas/PackageDurationDto"}]},"benefitsAr":{"type":"array","items":{"type":"string"}},"benefitsEn":{"type":"array","items":{"type":"string"}},"recommended":{"type":"boolean"},"status":{"example":"active","enum":["active","inactive"],"type":"string"},"position":{"type":"number","description":"Display order.","example":0},"activeSubscriptions":{"type":"number","description":"Running subscriptions.","example":12},"createdAt":{"format":"date-time","type":"string"},"updatedAt":{"format":"date-time","type":"string"}},"required":["id","nameAr","nameEn","price","previousPrice","currency","duration","benefitsAr","benefitsEn","recommended","status","position","activeSubscriptions","createdAt","updatedAt"]},"AdminPackagePageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminPackageDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":3}},"required":["items","page","limit","total"]},"CreatePackageDto":{"type":"object","properties":{"nameAr":{"type":"string","description":"Unique among active packages.","example":"الباقة الشهرية"},"nameEn":{"type":"string","description":"Unique among active packages.","example":"Monthly package"},"price":{"type":"number","description":"SAR, above zero, two decimals at most.","example":100},"previousPrice":{"type":"number","nullable":true,"description":"SAR, struck through on the card (D8); above the price.","example":120},"durationValue":{"type":"number","description":"A positive whole number.","example":1,"minimum":1,"maximum":1000},"durationUnit":{"type":"string","example":"month","enum":["day","month","year"]},"benefitsAr":{"description":"One line per benefit, shown to merchants.","type":"array","items":{"type":"string"}},"benefitsEn":{"type":"array","items":{"type":"string"}},"recommended":{"type":"boolean","description":"Figma's \"Recommended\" badge."},"active":{"type":"boolean","description":"Default true (BRD)."}},"required":["nameAr","nameEn","price","durationValue","durationUnit","benefitsAr","benefitsEn"]},"ReorderPackagesDto":{"type":"object","properties":{"ids":{"description":"Every package, in the new order.","uniqueItems":true,"minItems":1,"type":"array","items":{"type":"string","format":"uuid"}}},"required":["ids"]},"UpdatePackageDto":{"type":"object","properties":{"nameAr":{"type":"string"},"nameEn":{"type":"string"},"price":{"type":"number"},"previousPrice":{"type":"number","nullable":true},"durationValue":{"type":"number","minimum":1,"maximum":1000},"durationUnit":{"type":"string","enum":["day","month","year"]},"benefitsAr":{"type":"array","items":{"type":"string"}},"benefitsEn":{"type":"array","items":{"type":"string"}},"recommended":{"type":"boolean"}}},"AdminFreeTrialDto":{"type":"object","properties":{"months":{"type":"number","example":1},"seats":{"type":"number","description":"The first approved merchants who get it (D9).","example":100}},"required":["months","seats"]},"AdminStoreLinksDto":{"type":"object","properties":{"ios":{"type":"string","nullable":true,"example":"https://apps.apple.com/app/id0000000000"},"android":{"type":"string","nullable":true,"example":"https://play.google.com/store/apps/details?id=sa.mashhour.customer"}},"required":["ios","android"]},"AdminAppLinksDto":{"type":"object","properties":{"customer":{"$ref":"#/components/schemas/AdminStoreLinksDto"},"merchant":{"$ref":"#/components/schemas/AdminStoreLinksDto"}},"required":["customer","merchant"]},"SavedDto":{"type":"object","properties":{}},"SavedSettingsDto":{"type":"object","properties":{"adFee":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/SavedDto"}]},"freeTrial":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/SavedDto"}]},"adDefaultDays":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/SavedDto"}]},"reminderDays":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/SavedDto"}]},"appLinks":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/SavedDto"}]}},"required":["adFee","freeTrial","adDefaultDays","reminderDays","appLinks"]},"AdminSettingsDto":{"type":"object","properties":{"adFee":{"type":"number","description":"SAR per ad without a trial or subscription (D10).","example":10},"freeTrial":{"$ref":"#/components/schemas/AdminFreeTrialDto"},"freeTrialSeatsTaken":{"type":"number","description":"Seats taken so far; seats never return (D9).","example":37},"adDefaultDays":{"type":"number","description":"Days an ad runs when the merchant picks no date (D14).","example":30},"reminderDays":{"type":"number","description":"Days before a trial or subscription ends that the merchant is reminded.","example":3},"appLinks":{"description":"Store links shown in the apps and share pages; null hides one.","allOf":[{"$ref":"#/components/schemas/AdminAppLinksDto"}]},"saved":{"description":"When each was last saved, and by whom.","allOf":[{"$ref":"#/components/schemas/SavedSettingsDto"}]}},"required":["adFee","freeTrial","freeTrialSeatsTaken","adDefaultDays","reminderDays","appLinks","saved"]},"FreeTrialPatchDto":{"type":"object","properties":{"months":{"type":"number","description":"1–24.","example":1,"minimum":1,"maximum":24},"seats":{"type":"number","description":"0–100000; lowering it only stops new trials.","example":100,"minimum":0,"maximum":100000}}},"StoreLinksPatchDto":{"type":"object","properties":{"ios":{"type":"string","nullable":true},"android":{"type":"string","nullable":true}}},"AppLinksPatchDto":{"type":"object","properties":{"customer":{"$ref":"#/components/schemas/StoreLinksPatchDto"},"merchant":{"$ref":"#/components/schemas/StoreLinksPatchDto"}}},"UpdateSettingsDto":{"type":"object","properties":{"adFee":{"type":"number","description":"SAR, two decimals at most; the next ad pays it.","example":15},"freeTrial":{"$ref":"#/components/schemas/FreeTrialPatchDto"},"adDefaultDays":{"type":"number","description":"1–365.","example":30,"minimum":1,"maximum":365},"reminderDays":{"type":"number","description":"1–30.","example":3,"minimum":1,"maximum":30},"appLinks":{"description":"Only the links sent change; null hides one.","allOf":[{"$ref":"#/components/schemas/AppLinksPatchDto"}]}}},"AdminRefDto":{"type":"object","properties":{}},"AdminContentPageSummaryDto":{"type":"object","properties":{"key":{"type":"string","example":"about","enum":["about","terms","privacy"]},"titleAr":{"type":"string"},"titleEn":{"type":"string"},"complete":{"type":"boolean","description":"Both languages are filled."},"updatedAt":{"format":"date-time","type":"string"},"updatedBy":{"nullable":true,"description":"Null for the seed, or once that admin is deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/AdminRefDto"}]}},"required":["key","titleAr","titleEn","complete","updatedAt","updatedBy"]},"AdminContentPageDto":{"type":"object","properties":{"key":{"example":"about","enum":["about","terms","privacy"],"type":"string"},"titleAr":{"type":"string"},"titleEn":{"type":"string"},"complete":{"type":"boolean","description":"Both languages are filled."},"updatedAt":{"format":"date-time","type":"string"},"updatedBy":{"nullable":true,"description":"Null for the seed, or once that admin is deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/AdminRefDto"}]},"contentAr":{"type":"string","description":"Rich text (HTML)."},"contentEn":{"type":"string"}},"required":["key","titleAr","titleEn","complete","updatedAt","updatedBy","contentAr","contentEn"]},"SavePageDto":{"type":"object","properties":{"contentAr":{"type":"string","description":"Rich text (HTML); sanitised, required (BRD: \"Text must be entered\").","maxLength":200000},"contentEn":{"type":"string","maxLength":200000},"titleAr":{"type":"string","description":"The page title, when it changes.","example":"من نحن","maxLength":150},"titleEn":{"type":"string","example":"About us","maxLength":150}},"required":["contentAr","contentEn"]},"AdminContactChannelsDto":{"type":"object","properties":{"phones":{"example":["+966551234567"],"type":"array","items":{"type":"string"}},"whatsapp":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"facebook":{"type":"string","nullable":true},"x":{"type":"string","nullable":true},"instagram":{"type":"string","nullable":true},"snapchat":{"type":"string","nullable":true},"tiktok":{"type":"string","nullable":true},"youtube":{"type":"string","nullable":true}},"required":["phones","whatsapp","email","facebook","x","instagram","snapchat","tiktok","youtube"]},"SaveContactChannelsDto":{"type":"object","properties":{"phones":{"description":"Contact mobiles, `05…` (up to 5, no duplicates).","example":["0551234567"],"maxItems":5,"type":"array","items":{"type":"string"}},"whatsapp":{"type":"string","nullable":true,"description":"A WhatsApp number, `05…`.","example":"0551234567"},"email":{"type":"string","nullable":true,"example":"support@mashhour.sa"},"facebook":{"type":"string","nullable":true,"example":"https://facebook.com/mashhour"},"x":{"type":"string","nullable":true,"example":"https://x.com/mashhour"},"instagram":{"type":"string","nullable":true},"snapchat":{"type":"string","nullable":true},"tiktok":{"type":"string","nullable":true},"youtube":{"type":"string","nullable":true}}},"AdminContactMessageRowDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","example":"سارة أحمد"},"senderType":{"type":"string","example":"customer","enum":["customer","merchant","guest"]},"senderId":{"type":"string","nullable":true,"description":"The account, when the sender was signed in."},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","example":"sara@example.com"},"kind":{"type":"string","example":"message","enum":["message","complaint"]},"type":{"type":"string","nullable":true,"example":"inquiry","enum":["merchant","app","complaint","ad","payment","request","suggestion","inquiry","other"]},"typeLabel":{"type":"string","nullable":true,"description":"In the request language.","example":"Inquiry"},"status":{"type":"string","example":"not_replied","enum":["not_replied","replied"]},"excerpt":{"type":"string","description":"The start of the text."},"createdAt":{"format":"date-time","type":"string","description":"The sending date."}},"required":["id","name","senderType","senderId","mobile","email","kind","type","typeLabel","status","excerpt","createdAt"]},"AdminContactCountsDto":{"type":"object","properties":{"notReplied":{"type":"number","description":"For the side menu badge.","example":3}},"required":["notReplied"]},"AdminContactMessagePageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminContactMessageRowDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42},"counts":{"$ref":"#/components/schemas/AdminContactCountsDto"}},"required":["items","page","limit","total","counts"]},"AdminContactMessageDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","example":"سارة أحمد"},"senderType":{"example":"customer","enum":["customer","merchant","guest"],"type":"string"},"senderId":{"type":"string","nullable":true,"description":"The account, when the sender was signed in."},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","example":"sara@example.com"},"kind":{"example":"message","enum":["message","complaint"],"type":"string"},"type":{"nullable":true,"example":"inquiry","enum":["merchant","app","complaint","ad","payment","request","suggestion","inquiry","other"],"type":"string"},"typeLabel":{"type":"string","nullable":true,"description":"In the request language.","example":"Inquiry"},"status":{"example":"not_replied","enum":["not_replied","replied"],"type":"string"},"excerpt":{"type":"string","description":"The start of the text."},"createdAt":{"format":"date-time","type":"string","description":"The sending date."},"body":{"type":"string"},"app":{"type":"string","description":"The app it was sent from.","example":"customer"},"language":{"type":"string","description":"The sender's language; the reply email is in it.","example":"ar"},"reply":{"type":"string","nullable":true,"description":"Once replied: shown read-only."},"repliedAt":{"format":"date-time","type":"string","nullable":true},"repliedBy":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/AdminRefDto"}]}},"required":["id","name","senderType","senderId","mobile","email","kind","type","typeLabel","status","excerpt","createdAt","body","app","language","reply","repliedAt","repliedBy"]},"ReplyContactMessageDto":{"type":"object","properties":{"reply":{"type":"string","description":"BRD: required, letters and numbers, 3–250."}},"required":["reply"]},"AdminReportAdDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"title":{"type":"string","example":"عرض المشويات المشكلة"},"status":{"type":"string","description":"As stored (`deleted` once removed).","example":"active","enum":["active","disabled","rejected","pending_payment","pending_review","expired","deleted"]}},"required":["id","title","status"]},"AdminReportPartyDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"name":{"type":"string","nullable":true,"example":"سارة أحمد"}},"required":["id","name"]},"AdminReportDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"ad":{"$ref":"#/components/schemas/AdminReportAdDto"},"merchant":{"description":"The store, by its name.","allOf":[{"$ref":"#/components/schemas/AdminReportPartyDto"}]},"customer":{"$ref":"#/components/schemas/AdminReportPartyDto"},"reason":{"type":"string","example":"سعر مضلل"},"text":{"type":"string","example":"السعر في الإعلان يختلف عن المحل."},"status":{"example":"open","enum":["open","reviewed"],"type":"string"},"createdAt":{"format":"date-time","type":"string"},"reviewedAt":{"format":"date-time","type":"string","nullable":true},"reviewedBy":{"nullable":true,"description":"The admin who marked it reviewed.","type":"object","allOf":[{"$ref":"#/components/schemas/AdminReportPartyDto"}]},"note":{"type":"string","nullable":true}},"required":["id","ad","merchant","customer","reason","text","status","createdAt","reviewedAt","reviewedBy","note"]},"AdminReportPageDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminReportDto"}},"page":{"type":"number","example":1},"limit":{"type":"number","example":20},"total":{"type":"number","example":42},"openCount":{"type":"number","description":"Open reports, for the menu badge.","example":3}},"required":["items","page","limit","total","openCount"]},"MarkReportReviewedDto":{"type":"object","properties":{"note":{"type":"string","description":"Optional; what was done, 3–500 characters."}}},"ErrorResponse":{"type":"object","required":["code","message","requestId"],"properties":{"code":{"type":"string","enum":["VALIDATION_FAILED","INVALID_JSON","UNAUTHORIZED","FORBIDDEN","ACCOUNT_DISABLED","NOT_FOUND","CONFLICT","PAYLOAD_TOO_LARGE","TOO_MANY_REQUESTS","MOBILE_NOT_REGISTERED","MOBILE_ALREADY_REGISTERED","MOBILE_UNCHANGED","EMAIL_ALREADY_REGISTERED","USERNAME_TAKEN","CR_ALREADY_REGISTERED","INVALID_CREDENTIALS","ACCOUNT_UNDER_REVIEW","ACCOUNT_REJECTED","PASSWORD_INCORRECT","PASSWORD_UNCHANGED","RESET_TOKEN_INVALID","CITY_NOT_AVAILABLE","CATEGORY_NOT_AVAILABLE","CATEGORY_NAME_TAKEN","CATEGORY_HAS_ADS","OTP_INVALID","OTP_EXPIRED","OTP_TOO_MANY_ATTEMPTS","OTP_RESEND_TOO_SOON","VERIFICATION_INVALID","SMS_SEND_FAILED","FILE_REQUIRED","FILE_TOO_LARGE","FILE_TYPE_NOT_ALLOWED","FILE_NOT_AVAILABLE","PACKAGE_NOT_AVAILABLE","PACKAGE_NAME_TAKEN","PACKAGE_IN_USE","CONTACT_MESSAGE_REPLIED","SUBSCRIPTION_ALREADY_ACTIVE","INSUFFICIENT_BALANCE","ROLE_NAME_TAKEN","ROLE_IN_USE","SYSTEM_ROLE_LOCKED","SELF_CHANGE_NOT_ALLOWED","ROLE_NOT_AVAILABLE","SUPER_ADMIN_ROLE_RESERVED","SUPER_ADMIN_PROTECTED","AD_NOT_AVAILABLE","MERCHANT_NOT_AVAILABLE","ALREADY_REPORTED","AD_STATUS_INVALID","MERCHANT_REVIEW_INVALID","REPORT_ALREADY_REVIEWED","AD_FEE_REQUIRED","IDEMPOTENCY_KEY_REUSED","INTERNAL_ERROR"],"description":"Stable error code. Clients branch on this.","example":"NOT_FOUND"},"message":{"type":"string","description":"Translated message for display.","example":"The requested item was not found"},"details":{"type":"array","description":"Field problems, only for `VALIDATION_FAILED`.","items":{"type":"object","required":["field","code","message"],"properties":{"field":{"type":"string","description":"Dotted path, for example `address.city`.","example":"mobile"},"code":{"type":"string","description":"The rule that failed, e.g. `isSaudiMobileRequired` (empty) or `isSaudiMobile` (invalid).","example":"isSaudiMobileRequired"},"message":{"type":"string","example":"Mobile number must be entered."}}}},"requestId":{"type":"string","description":"Same as the `X-Request-Id` response header.","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}},"parameters":{"AcceptLanguage":{"name":"Accept-Language","in":"header","required":false,"description":"Language of messages. Arabic by default.","schema":{"type":"string","enum":["ar","en"],"default":"ar"}}}}}