Supercommerce API Docs
Vendor API

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_image child table (one row per image, with a sortOrder). Logo, banner, bio and the business/contact/address fields live on vendor_profile; the bank account on vendor_bank_account (one per vendor). The public seller page reads the profile fields back via GET /store/vendors/:slug (see Store API → Vendors); the bank account is never public. slug is intentionally not editable here (it is the public URL).


Conventions

Authentication

Endpoint groupAuth
GET /vendor/profilevendor session
PUT /vendor/profilevendor session
GET /vendor/profile/cover-imagesvendor session
PUT /vendor/profile/cover-imagesvendor session
GET /vendor/bank-accountvendor session
PUT /vendor/bank-accountvendor 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/presignedPUT 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"
  }
}
FieldTypeNotes
logostring | nullStorage key (or absolute URL). null when unset.
bannerstring | nullStorage key (or absolute URL). null when unset.
biostringThe seller-page description (business_description).
businessNamestringDisplay name; mirrored onto the storefront name.
businessEmailstringBusiness contact email.
businessPhonestringBusiness contact phone.
street / city / state / zip / countrystring | nullBusiness address parts. city/state/country show on the public seller page.
taxIdstring | nullTax 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
}
FieldTypeNotes
logostring | null (optional)Storage key from the presigned flow. null clears it. Updating it also syncs the logo onto the vendor's product-feed record.
bannerstring | null (optional)Storage key from the presigned flow. null clears it.
biostring (optional)Non-empty; max 2000 chars.
businessNamestring (optional)Non-empty; max 255. Also updates the storefront name (and the directory search index).
businessEmailstring (optional)Valid email; max 255.
businessPhonestring (optional)Non-empty; max 50.
street / city / state / zip / countrystring | null (optional)Non-empty when set; null clears.
taxIdstring | 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 }
  ]
}
FieldTypeNotes
imagesarray (max 10)Full replacement set. An empty array clears the carousel.
images[].urlstringThe storage key (or absolute URL) returned by the presigned-upload flow.
images[].sortOrderint ≥ 0Display 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
}
FieldTypeNotes
bankNamestringRequired, non-empty.
accountHolderNamestringRequired, non-empty.
accountNumberstringRequired, non-empty.
routingNumberstring | null (optional)IFSC / ABA / sort code. null clears.
swiftCodestring | null (optional)SWIFT / BIC for international transfers. null clears.

Returns the saved account in the same shape as the GET.

On this page