Overview
Ready uses a four-tier verification system to establish trust for businesses in the directory and in MCP server metadata. Higher verification levels improve your directory ranking and signal credibility to AI agents that interact with your business.
Business Verified and Premium Verified tiers are in Beta. Business Verified auto-checks will
complete when Google Business Profile (GBP) API integration launches (EP-R07 post-launch).
Phone Verified is fully operational.
Verification tiers
Tiers are strictly ordered — you cannot skip a level.
| Tier | Display label | How it is awarded |
|---|
unverified | Unverified | Default for all new businesses |
phone_verified | Phone Verified | User-initiated: complete SMS verification from your Ready settings page — tier is awarded automatically on confirmation |
business_verified | Business Verified | Auto-check: account ≥ 30 days old + phone verified (GBP cross-reference in Beta — logs but is not blocking) |
premium_verified | Premium Verified | Manual review by ezForge team (post-launch queue, no automated promotion during Beta) |
Earning verification
Phone Verified
Complete phone verification from your Ready settings page. Ready sends an SMS code to your registered business phone number. When the code is confirmed, your account is automatically upgraded to phone_verified.
Business Verified
The auto-check runs after phone verification and evaluates:
- Account age — your business account must be at least 30 days old
- Phone verification — must already be at
phone_verified or higher
- GBP cross-reference — Google Business Profile match (Beta stub; currently always
false but non-blocking)
When criteria 1 and 2 are met, the system upgrades your tier to business_verified automatically.
Premium Verified
Contact ezForge support or use the in-dashboard option to apply. Your business is placed in a manual review queue (premium_review_queued_at is set). A team member reviews and promotes the tier. No automated promotion occurs.
Verification badge
The verification badge appears on your Ready settings page at /ready/settings. It shows:
- Tier label — color-coded badge (gray → blue → green → purple)
- Description — what the current tier means
- Next step — guidance on how to advance to the next tier (hidden at Premium Verified)
- Stale data warning — if your business hours have not been updated in 90 days, a yellow warning banner is shown
Stale data detection
Ready monitors how recently your business hours were updated. If no update is recorded in the last 90 days, a stale flag is set on your verification record. Stale businesses receive a warning in the dashboard prompting an update. Updating your hours clears the flag automatically.
VerificationLevel type
The VerificationLevel type is the public-facing string representation of a business’s verification tier. It is returned in directory API responses and MCP server metadata.
type VerificationLevel =
| 'unverified'
| 'phone_verified'
| 'business_verified'
| 'premium_verified';
Mapping from internal tier to VerificationLevel:
Internal VerificationTier | VerificationLevel |
|---|
unverified | unverified |
phone | phone_verified |
business | business_verified |
premium | premium_verified |
When no business_verification_levels row exists for a business (pre-migration records), the system falls back to checking the phone_verifications table. A confirmed phone record maps to phone_verified; no record maps to unverified.
business_verification_levels schema
One row per business. Created on first verification activity; upsertBusinessVerificationLevel inserts a default unverified row if none exists.
| Column | Type | Description |
|---|
business_id | varchar(26) | Primary key — foreign key to businesses.id (cascade delete) |
tier | verification_tier enum | Current tier: unverified, phone, business, premium |
achieved_at | timestamp | When the current tier was last achieved (null for unverified) |
gbp_verified | boolean | Whether a Google Business Profile match was confirmed (default false) |
gbp_place_id | varchar(255) | Matched GBP place ID, for audit trail (null until GBP integration) |
stale_flagged_at | timestamp | Set when business hours are more than 90 days stale; cleared on hours update |
premium_review_queued_at | timestamp | Set when business is queued for Premium Verified manual review |
created_at | timestamp | Row creation time |
updated_at | timestamp | Last update time |
Indexes: business_verification_levels_tier_idx on tier (used by directory filter queries).
Hub listing sync: On every tier upgrade, the integer value of the new tier (1–4) is mirrored into hub_listings.verification_tier for Typesense rank-score computation. This write is best-effort — hub listing failure does not block the tier upgrade.
getBusinessTrustSignals
Returns a concise set of trust signals for a business, suitable for inclusion in MCP server metadata.
Parameters:
| Parameter | Type | Description |
|---|
database | Database | Drizzle database instance |
businessId | string | Business ULID |
Returns:
{
verificationTier: VerificationTier; // 'unverified' | 'phone' | 'business' | 'premium'
accountAgeDays: number; // days since the business was created
staleFlagged: boolean; // true if stale_flagged_at is set
}
Throws: NotFoundError when the business does not exist.
getBusinessTrustSignals and getMcpServerMetadata are independent utilities — neither calls the other. They surface overlapping signals (accountAgeDays) to different consumers via separate SQL queries. The differences in their output shapes are intentional:
staleFlagged is returned by this function for stale-data detection (see Stale data detection) but is not part of the MCP metadata trust signals.
profileCompleteness, lastUpdated, and interactionCount appear in the MCP trust signals shape but are not returned by this function — getMcpServerMetadata computes them directly from its own SQL join (profileCompleteness from the business profile record, lastUpdated from the listing row, interactionCount from an analytics count query).
See Directory API for the full MCP response shape.
Directory API integration
Verification level is included in all directory responses (see Directory API):
- List directory —
verificationLevel field on each listing item
- Get listing —
verificationLevel field on the detail response
- MCP server metadata —
business.verificationLevel plus trust signals: accountAgeDays, profileCompleteness, lastUpdated, interactionCount (see Directory API for full shape)
You can filter the directory by minimum verification level using the min_verification query parameter:
| Value | Businesses returned |
|---|
phone_verified | Phone Verified, Business Verified, and Premium Verified |
business_verified | Business Verified and Premium Verified |
premium_verified | Premium Verified only |
Hub listing sync
When a business’s verification tier is upgraded, the integer equivalent is written to hub_listings.verification_tier:
| Tier | Integer |
|---|
unverified | 1 |
phone | 2 |
business | 3 |
premium | 4 |
The Hub uses this value in its Typesense rank-score computation. Higher-verified businesses rank higher in Hub search results.