Skip to main content

Overview

Hub verification gives AI agents and human users a reliable signal of publisher credibility. Every listing starts at Tier 1 (Unverified) and can be advanced through three higher tiers — each requiring progressively stronger identity proof. Higher tiers earn:
  • A trust badge displayed on your listing
  • Ranking boosts in Hub search results and the Directory API
  • Eligibility for composite skill inclusion (Tier 4 only)

Verification tiers

TierBadgeHow to earn
1 — Unverified(none)Default at listing creation
2 — Phone Verified✓ Phone VerifiedSMS code via Twilio Verify
3 — Business Verified✓ Business VerifiedGBP cross-reference (internal) or $25 flat fee (external)
4 — Premium Verified★ Premium VerifiedManual review by the ezForge team; $100 flat fee (external)
Internal listings (linked to a Ready business via businessId) run automated checks instead of collecting a fee. External listings (businessId null, externalUrl set) pay a one-time flat fee per tier advancement.

Ready Pro/Premium auto-promotion

Users on a Professional or Premium Ready subscription whose linked business is already business-verified in Ready are automatically promoted to Tier 3 at no additional charge. This sync runs daily.

Advancing verification

All verification actions go through a single endpoint:
POST /api/v1/hub/listings/:id/verify
Authentication: session cookie (user must own the listing).

Tier 2 — Phone Verification

Step 1 — Send SMS code
{
  "tier": 2,
  "action": "send",
  "phone": "+15005550006"
}
Response:
{ "data": { "action": "phone_code_sent", "tier": 1 } }
Step 2 — Confirm code
{
  "tier": 2,
  "action": "verify",
  "phone": "+15005550006",
  "code": "123456"
}
Response on success:
{ "data": { "action": "upgraded", "tier": 2 } }

Tier 3 — Business Verification

Prerequisite: listing must be at Tier 2.
{ "tier": 3 }
Internal listing (Ready business linked):
{ "data": { "action": "upgraded", "tier": 3 } }
External listing (fee required — $25):
{
  "data": {
    "action": "checkout_required",
    "tier": 2,
    "checkoutUrl": "https://checkout.stripe.com/..."
  }
}
After successful payment, the Stripe webhook upgrades the listing to Tier 3 automatically.

Tier 4 — Premium Verification

Prerequisite: listing must be at Tier 3.
{ "tier": 4 }
Internal listing (queued for manual review):
{ "data": { "action": "queued_for_review", "tier": 3 } }
External listing (fee required — $100):
{
  "data": {
    "action": "checkout_required",
    "tier": 3,
    "checkoutUrl": "https://checkout.stripe.com/..."
  }
}
After payment, the listing enters the manual review queue. Tier 4 is granted by the ezForge team, not automatically on payment.

Request reference

FieldTypeRequiredDescription
tier2 | 3 | 4YesTarget verification tier
action"send" | "verify"Tier 2 onlyDefault: "send"
phonestringTier 2E.164 format, e.g. +15005550006
codestringTier 2 + action="verify"4–8 digit SMS code

Response actions

actionMeaning
phone_code_sentSMS dispatched; call again with action="verify"
upgradedListing tier was immediately advanced
checkout_requiredPayment needed; redirect user to checkoutUrl
queued_for_reviewSubmitted to manual review queue (Tier 4)
no_changeListing is already at or above the requested tier

Error codes

StatusCodeCause
400Malformed body or missing required fields
401Not authenticated
404NOT_FOUNDListing not found or not owned by you
422PREREQUISITE_NOT_METRequired previous tier not satisfied
422VERIFICATION_CODE_INVALIDSMS code incorrect or expired
422BUSINESS_VERIFICATION_INELIGIBLEGBP match or 30-day account age requirement not met
429Rate limit exceeded
503TWILIO_NOT_CONFIGUREDTwilio credentials missing (internal error)
503STRIPE_NOT_CONFIGUREDStripe credentials missing (internal error)

Annual re-verification

Verified listings (Tier 2+) are subject to an annual re-verification window. Eleven months after the last tier update, the listing is flagged for re-verification and the owner receives a reminder. Listings that are not re-verified within 12 months may be downgraded (email dispatch and downgrade logic tracked in follow-up issues). The re-verification window is currently measured from the listing’s updated_at timestamp (reset by tier changes and content edits alike), not from the listing’s creation date. A dedicated last_verified_at field is planned as a follow-up.