RegisterCustomerInput
Registers a new customer account.
input RegisterCustomerInput {
address: CustomerAddressInput
businessType: BuyerBusinessType
code: String!
companyName: String!
contactName: String!
department: String
email: String!
firstName: String
lastName: String
phone: String
subdomain: String
title: String
whatsapp: String
}
Fields
RegisterCustomerInput.address ● CustomerAddressInput input
The registrant's first address, collected as the second step of signup and created in the SAME transaction as the Partner. It rides on registration rather than being added afterwards because a tenant that screens new customers gives them no session — so an address collected after sign-in is an address a PENDING account can never enter. Optional: a tenant that does not screen its customers may also let them skip it and add one later.
RegisterCustomerInput.businessType ● BuyerBusinessType enum
Whether the registrant is a business or an individual → the Partner.type COLUMN (mirrored onto Partner.metadata.businessType), the SAME field the seller console's customer form edits and myProfile.businessType reads back. Omitted defaults to BUSINESS.
RegisterCustomerInput.code ● String! non-null scalar
The 6-digit code the registrant already verified on the OTP screen, which now comes BEFORE this form (mirroring the buyer app's email → OTP → details order, owner decision 2026-08-11). Re-checked server-side here because this mutation is what actually creates the account: without it, registration is callable directly and 'verified email' would be a client-side claim (Foundation Gate 3). The code is NOT consumed here — the sign-in that follows spends it.
RegisterCustomerInput.companyName ● String! non-null scalar
The name of the company.
RegisterCustomerInput.contactName ● String! non-null scalar
The person's full name. Still REQUIRED — it is what every existing reader renders, and older portal builds send only this. When firstName/lastName are also sent they win, because a split of "Ana Maria Da Silva" can only guess where the surname starts and the form already knows.
RegisterCustomerInput.department ● String scalar
The person's department (e.g. 'Procurement'). Stored on their Contact rows, like title.
RegisterCustomerInput.email ● String! non-null scalar
Email address.
RegisterCustomerInput.firstName ● String scalar
Given name. Optional for older builds sending only contactName; takes precedence over splitting it when present.
RegisterCustomerInput.lastName ● String scalar
Family name. See firstName.
RegisterCustomerInput.phone ● String scalar
Mobile number in E.164 form (e.g. +27821234567) → User.phone plus a PHONE Contact channel row.
RegisterCustomerInput.subdomain ● String scalar
Dev/localhost fallback for multi-tenant resolution — the request host (X-Original-Host → Host) always wins, exactly like checkCustomerExists.
RegisterCustomerInput.title ● String scalar
The person's job title (e.g. 'Purchasing Manager'). Stored on their Contact rows — there is no title column on User. Same field as MobileRegisterBuyerInput.title.
RegisterCustomerInput.whatsapp ● String scalar
WhatsApp number in E.164 form. Persisted as its own WHATSAPP Contact channel row — there is no WhatsApp column on User. The portal form offers a "Same as mobile number" tick, exactly like the seller console and the buyer app.
Member Of
registerCustomer mutation