{"openapi":"3.1.0","info":{"title":"Yadzi API","version":"1.0.0","description":"The web ↔ mobile contract. All app endpoints are versioned under /api/v1."},"servers":[{"url":"https://www.yadzi.ma"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Health":{"type":"object","properties":{"status":{"type":"string","enum":["ok"]},"service":{"type":"string"},"version":{"type":"string"},"time":{"type":"string"}},"required":["status","service","version","time"]},"TokenPair":{"type":"object","properties":{"access_token":{"type":"string"},"refresh_token":{"type":"string"},"expires_in":{"type":"number"}},"required":["access_token","refresh_token","expires_in"]},"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"next_step":{"type":"string"},"details":{}},"required":["code","message"]}},"required":["error"]},"RegisterRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"display_name":{"type":"string","minLength":1}},"required":["email","password","display_name"]},"LoginRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":1}},"required":["email","password"]},"RefreshRequest":{"type":"object","properties":{"refresh_token":{"type":"string"}},"required":["refresh_token"]},"VerifyEmailRequest":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]},"RequestResetRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]},"ResetPasswordRequest":{"type":"object","properties":{"token":{"type":"string"},"password":{"type":"string","minLength":8}},"required":["token","password"]},"Me":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"status":{"type":"string"},"email_verified":{"type":"boolean"},"phone_verified":{"type":"boolean"},"kyc_status":{"type":"string"},"profile":{"type":["object","null"],"properties":{"display_name":{"type":"string"},"city":{"type":["string","null"]},"rating_avg":{"type":"number"},"rating_count":{"type":"number"},"is_top_seller":{"type":"boolean"}},"required":["display_name","city","rating_avg","rating_count","is_top_seller"]}},"required":["id","email","role","status","email_verified","phone_verified","kyc_status","profile"]}},"parameters":{}},"paths":{"/api/v1/health":{"get":{"summary":"Liveness check (public)","tags":["system"],"responses":{"200":{"description":"Service is up","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/api/v1/auth/register":{"post":{"summary":"Register with email + password","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}}},"responses":{"201":{"description":"Account created; tokens issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}},"409":{"description":"Email already in use","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/login":{"post":{"summary":"Log in with email + password","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Authenticated; tokens issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/refresh":{"post":{"summary":"Rotate refresh token (mobile)","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}}},"responses":{"200":{"description":"New token pair","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}},"401":{"description":"Invalid or expired refresh token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/verify-email":{"post":{"summary":"Verify email with a token","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}}},"responses":{"200":{"description":"Email verified","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["verified"]}},"required":["status"]}}}},"400":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/request-reset":{"post":{"summary":"Request a password-reset link","description":"Always returns 202, even for an unknown address, so the response cannot be used to enumerate accounts.","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestResetRequest"}}}},"responses":{"202":{"description":"Accepted — a link is sent if the account exists","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["sent"]}},"required":["status"]}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/reset-password":{"post":{"summary":"Set a new password with a reset token","description":"Revokes all refresh tokens for the account on success.","tags":["auth"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}}},"responses":{"200":{"description":"Password changed","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["reset"]}},"required":["status"]}}}},"400":{"description":"Invalid or expired token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/auth/social/{provider}":{"post":{"summary":"Native social token-exchange (google|apple) → our JWT","tags":["auth"],"parameters":[{"schema":{"type":"string","enum":["google","apple"]},"required":true,"name":"provider","in":"path"}],"responses":{"200":{"description":"Authenticated; tokens issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenPair"}}}},"501":{"description":"Provider not yet configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/me":{"get":{"summary":"Current authenticated user (T1)","tags":["account"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"The authenticated user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Not authenticated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"webhooks":{}}