{"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 is required."}],"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 (listing media, logos, avatars) need nothing else. Private\nfiles (commercial registrations, chat attachments) 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/cities":{"get":{"description":"The active cities, for city pickers (registration, listings, 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/auth/register/otp":{"post":{"description":"Checks the registration form, then sends a 4-digit code to the mobile. Nothing is saved yet: send the same form again with the code to `register`. `MOBILE_ALREADY_REGISTERED` means the app should offer login. Call again to resend once `resendAfterSeconds` have passed.","operationId":"CustomerAuth_requestRegister","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpSentDto"}}}},"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 is required."}],"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 already exists. Please verify 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":"Send a registration code","tags":["Customer · Auth"],"x-public":true,"security":[]}},"/v1/customer/auth/register":{"post":{"description":"The registration form again, with the code: creates the account and starts a session (the app then shows Home).","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/CustomerSessionDto"}}}},"400":{"description":"OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"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 is required."}],"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 already exists. Please verify 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_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":"Register with the code","tags":["Customer · Auth"],"x-public":true,"x-session-token":{"namespace":"customer","field":"accessToken"},"security":[]}},"/v1/customer/auth/login/otp":{"post":{"description":"Sends a 4-digit code to a registered, active number. `MOBILE_NOT_REGISTERED` means the app should offer registration.","operationId":"CustomerAuth_requestLogin","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/OtpSentDto"}}}},"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 is required."}],"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 verify that 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 login code","tags":["Customer · Auth"],"x-public":true,"security":[]}},"/v1/customer/auth/login":{"post":{"description":"Checks the login code and starts a session.","operationId":"CustomerAuth_login","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomerSessionDto"}}}},"400":{"description":"OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"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 is required."}],"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 verify that 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":"Log in with the code","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/AccountDto"}}}},"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/AccountDto"}}}},"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 is required."}],"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/mobile/otp":{"post":{"description":"Step 1 of changing the mobile number: the code goes to the new number. Call again to resend once `resendAfterSeconds` have passed.","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/OtpSentDto"}}}},"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 is required."}],"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 already exists. Please verify 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/mobile":{"post":{"description":"Step 2: checks the code sent to the new number and swaps it in; 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/AccountDto"}}}},"400":{"description":"MOBILE_UNCHANGED, 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"}},"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 is required."}],"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 already exists. Please verify 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/files":{"post":{"description":"Send the file as multipart/form-data in the `file` field. Its type is checked from its bytes, not its name. Then pass the returned `id` to the endpoint that uses it; files unused after 24 hours are deleted.\n\n- `customer_avatar`: PNG, JPG, up to 5 MB, public\n- `chat_image`: PNG, JPG, WEBP, up to 5 MB, private\n- `chat_file`: PDF, up to 10 MB, private\n- `chat_voice`: M4A, AAC, up to 3 MB, private","operationId":"CustomerFiles_upload","parameters":[{"name":"purpose","required":true,"in":"query","schema":{"enum":["customer_avatar","chat_image","chat_file","chat_voice"],"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDto"}}}},"400":{"description":"FILE_REQUIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_REQUIRED":{"value":{"code":"FILE_REQUIRED","message":"No file was attached.","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 is required."}],"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"}}}}}},"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":"Upload a file","tags":["Customer · Files"],"security":[{"customer":[]}]}},"/v1/advertiser/auth/register/files":{"post":{"description":"Before the account exists, the establishment form's files: `commercial_registration` (PDF, PNG or JPG, up to 10 MB) or `establishment_logo` (PNG or JPG, up to 5 MB). Send the returned `id` as `crFileId` / `logoFileId` with the form. Files not used within 24 hours are deleted. At most 20 uploads per hour from one network.","operationId":"AdvertiserAuth_uploadRegistrationFile","parameters":[{"name":"purpose","required":true,"in":"query","schema":{"type":"string","enum":["establishment_logo","commercial_registration"]}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDto"}}}},"400":{"description":"FILE_REQUIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_REQUIRED":{"value":{"code":"FILE_REQUIRED","message":"No file was attached.","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 is required."}],"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":"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":"Upload a registration file","tags":["Advertiser · Auth"],"x-public":true,"security":[]}},"/v1/advertiser/auth/register/individual/otp":{"post":{"description":"Checks the individual form (step 1), then sends a 4-digit code to the mobile. Nothing is saved yet: send the same form again with the code to `register/individual`.","operationId":"AdvertiserAuth_requestIndividual","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterIndividualOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpSentDto"}}}},"400":{"description":"CITY_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CITY_NOT_AVAILABLE":{"value":{"code":"CITY_NOT_AVAILABLE","message":"This city is not available. Please choose another.","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 is required."}],"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 already exists. Please verify 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":"Send an individual registration code","tags":["Advertiser · Auth"],"x-public":true,"security":[]}},"/v1/advertiser/auth/register/individual":{"post":{"description":"The individual form again, with the code: creates the account and starts a session. `nextStep` tells the app where to go.","operationId":"AdvertiserAuth_registerIndividual","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterIndividualDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdvertiserSessionDto"}}}},"400":{"description":"CITY_NOT_AVAILABLE, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"CITY_NOT_AVAILABLE":{"value":{"code":"CITY_NOT_AVAILABLE","message":"This city is not available. Please choose another.","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 is required."}],"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 already exists. Please verify 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_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":"Register an individual with the code","tags":["Advertiser · Auth"],"x-public":true,"x-session-token":{"namespace":"advertiser","field":"accessToken"},"security":[]}},"/v1/advertiser/auth/register/establishment/otp":{"post":{"description":"Checks the establishment form (step 1), including its uploaded files, then sends a 4-digit code to the manager mobile. Nothing is saved yet: send the same form again with the code to `register/establishment`.","operationId":"AdvertiserAuth_requestEstablishment","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterEstablishmentOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OtpSentDto"}}}},"400":{"description":"CITY_NOT_AVAILABLE, FILE_NOT_AVAILABLE, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"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 is required."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, 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 already exists. Please verify 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"}},"CR_ALREADY_REGISTERED":{"value":{"code":"CR_ALREADY_REGISTERED","message":"The Commercial Registration number 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":"Send an establishment registration code","tags":["Advertiser · Auth"],"x-public":true,"security":[]}},"/v1/advertiser/auth/register/establishment":{"post":{"description":"The establishment form again, with the code: creates the account, attaches its files and starts a session.","operationId":"AdvertiserAuth_registerEstablishment","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterEstablishmentDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdvertiserSessionDto"}}}},"400":{"description":"CITY_NOT_AVAILABLE, FILE_NOT_AVAILABLE, OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"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"}},"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 is required."}],"requestId":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"}}}}}},"409":{"description":"MOBILE_ALREADY_REGISTERED, 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 already exists. Please verify 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"}},"CR_ALREADY_REGISTERED":{"value":{"code":"CR_ALREADY_REGISTERED","message":"The Commercial Registration number is already registered.","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":"Register an establishment with the code","tags":["Advertiser · Auth"],"x-public":true,"x-session-token":{"namespace":"advertiser","field":"accessToken"},"security":[]}},"/v1/advertiser/auth/login/otp":{"post":{"description":"Sends a 4-digit code to a registered, active advertiser number. `MOBILE_NOT_REGISTERED` means the app should offer account creation.","operationId":"AdvertiserAuth_requestLogin","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/OtpSentDto"}}}},"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 is required."}],"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 verify that 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 login code","tags":["Advertiser · Auth"],"x-public":true,"security":[]}},"/v1/advertiser/auth/login":{"post":{"description":"Checks the login code and starts a session.","operationId":"AdvertiserAuth_login","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyOtpDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdvertiserSessionDto"}}}},"400":{"description":"OTP_INVALID, OTP_EXPIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"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 is required."}],"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 verify that 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":"Log in with the code","tags":["Advertiser · Auth"],"x-public":true,"x-session-token":{"namespace":"advertiser","field":"accessToken"},"security":[]}},"/v1/advertiser/auth/logout":{"post":{"description":"Ends the session of the token sent; it stops working immediately. Other devices stay signed in.","operationId":"AdvertiserSession_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":["Advertiser · Auth"],"security":[{"advertiser":[]}]}},"/v1/advertiser/account":{"get":{"operationId":"AdvertiserAccount_get","parameters":[{"$ref":"#/components/parameters/AcceptLanguage"}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDto"}}}},"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":["Advertiser · Account"],"security":[{"advertiser":[]}]},"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":"AdvertiserAccount_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/AccountDto"}}}},"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 is required."}],"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":["Advertiser · Account"],"security":[{"advertiser":[]}]},"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":"AdvertiserAccount_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":["Advertiser · Account"],"security":[{"advertiser":[]}]}},"/v1/advertiser/account/mobile/otp":{"post":{"description":"Step 1 of changing the mobile number: the code goes to the new number. Call again to resend once `resendAfterSeconds` have passed.","operationId":"AdvertiserAccount_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/OtpSentDto"}}}},"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 is required."}],"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 already exists. Please verify 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":["Advertiser · Account"],"security":[{"advertiser":[]}]}},"/v1/advertiser/account/mobile":{"post":{"description":"Step 2: checks the code sent to the new number and swaps it in; 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":"AdvertiserAccount_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/AccountDto"}}}},"400":{"description":"MOBILE_UNCHANGED, 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"}},"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 is required."}],"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 already exists. Please verify 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":["Advertiser · Account"],"security":[{"advertiser":[]}]}},"/v1/advertiser/cities":{"get":{"description":"The active cities, for city pickers (registration, listings, 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":"AdvertiserCities_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":["Advertiser · Cities"],"x-public":true,"security":[]}},"/v1/advertiser/files":{"post":{"description":"Send the file as multipart/form-data in the `file` field. Its type is checked from its bytes, not its name. Then pass the returned `id` to the endpoint that uses it; files unused after 24 hours are deleted.\n\n- `listing_image`: PNG, JPG, up to 5 MB, public\n- `listing_video`: MP4, MOV, up to 20 MB, public\n- `advertiser_avatar`: PNG, JPG, up to 5 MB, public\n- `establishment_logo`: PNG, JPG, up to 5 MB, public\n- `commercial_registration`: PDF, PNG, JPG, up to 10 MB, private\n- `chat_image`: PNG, JPG, WEBP, up to 5 MB, private\n- `chat_file`: PDF, up to 10 MB, private\n- `chat_voice`: M4A, AAC, up to 3 MB, private","operationId":"AdvertiserFiles_upload","parameters":[{"name":"purpose","required":true,"in":"query","schema":{"enum":["listing_image","listing_video","advertiser_avatar","establishment_logo","commercial_registration","chat_image","chat_file","chat_voice"],"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDto"}}}},"400":{"description":"FILE_REQUIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_REQUIRED":{"value":{"code":"FILE_REQUIRED","message":"No file was attached.","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 is required."}],"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"}}}}}},"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":"Upload a file","tags":["Advertiser · Files"],"security":[{"advertiser":[]}]}},"/v1/admin/files":{"post":{"description":"Send the file as multipart/form-data in the `file` field. Its type is checked from its bytes, not its name. Then pass the returned `id` to the endpoint that uses it; files unused after 24 hours are deleted.\n\n- `establishment_logo`: PNG, JPG, up to 5 MB, public\n- `commercial_registration`: PDF, PNG, JPG, up to 10 MB, private\n- `banner_media`: PNG, JPG, WEBP, MP4, up to 10 MB, public\n- `category_icon`: PNG, JPG, WEBP, up to 2 MB, public\n- `package_icon`: PNG, JPG, WEBP, up to 2 MB, public\n- `admin_avatar`: PNG, JPG, WEBP, up to 5 MB, public","operationId":"AdminFiles_upload","parameters":[{"name":"purpose","required":true,"in":"query","schema":{"enum":["establishment_logo","commercial_registration","banner_media","category_icon","package_icon","admin_avatar"],"type":"string"}},{"$ref":"#/components/parameters/AcceptLanguage"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileDto"}}}},"400":{"description":"FILE_REQUIRED, VALIDATION_FAILED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"FILE_REQUIRED":{"value":{"code":"FILE_REQUIRED","message":"No file was attached.","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 is required."}],"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"}}}}}},"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":"Upload a file","tags":["Admin · Files"],"security":[{"admin":[]}]}}},"info":{"title":"Maqsed API","description":"One API for the three Maqsed clients: the customer interface of the app (`/v1/customer`), the advertiser interface of the app (`/v1/advertiser`), 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).\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 · Auth"},{"name":"Customer · Cities"},{"name":"Customer · Files"},{"name":"Advertiser · Account"},{"name":"Advertiser · Auth"},{"name":"Advertiser · Cities"},{"name":"Advertiser · Files"},{"name":"Admin · Files"},{"name":"System"}],"servers":[],"components":{"securitySchemes":{"customer":{"scheme":"bearer","bearerFormat":"opaque session token","type":"http","description":"Session token from the customer sign-in."},"advertiser":{"scheme":"bearer","bearerFormat":"opaque session token","type":"http","description":"Session token from the advertiser 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"]},"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"]},"RegisterOtpDto":{"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"]},"OtpSentDto":{"type":"object","properties":{"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}},"required":["expiresAt","resendAfterSeconds"]},"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`."},"code":{"type":"string","description":"The code from the SMS (`1234` while the fake SMS sender is on).","example":"1234"},"deviceName":{"type":"string","description":"A name for this device, shown in the signed-in devices list.","example":"iPhone 16","maxLength":100}},"required":["name","mobile","acceptTerms","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)."},"gender":{"type":"string","nullable":true,"enum":["male","female"]},"dateOfBirth":{"type":"string","nullable":true,"description":"`YYYY-MM-DD`.","example":"1995-04-12"},"language":{"type":"string","description":"Used when a request names no language, and for SMS.","example":"ar","enum":["ar","en"]},"createdAt":{"format":"date-time","type":"string"}},"required":["id","name","mobile","email","avatarUrl","gender","dateOfBirth","language","createdAt"]},"CustomerSessionDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"The session token, shown only once. Send it as `Authorization: Bearer …`.","example":"mq_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"]},"VerifyOtpDto":{"type":"object","properties":{"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX` (`5…` and `+9665…` are accepted too).","example":"0551234567"},"code":{"type":"string","description":"The code from the SMS (`1234` while the fake SMS sender is on).","example":"1234"},"deviceName":{"type":"string","description":"A name for this device, shown in the signed-in devices list.","example":"iPhone 16","maxLength":100}},"required":["mobile","code"]},"AccountDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"language":{"description":"Used when a request sends no language.","example":"ar","enum":["ar","en"],"type":"string"},"createdAt":{"format":"date-time","type":"string"}},"required":["id","mobile","language","createdAt"]},"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":{"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX` (`5…` and `+9665…` are accepted too).","example":"0551234567"},"code":{"type":"string","description":"The code sent to the new number (`1234` while the fake SMS sender is on).","example":"1234"}},"required":["mobile","code"]},"FileDto":{"type":"object","properties":{"id":{"type":"string","description":"Pass this id to the endpoint that uses the file (listing, profile, logo, …).","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"purpose":{"example":"listing_image","enum":["listing_image","listing_video","customer_avatar","advertiser_avatar","establishment_logo","commercial_registration","chat_image","chat_file","chat_voice","banner_media","category_icon","package_icon","admin_avatar"],"type":"string"},"name":{"type":"string","description":"The name the file was uploaded with.","example":"logo.png"},"mimeType":{"type":"string","example":"image/png"},"size":{"type":"number","description":"Size in bytes.","example":48213},"url":{"type":"string","description":"Where to download it. Public files have a permanent URL; private ones\n(documents, chat files) a signed URL that expires at `urlExpiresAt`.","example":"https://api.maqsed.sa/files/0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"urlExpiresAt":{"type":"string","description":"When a private file's URL stops working; absent for public files."}},"required":["id","purpose","name","mimeType","size","url"]},"RegisterIndividualOtpDto":{"type":"object","properties":{"name":{"type":"string","description":"Letters and numbers only, 2–100 characters.","example":"سارة أحمد"},"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX`; the login number.","example":"0551234567"},"email":{"type":"string","description":"Optional; unique among advertisers, at most 100 characters.","example":"sara@example.com"},"cityId":{"type":"string","description":"From `GET /v1/advertiser/cities`."},"acceptTerms":{"type":"boolean","description":"The Terms and Conditions checkbox; must be `true`."}},"required":["name","mobile","cityId","acceptTerms"]},"RegisterIndividualDto":{"type":"object","properties":{"name":{"type":"string","description":"Letters and numbers only, 2–100 characters.","example":"سارة أحمد"},"mobile":{"type":"string","description":"Saudi mobile number, `05XXXXXXXX`; the login number.","example":"0551234567"},"email":{"type":"string","description":"Optional; unique among advertisers, at most 100 characters.","example":"sara@example.com"},"cityId":{"type":"string","description":"From `GET /v1/advertiser/cities`."},"acceptTerms":{"type":"boolean","description":"The Terms and Conditions checkbox; must be `true`."},"code":{"type":"string","description":"The code from the SMS (`1234` while the fake SMS sender is on).","example":"1234"},"deviceName":{"type":"string","description":"A name for this device, shown in the signed-in devices list.","example":"iPhone 16","maxLength":100}},"required":["name","mobile","cityId","acceptTerms","code"]},"EstablishmentDto":{"type":"object","properties":{"name":{"type":"string","example":"مؤسسة المقصد للتجارة"},"crNumber":{"type":"string","example":"1010123456"},"taxNumber":{"type":"string","example":"300000000000003"},"address":{"type":"string","nullable":true},"logoUrl":{"type":"string","nullable":true},"crDocument":{"description":"Private: a signed link that expires.","allOf":[{"$ref":"#/components/schemas/FileDto"}]}},"required":["name","crNumber","taxNumber","address","logoUrl","crDocument"]},"AdvertiserDto":{"type":"object","properties":{"id":{"type":"string","example":"0199a3c4-5b6e-7f80-9a1b-2c3d4e5f6a7b"},"accountType":{"type":"string","enum":["individual","establishment"]},"displayName":{"type":"string","description":"The establishment's name, or the individual's.","example":"مؤسسة المقصد للتجارة"},"name":{"type":"string","description":"The individual's full name, or the account manager's.","example":"خالد العتيبي"},"mobile":{"type":"string","description":"E.164.","example":"+966551234567"},"email":{"type":"string","nullable":true},"city":{"$ref":"#/components/schemas/CityDto"},"language":{"type":"string","example":"ar","enum":["ar","en"]},"createdAt":{"format":"date-time","type":"string"},"establishment":{"nullable":true,"description":"Null for individuals.","type":"object","allOf":[{"$ref":"#/components/schemas/EstablishmentDto"}]}},"required":["id","accountType","displayName","name","mobile","email","city","language","createdAt","establishment"]},"AdvertiserSessionDto":{"type":"object","properties":{"accessToken":{"type":"string","description":"The session token, shown only once. Send it as `Authorization: Bearer …`.","example":"mq_adv_3q2-7wEvxN1c9kP0YyR5bA8dF6gH4jL2mZ1xV7sT0uQ"},"advertiser":{"$ref":"#/components/schemas/AdvertiserDto"},"nextStep":{"description":"Where the app goes next: `packages` after registration (the design's\nstep 3; `identity`, step 2, once Nafath exists), `home` after login.","example":"packages","enum":["packages","home"],"type":"string"}},"required":["accessToken","advertiser","nextStep"]},"RegisterEstablishmentOtpDto":{"type":"object","properties":{"establishmentName":{"type":"string","description":"2–150 characters: Arabic or English letters, digits and spaces.","example":"مؤسسة المقصد للتجارة"},"crNumber":{"type":"string","description":"Commercial Registration number, 10 digits; unique.","example":"1010123456"},"name":{"type":"string","description":"The account manager: letters and spaces, 2–100 characters.","example":"خالد العتيبي"},"mobile":{"type":"string","description":"The account manager's mobile, `05XXXXXXXX`; the login number.","example":"0551234567"},"email":{"type":"string","description":"Optional; unique among advertisers, at most 100 characters.","example":"info@company.sa"},"cityId":{"type":"string","description":"From `GET /v1/advertiser/cities`."},"taxNumber":{"type":"string","description":"VAT number: 15 digits starting and ending with 3.","example":"300000000000003"},"address":{"type":"string","description":"Optional (not on the design's form; the profile can add it).","example":"طريق الملك فهد، حي العليا"},"crFileId":{"type":"string","description":"The Commercial Registration document: the `id` from\n`POST /v1/advertiser/auth/register/files?purpose=commercial_registration`."},"logoFileId":{"type":"string","description":"Optional logo: the `id` from\n`POST /v1/advertiser/auth/register/files?purpose=establishment_logo`."},"acceptTerms":{"type":"boolean","description":"Terms and Conditions and Privacy Policy; must be `true`."}},"required":["establishmentName","crNumber","name","mobile","cityId","taxNumber","crFileId","acceptTerms"]},"RegisterEstablishmentDto":{"type":"object","properties":{"establishmentName":{"type":"string","description":"2–150 characters: Arabic or English letters, digits and spaces.","example":"مؤسسة المقصد للتجارة"},"crNumber":{"type":"string","description":"Commercial Registration number, 10 digits; unique.","example":"1010123456"},"name":{"type":"string","description":"The account manager: letters and spaces, 2–100 characters.","example":"خالد العتيبي"},"mobile":{"type":"string","description":"The account manager's mobile, `05XXXXXXXX`; the login number.","example":"0551234567"},"email":{"type":"string","description":"Optional; unique among advertisers, at most 100 characters.","example":"info@company.sa"},"cityId":{"type":"string","description":"From `GET /v1/advertiser/cities`."},"taxNumber":{"type":"string","description":"VAT number: 15 digits starting and ending with 3.","example":"300000000000003"},"address":{"type":"string","description":"Optional (not on the design's form; the profile can add it).","example":"طريق الملك فهد، حي العليا"},"crFileId":{"type":"string","description":"The Commercial Registration document: the `id` from\n`POST /v1/advertiser/auth/register/files?purpose=commercial_registration`."},"logoFileId":{"type":"string","description":"Optional logo: the `id` from\n`POST /v1/advertiser/auth/register/files?purpose=establishment_logo`."},"acceptTerms":{"type":"boolean","description":"Terms and Conditions and Privacy Policy; must be `true`."},"code":{"type":"string","description":"The code from the SMS (`1234` while the fake SMS sender is on).","example":"1234"},"deviceName":{"type":"string","description":"A name for this device, shown in the signed-in devices list.","example":"iPhone 16","maxLength":100}},"required":["establishmentName","crNumber","name","mobile","cityId","taxNumber","crFileId","acceptTerms","code"]},"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","FILE_REQUIRED","FILE_TOO_LARGE","FILE_TYPE_NOT_ALLOWED","MOBILE_NOT_REGISTERED","MOBILE_ALREADY_REGISTERED","MOBILE_UNCHANGED","EMAIL_ALREADY_REGISTERED","CR_ALREADY_REGISTERED","CITY_NOT_AVAILABLE","FILE_NOT_AVAILABLE","OTP_INVALID","OTP_EXPIRED","OTP_TOO_MANY_ATTEMPTS","OTP_RESEND_TOO_SOON","SMS_SEND_FAILED","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 is required."}}}},"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"}}}}}