> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ezforge.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Listing Verification

> Advance your Hub listing through the 4-tier verification system to earn trust badges and search-ranking boosts

## 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](/api-reference/directory)
* Eligibility for composite skill inclusion (Tier 2+ required; `verification_tier_min` filter lets agents raise the bar further)

## Verification tiers

| Tier                      | Badge               | How to earn                                                  |
| ------------------------- | ------------------- | ------------------------------------------------------------ |
| **1 — Unverified**        | (none)              | Default at listing creation                                  |
| **2 — Phone Verified**    | ✓ Phone Verified    | SMS code via Twilio Verify                                   |
| **3 — Business Verified** | ✓ Business Verified | GBP cross-reference (internal) or \$25 flat fee (external)   |
| **4 — Premium Verified**  | ★ Premium Verified  | Manual 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**

```json theme={null}
{
  "tier": 2,
  "action": "send",
  "phone": "+15005550006"
}
```

Response:

```json theme={null}
{ "data": { "action": "phone_code_sent", "tier": 1 } }
```

**Step 2 — Confirm code**

```json theme={null}
{
  "tier": 2,
  "action": "verify",
  "phone": "+15005550006",
  "code": "123456"
}
```

Response on success:

```json theme={null}
{ "data": { "action": "upgraded", "tier": 2 } }
```

### Tier 3 — Business Verification

Prerequisite: listing must be at Tier 2.

```json theme={null}
{ "tier": 3 }
```

**Internal listing** (Ready business linked):

```json theme={null}
{ "data": { "action": "upgraded", "tier": 3 } }
```

**External listing** (fee required — \$25):

```json theme={null}
{
  "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.

```json theme={null}
{ "tier": 4 }
```

**Internal listing** (queued for manual review):

```json theme={null}
{ "data": { "action": "queued_for_review", "tier": 3 } }
```

**External listing** (fee required — \$100):

```json theme={null}
{
  "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

| Field    | Type                 | Required                   | Description                       |
| -------- | -------------------- | -------------------------- | --------------------------------- |
| `tier`   | `2 \| 3 \| 4`        | Yes                        | Target verification tier          |
| `action` | `"send" \| "verify"` | Tier 2 only                | Default: `"send"`                 |
| `phone`  | `string`             | Tier 2                     | E.164 format, e.g. `+15005550006` |
| `code`   | `string`             | Tier 2 + `action="verify"` | 4–8 digit SMS code                |

## Response actions

| `action`            | Meaning                                           |
| ------------------- | ------------------------------------------------- |
| `phone_code_sent`   | SMS dispatched; call again with `action="verify"` |
| `upgraded`          | Listing tier was immediately advanced             |
| `checkout_required` | Payment needed; redirect user to `checkoutUrl`    |
| `queued_for_review` | Submitted to manual review queue (Tier 4)         |
| `no_change`         | Listing is already at or above the requested tier |

## Error codes

| Status | Code                               | Cause                                               |
| ------ | ---------------------------------- | --------------------------------------------------- |
| `400`  | —                                  | Malformed body or missing required fields           |
| `401`  | —                                  | Not authenticated                                   |
| `404`  | `NOT_FOUND`                        | Listing not found or not owned by you               |
| `422`  | `PREREQUISITE_NOT_MET`             | Required previous tier not satisfied                |
| `422`  | `VERIFICATION_CODE_INVALID`        | SMS code incorrect or expired                       |
| `422`  | `BUSINESS_VERIFICATION_INELIGIBLE` | GBP match or 30-day account age requirement not met |
| `429`  | —                                  | Rate limit exceeded                                 |
| `503`  | `TWILIO_NOT_CONFIGURED`            | Twilio credentials missing (internal error)         |
| `503`  | `STRIPE_NOT_CONFIGURED`            | Stripe 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.
