- Frontend removed
budget_rangefrom Brand global settings. - Budget should now be campaign-level only (e.g. campaign brief/budget flows).
- Brand Settings now has:
Generaltab (owner + company profile)Email Verificationtab (company email OTP verification)
GET /api/brands/settings/profile
Use this as the current Brand settings profile endpoint (frontend expects backend to implement/update this exact contract).
Hydrates Brand Settings General tab.
export interface BrandSettingsProfileResponse {
owner_name: string;
owner_title: string | null;
company_name: string;
brand_name: string | null;
industry: string | null;
account_email: string | null; // auth/login email (signup email)
company_email: string | null; // editable business contact email
company_email_verified: boolean;
company_email_verified_at: string | null;
}{
"owner_name": "Jane Doe",
"owner_title": "Marketing Manager",
"company_name": "Acme Group Pte Ltd",
"brand_name": "Acme Beauty",
"industry": "Beauty & Personal Care",
"account_email": "jane@acme.com",
"company_email": "marketing@acmebeauty.com",
"company_email_verified": true,
"company_email_verified_at": "2026-02-10T14:42:10.000Z"
}PUT /api/brands/settings/profile
Use this as the current Brand settings update endpoint (same path, contract extended with new fields).
export interface UpdateBrandSettingsProfileRequest {
owner_name: string;
owner_title?: string | null;
company_name: string;
brand_name?: string | null;
industry?: string | null;
}export interface UpdateBrandSettingsProfileResponse {
success: boolean;
data: BrandSettingsProfileResponse;
}- Do not include
budget_rangein this endpoint anymore. owner_namemaps to account owner display name.account_emailis read-only in this endpoint.company_emailis separate fromaccount_email.- If no company email is set, frontend defaults company email input to
account_email.
GET /api/brands/verification/company-email
export interface CompanyEmailVerificationStatus {
company_email: string | null;
is_verified: boolean;
verified_at: string | null; // ISO timestamp
pending_verification: boolean;
otp_expires_at: string | null; // ISO timestamp
}{
"company_email": "marketing@acmebeauty.com",
"is_verified": false,
"verified_at": null,
"pending_verification": true,
"otp_expires_at": "2026-02-10T14:40:00.000Z"
}POST /api/brands/verification/company-email/request-otp
export interface InitiateCompanyEmailVerificationRequest {
company_email: string;
}export interface InitiateCompanyEmailVerificationResponse {
success: boolean;
data: {
company_email: string;
otp_expires_at: string; // ISO timestamp
cooldown_seconds: number;
};
}POST /api/brands/verification/company-email/verify-otp
export interface VerifyCompanyEmailOtpRequest {
company_email: string;
otp_code: string; // 6 digits
}export interface VerifyCompanyEmailOtpResponse {
success: boolean;
data: {
company_email: string;
is_verified: boolean;
verified_at: string; // ISO timestamp
};
}- OTP should be numeric and 6 digits.
- OTP expiration recommended: 10 minutes.
- Max attempts recommended: 5 attempts per OTP.
- Request cooldown recommended: 60 seconds between OTP sends.
- If company email changes, previous verification should be invalidated.
- All endpoints require authenticated Brand user context.
export interface ApiErrorResponse {
success: false;
error: string;
code?: string;
details?: string;
}Recommended error codes:
INVALID_EMAILOTP_EXPIREDOTP_INVALIDOTP_MAX_ATTEMPTS_EXCEEDEDOTP_RATE_LIMITEDUNAUTHORIZED
Generaltab updates profile settings and owner/company metadata.Email Verificationtab:- Enter company email
- Request OTP
- Verify OTP
- Show verification status badge + timestamps