Companies and verification
Beauty Router reviews each company before it can order. A company is one salon location or one licensed professional. It is created the first time your server logs in one of its users.
You can collect the company’s details in two ways:
- Use Beauty Router’s verification page. This is the easiest path.
- Build your own screens. Send the details and documents over the API, then submit the company for review.
A user logged in with canManageCompany: false can read the
company. The requests on this page that change it fail with user_cannot_manage_company.
Business types
Section titled “Business types”| Type | Who it is |
|---|---|
salon |
A salon or spa |
professional |
An individual licensed professional |
store |
A beauty supply store |
businessType is null until the company picks a type.
Beauty Router does not support beauty supply stores yet, so verification for a store always fails.
Verification statuses
Section titled “Verification statuses”| Status | Meaning |
|---|---|
unverified |
The company was not submitted for review yet. |
in_review |
Beauty Router is reviewing the company. |
prequalified |
The initial check passed, and the detailed verification is still pending. |
verified |
The company passed the review. |
declined |
The company did not pass the review. |
A prequalified company can order, and its orders wait until the detailed verification ends. No charge happens until
then. When a company is declined, its orders close.
Wholesale prices and ordering open only once the company is prequalified or verified. That holds in Beauty Router’s
interface and in the API, where any other company gets company_not_verified. See Create orders.
When the status changes, Beauty Router sends a company.verification_updated webhook.
Use Beauty Router’s verification page
Section titled “Use Beauty Router’s verification page”Call showVerification(element) from the JavaScript library. The page collects the company
details, the documents, and the payment card, and it submits the company for review. You do not need the endpoints in
the next section on this path.
Each login returns the company’s verificationStatus, so you know what to show the user.
Build your own screens
Section titled “Build your own screens”Use these endpoints to collect the details on your own screens. You can update company details one by one, and upload documents one by one. Each step is saved in Beauty Router, so intermediate steps are kept. When everything is ready, submit the company for review.
The payment card is still entered in Beauty Router’s interface. See Payment card.
Show “Powered by Beauty Router” and a link to Beauty Router’s terms on these screens. See Beauty Router mark.
Read the company
Section titled “Read the company”GET /v1/company returns the company of the logged-in user.
curl https://api.beautyrouter.com/v1/company \ -H "Authorization: Bearer $USER_TOKEN"{ "id": "loc-7Hk2pQx9Lm", "businessType": "salon", "displayName": "Golden Hour Hair Studio", "legalName": "Golden Hour Salon LLC", "ein": "847102938", "deliveryAddress": { "line1": "1450 Larimer St", "line2": "Suite 200", "city": "Denver", "state": "CO", "postalCode": "80202", "country": "US", "phone": "+13035550142" }, "verificationStatus": "verified", "buyingSuspended": false, "pendingChanges": null}Fields the company has not filled in yet are null.
buyingSuspended is true when Beauty Router suspended the company’s buying. The company can still read its data and
manage its orders, but it cannot place a new order.
Update the company
Section titled “Update the company”PUT /v1/company accepts a partial update. Send only the fields you change, and fields you leave out stay as they are.
| Field | Description |
|---|---|
businessType |
salon, professional, or store. |
displayName |
The name the company goes by. |
legalName |
The registered legal name. Not used for professional. |
ein |
The Employer Identification Number, 9 digits. Not used for professional. |
deliveryAddress |
The default delivery address. See the fields below. |
deliveryAddress field |
Description |
|---|---|
line1 |
Street address. |
line2 |
Suite, unit, or floor. Optional. |
city |
City. |
state |
Two-letter US state code, such as CO. |
postalCode |
ZIP code. |
country |
Always US. |
phone |
Phone number for the delivery. Required on the company. |
curl -X PUT https://api.beautyrouter.com/v1/company \ -H "Authorization: Bearer $USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "businessType": "salon", "displayName": "Golden Hour Hair Studio", "legalName": "Golden Hour Salon LLC", "ein": "847102938" }'The response is the company.
What happens to a change depends on the company’s status:
unverifiedordeclined. The change saves and shows directly inGET /v1/company.in_review,prequalified, orverified. A change tolegalName,ein,displayName, orbusinessTypegoes topendingChangesuntil the review. See Changes after verification.
A company can change its delivery address at any time, in any status. It needs a license in that state only to order:
without one, the order fails with address_state_without_license in its problems.
The address still saves when the company has no license in that state, and the response has a warnings list. It is the
same check as at order time, so an order to that address fails until the company has the license:
{ "id": "loc-7Hk2pQx9Lm", "verificationStatus": "verified", "warnings": ["address_state_without_license"]}The example shows only some of the fields. A warning comes only with the call that saved that address.
A prequalified company’s license counts as soon as it is uploaded. A verified company’s license must be reviewed
before an order can go to that state, and uploading the license creates the review task.
Documents
Section titled “Documents”Send each document in its own request. The request body is the file itself, Content-Type is the file’s type, such as
application/pdf, and fileName is a query parameter. The file is a PDF, PNG, JPEG, WebP, GIF, TIFF, HEIC, HEIF, or AVIF
file, up to 30 MB. A larger file fails with file_too_large, and another file type fails with
file_type_not_supported.
Beauty Router reads the details from the document, so you send only the file. Until it has processed the document,
fields such as number, state, and expirationDate are null in reads. processingStatus says where that stands:
| Status | Meaning |
|---|---|
pending |
Beauty Router is reading the document. |
done |
Beauty Router has read the document. |
failed |
Beauty Router could not read the file. Ask the user for a better file. |
To correct a document, delete it and upload it again. There is no update. The same file twice for one company fails with
document_already_uploaded.
A document that Beauty Router reviewed can be deleted only while the company is unverified or declined. Otherwise the
request fails with document_locked.
Licenses
Section titled “Licenses”A company needs at least one license. See Submit for review for which kind.
POST /v1/company/licenses takes these query parameters:
| Field | Description |
|---|---|
type |
business or professional. |
fileName |
The name of the file, such as cosmetology-license.pdf. |
curl -X POST "https://api.beautyrouter.com/v1/company/licenses?type=professional&fileName=cosmetology-license.pdf" \ -H "Authorization: Bearer $USER_TOKEN" \ -H "Content-Type: application/pdf" \ --data-binary @cosmetology-license.pdfThe response is the new license. Beauty Router has not processed it yet:
{ "id": "lic-5Bn7vCx1Qe", "type": "professional", "number": null, "state": null, "expirationDate": null, "firstName": null, "lastName": null, "processingStatus": "pending"}GET /v1/company/licenses lists the company’s licenses, with paging.
DELETE /v1/company/licenses/{licenseId} deletes a license.
Exemption certificates
Section titled “Exemption certificates”Exemption certificates are optional. Once Beauty Router reviewed a certificate, orders delivered in its state have no sales tax.
POST /v1/company/exemption-certificates takes one query parameter, fileName, such as resale-certificate.pdf.
curl -X POST "https://api.beautyrouter.com/v1/company/exemption-certificates?fileName=resale-certificate.pdf" \ -H "Authorization: Bearer $USER_TOKEN" \ -H "Content-Type: application/pdf" \ --data-binary @resale-certificate.pdfThe response is the new certificate. Beauty Router has not processed it yet:
{ "id": "exc-2Qw7eRt5Yu", "state": null, "number": null, "startDate": null, "expirationDate": null, "processingStatus": "pending"}GET /v1/company/exemption-certificates lists the company’s certificates, with paging.
DELETE /v1/company/exemption-certificates/{certificateId} deletes a certificate.
Submit for review
Section titled “Submit for review”POST /v1/company/verification submits the company for review. The response is the company, with verificationStatus set
to in_review.
Beauty Router runs the initial check once it has processed the documents. When the check passes, the status becomes
prequalified, and a company.verification_updated webhook follows.
curl -X POST https://api.beautyrouter.com/v1/company/verification \ -H "Authorization: Bearer $USER_TOKEN"The data a company needs depends on its businessType, so set that first:
| Data | salon or store |
professional |
|---|---|---|
displayName |
Required | Required |
legalName |
Required | Not used |
ein |
Required | Not used |
deliveryAddress |
Required | Required |
| Licenses | At least one business or professional license | At least one professional license |
| Exemption certificates | Optional | Optional |
When data is missing, the request fails with verification_data_missing, and missing lists what to add:
{ "error": { "code": "verification_data_missing", "message": "The company needs more data before review.", "missing": ["ein", "licenses"] }}A repeated submit, or a submit on a verified company, changes nothing.
Changes after verification
Section titled “Changes after verification”When an in_review, prequalified, or verified company changes legalName, ein, displayName, or businessType,
the change goes to review. The status stays the same while Beauty Router reviews it.
During that review, GET /v1/company returns the current values, plus the new values in pendingChanges:
{ "id": "loc-7Hk2pQx9Lm", "businessType": "salon", "displayName": "Golden Hour Hair Studio", "legalName": "Golden Hour Salon LLC", "ein": "847102938", "deliveryAddress": { "line1": "1450 Larimer St", "line2": "Suite 200", "city": "Denver", "state": "CO", "postalCode": "80202", "country": "US", "phone": "+13035550142" }, "verificationStatus": "verified", "buyingSuspended": false, "pendingChanges": { "displayName": "Golden Hour Salon and Spa" }}When Beauty Router approves or declines the change, it sends a company.verification_updated webhook.
pendingChanges is null when no change waits for review.
Service endpoints
Section titled “Service endpoints”These endpoints save the selection described in Services.
GET /v1/services lists the services a company can select. It has no paging:
curl https://api.beautyrouter.com/v1/services \ -H "Authorization: Bearer $USER_TOKEN"{ "data": [ { "id": "svc-2Hk8mNq4Lp", "name": "Hair Color" }, { "id": "svc-7Tz3bVw9Rc", "name": "Keratin Treatments" } ]}GET /v1/company/services returns the company’s selection. PUT /v1/company/services replaces it. Both have the same
format:
curl -X PUT https://api.beautyrouter.com/v1/company/services \ -H "Authorization: Bearer $USER_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "serviceIds": ["svc-2Hk8mNq4Lp", "svc-7Tz3bVw9Rc"] }'GET /v1/user/services returns the logged-in user’s selection:
{ "serviceIds": ["svc-2Hk8mNq4Lp", "svc-7Tz3bVw9Rc"], "source": "company"}source is company when the user follows the company, or user when they have their own selection.
PUT /v1/user/services takes serviceIds and sets the user’s own selection, which stays until they remove it. It returns
the same format. An empty list means the user has their own empty selection, so the marketplace shows them all products.
DELETE /v1/user/services removes the user’s selection, so they follow the company again. The response is 204 with no
body.
Any logged-in user of the company can change the company’s selection and their own, including a user with
canManageCompany: false. A user who has their own selection keeps it when the company’s selection changes.
Payment card
Section titled “Payment card”A company needs a payment card before its first order. The card is entered only in Beauty Router’s interface: on the
verification page that showVerification(element) shows, or in the small card list that showPaymentCards(element)
shows. The API never takes card details. Only cards issued in the US are accepted.
GET /v1/company/payment-cards lists the company’s cards. Any logged-in user of the company can read it. It has no
paging.
curl https://api.beautyrouter.com/v1/company/payment-cards \ -H "Authorization: Bearer $USER_TOKEN"{ "data": [ { "id": "card-6Mn3bVc8Xz", "brand": "visa", "last4": "1881", "expMonth": 9, "expYear": 2028, "isDefault": true, "usable": true } ]}| Field | Description |
|---|---|
id |
The card ID, such as card-6Mn3bVc8Xz. |
brand |
The card brand, such as visa or mastercard. |
last4 |
The last four digits. |
expMonth |
The month the card expires, from 1 to 12. |
expYear |
The year the card expires. |
isDefault |
Whether this is the default card for orders. |
usable |
Whether the card can pay. It is false when the card expired or was disabled. |
Services
Section titled “Services”A company can select the services it offers, such as hair color or keratin treatments. Beauty Router uses the selection to personalize the marketplace. It is optional and has no effect on verification.
Services have two levels: the salon location and the user. A user either uses the company’s selection or overrides it with their own. The marketplace personalizes by the user’s own selection if they have one, and otherwise by the company’s. With neither, it shows all products.
You can collect the selection in two ways, and both let you choose the level:
- Show Beauty Router’s form. Call
showServiceSelector(element, { level }), wherelevelis"company", the default, or"user". The user selects services there, and can propose a new one. - Use the API. Show the services in your own form, then save the selection. See Service endpoints.
