Profile Customization — Vendor
Vendor self-service of the seller page and account details: logo, banner, bio, business identity/contact/address, the cover-image carousel, and the payout bank account.
Vendor self-service of the seller page and account details: the vendor's logo, banner, bio, business identity/contact/address, the cover-image carousel, and the payout bank account. All endpoints are scoped to the session's active vendor; a vendor can only manage their own data.
Sources:
api-modules/vendor/src/controllers/vendor-profile.controller.ts(profile),api-modules/vendor/src/controllers/vendor-customization.controller.ts(cover images),api-modules/vendor/src/controllers/vendor-bank-account.controller.ts(bank account).Cover images are stored in the
vendor_cover_imagechild table (one row per image, with asortOrder). Logo, banner, bio and the business/contact/address fields live onvendor_profile; the bank account onvendor_bank_account(one per vendor). The public seller page reads the profile fields back viaGET /store/vendors/:slug(see Store API → Vendors); the bank account is never public.slugis intentionally not editable here (it is the public URL).
Conventions
Authentication
| Endpoint group | Auth |
|---|---|
GET /vendor/profile | vendor session |
PUT /vendor/profile | vendor session |
GET /vendor/profile/cover-images | vendor session |
PUT /vendor/profile/cover-images | vendor session |
GET /vendor/bank-account | vendor session |
PUT /vendor/bank-account | vendor session |
The vendor is resolved from the session's active vendor; there is no vendor id in the path.
Upload flow
Image binaries (logo, banner, cover images) are not uploaded here. The client first uploads each file via the storage presigned-upload flow (POST /storage/presigned → PUT to the returned URL), then sends the resulting storage key(s) to the relevant endpoint. Only the key is persisted.
A vendor may set at most 10 cover images.
GET /vendor/profile
Return the active vendor's editable seller-page profile.
{
"data": {
"logo": "https://cdn/.../logo.png",
"banner": "https://cdn/.../banner.jpg",
"bio": "Handmade leather goods since 2012.",
"businessName": "Acme Leather",
"businessEmail": "hello@acme.test",
"businessPhone": "+91 98765 43210",
"street": "12 Bandra Kurla Complex",
"city": "Mumbai",
"state": "MH",
"zip": "400051",
"country": "IN",
"taxId": "27ABCDE1234F1Z5"
}
}| Field | Type | Notes |
|---|---|---|
logo | string | null | Storage key (or absolute URL). null when unset. |
banner | string | null | Storage key (or absolute URL). null when unset. |
bio | string | The seller-page description (business_description). |
businessName | string | Display name; mirrored onto the storefront name. |
businessEmail | string | Business contact email. |
businessPhone | string | Business contact phone. |
street / city / state / zip / country | string | null | Business address parts. city/state/country show on the public seller page. |
taxId | string | null | Tax registration number (GSTIN / VAT / …). |
PUT /vendor/profile
Partial update of the profile. Omit a field to leave it unchanged; send null to clear a nullable field. bio, businessName, businessEmail and businessPhone are required and cannot be cleared (only replaced with a non-empty value). At least one field must be present. slug is not editable.
Request body (all fields optional):
{
"logo": "uploads/vendors/v1/logo.png", // null clears
"banner": "uploads/vendors/v1/banner.jpg", // null clears
"bio": "Handmade leather goods since 2012.",
"businessName": "Acme Leather",
"businessEmail": "hello@acme.test",
"businessPhone": "+91 98765 43210",
"street": "12 Bandra Kurla Complex", // null clears
"city": "Mumbai", // null clears
"state": "MH", // null clears
"zip": "400051", // null clears
"country": "IN", // null clears
"taxId": "27ABCDE1234F1Z5" // null clears
}| Field | Type | Notes |
|---|---|---|
logo | string | null (optional) | Storage key from the presigned flow. null clears it. Updating it also syncs the logo onto the vendor's product-feed record. |
banner | string | null (optional) | Storage key from the presigned flow. null clears it. |
bio | string (optional) | Non-empty; max 2000 chars. |
businessName | string (optional) | Non-empty; max 255. Also updates the storefront name (and the directory search index). |
businessEmail | string (optional) | Valid email; max 255. |
businessPhone | string (optional) | Non-empty; max 50. |
street / city / state / zip / country | string | null (optional) | Non-empty when set; null clears. |
taxId | string | null (optional) | Non-empty when set; null clears. |
Returns the updated profile in the same shape as the GET. An empty body (no recognised field) is rejected with 400. Any profile change busts the storefront seller-page cache immediately.
GET /vendor/profile/cover-images
List the active vendor's cover carousel, in display order.
{
"data": [
{ "id": "cov_1", "url": "https://cdn/.../cover-1.jpg", "sortOrder": 0 },
{ "id": "cov_2", "url": "https://cdn/.../cover-2.jpg", "sortOrder": 1 }
]
}PUT /vendor/profile/cover-images
Wholesale-replace the carousel. The full desired set is sent every time; the previous set is replaced atomically.
Request body:
{
"images": [
{ "url": "https://cdn/.../cover-1.jpg", "sortOrder": 0 },
{ "url": "https://cdn/.../cover-2.jpg", "sortOrder": 1 }
]
}| Field | Type | Notes |
|---|---|---|
images | array (max 10) | Full replacement set. An empty array clears the carousel. |
images[].url | string | The storage key (or absolute URL) returned by the presigned-upload flow. |
images[].sortOrder | int ≥ 0 | Display order. |
Returns the persisted rows in the same shape as the GET. A set larger than 10 is rejected with 400.
GET /vendor/bank-account
Return the active vendor's payout bank account, or null in data when none is set up yet. Never part of any public/store surface.
{
"data": {
"bankName": "HDFC Bank",
"accountHolderName": "Acme Leather Pvt Ltd",
"accountNumber": "50100123456789",
"routingNumber": "HDFC0000123",
"swiftCode": "HDFCINBB"
}
}PUT /vendor/bank-account
Create or replace the vendor's single payout account (upsert — there is one row per vendor). Existing payouts keep the account they were pinned to at creation, so edits here only affect future payouts.
Request body:
{
"bankName": "HDFC Bank",
"accountHolderName": "Acme Leather Pvt Ltd",
"accountNumber": "50100123456789",
"routingNumber": "HDFC0000123", // optional; null clears
"swiftCode": "HDFCINBB" // optional; null clears
}| Field | Type | Notes |
|---|---|---|
bankName | string | Required, non-empty. |
accountHolderName | string | Required, non-empty. |
accountNumber | string | Required, non-empty. |
routingNumber | string | null (optional) | IFSC / ABA / sort code. null clears. |
swiftCode | string | null (optional) | SWIFT / BIC for international transfers. null clears. |
Returns the saved account in the same shape as the GET.
Product Attribute Module — Vendor surface
Vendor-facing read endpoints for platform-defined product attributes and attribute groups that the vendor product form binds to. Attributes themselves (definitions, codes, types,…
Reports Module — Vendor
Vendor-scoped, registry-driven operational reports (orders sub-orders) with date-ranged paginated views, KPI/trend, and async CSV/XLSX exports — all locked to the authenticated vendor.