# Get started with VerifiedInbox (guide for AI assistants)

> Everything an AI assistant needs to take a company's email domain from a first check to its logo, and Gmail's blue checkmark, shown in the inbox, using the VerifiedInbox MCP server or REST API.

You are probably reading this because a person asked you something like: *"Add a verified VMC mark to my email domain using getverifiedinbox.com/get-started.md"*. This page is written for you, the AI assistant. It contains everything you need to complete the job with the person, step by step, across as many conversations as it takes.

## The 60-second version

1. **Connect** to the MCP server at `https://api.getverifiedinbox.com/mcp` (no credentials needed to start). If you can't use MCP, use the REST API at `https://api.getverifiedinbox.com/v1` (see [REST API fallback](#rest-api-fallback)).
2. **Ask for the domain** if you don't know it (the part after the `@` in the person's work email, e.g. `acme.com`). Shared providers like gmail.com cannot be used.
3. Call `check_domain`, then `start_application`. **Save the `application_id` and `guest_token`** it returns, and tell the person to keep them (or create a resume link) so you can continue later.
4. Walk through the free steps: `set_email_usage` + `recheck_email_security` → `submit_logo` → `get_logo_status` → `get_trademark_status` → `get_eligibility` → `get_estimate`. **Steps only move forward when completed:** once a step's `status` is `ready`, confirm with the person and call `complete_step`.
5. Tell the person, in plain English, which outcome they qualify for: **logo + blue checkmark (VMC)**, **logo only (CMC)**, or **not currently eligible** (and what to do about it).
6. When they are ready to pay, they need an account. Create a checkout link with `create_checkout`; **only the person can pay**.
7. After payment: business details → logo approval (by the person) → DNS records (added by the person) → certificate → go live, completing each step with `complete_step`. Always follow the `next_actions` returned by every tool.

## What VerifiedInbox does

VerifiedInbox gets a company's logo shown next to the emails it sends in Gmail and other inboxes that support the BIMI standard, and, with a registered trademark, Gmail's **blue verified checkmark**. It is a one-stop shop: it runs the checks, prepares the logo file, checks the US trademark register, verifies the business, orders the certificate from the certificate issuer (DigiCert), gives copy-paste DNS records, hosts the logo and certificate, monitors the setup and renews the certificate every year.

The people you are helping are usually marketing, sales or company leaders, not engineers. Use plain English with them. Technical terms are fine with you, the agent, and in "advanced" details.

## Possible outcomes

| Outcome | What the person gets | Requirements | Price |
|---|---|---|---|
| **VMC** (Verified Mark Certificate) | Logo **and** Gmail's blue checkmark | Registered trademark for the logo (USPTO in the first release), own domain, DMARC at enforcement | $1,499 per domain per year + issuer fee |
| **CMC** (Common Mark Certificate) | Logo only, **no checkmark** | Logo used publicly for 12+ months (no trademark needed), own domain, DMARC at enforcement | $899 per domain per year + issuer fee |
| **Not currently eligible** | Clear list of what's missing, evidence, a date when they may qualify, and a reminder | — | Free |

For a CMC customer, success means **the logo is displayed**. Never promise a checkmark to a CMC customer.

### Separate outcomes (never collapse them into one "verified")

An application tracks several independent outcomes. Report each one separately:

| Outcome field | Meaning | Values |
|---|---|---|
| `eligibility` | Which route the domain qualifies for | `unknown`, `assessing`, `vmc_eligible`, `cmc_eligible`, `not_currently_eligible` |
| `payment` | Plan payment | `unpaid`, `checkout_open`, `paid`, `refund_pending`, `refunded`, `canceled` |
| `business` | Company verification | `not_started`, `verifying`, `verified`, `needs_info`, `rejected` |
| `ownership` | Domain control (DNS TXT record) | `pending`, `verified`, `lost` |
| `logo` | Logo file | `missing`, `processing`, `ready_for_review`, `approved`, `failed` |
| `trademark` | USPTO match | `not_started`, `searching`, `match_found`, `no_match`, `needs_review`, `manually_verified`, `error` |
| `certificate` | **Certificate issued** | `not_ordered`, `waiting_prerequisites`, `submitted`, `issuer_validation`, `awaiting_customer`, `issued`, `expiring`, `renewed`, `expired`, `rejected`, `revoked` |
| `bimi` | **BIMI correctly published and reachable** | `not_published`, `invalid`, `published` |
| `inbox_display` | **Display observed in a real mailbox** | `not_observed`, `observed` |
| `dmarc_rollout` | Safe DMARC rollout stage | `missing`, `monitoring`, `quarantine_partial`, `quarantine`, `reject` |

"Eligibility assessed", "certificate issued", "BIMI published" and "display observed" are four different milestones. Gmail decides when to show logos and checkmarks; even with everything correct, **display is never guaranteed**.

## Connect to the MCP server

- **Endpoint:** `https://api.getverifiedinbox.com/mcp`
- **Transport:** MCP Streamable HTTP (JSON responses). Protocol versions `2025-11-25`, `2025-06-18`, `2025-03-26`.
- Every MCP tool wraps one or more REST API operations (listed below) and uses the same server logic. Tool arguments are generated from the OpenAPI schema, so MCP and REST never disagree.

### Three ways to connect

| Mode | How | What you can do |
|---|---|---|
| **Anonymous** | Connect with no credentials | All free tools. `start_application` returns a `guest_token`; pass it as the `guest_token` argument on later calls (or send the `VI-Guest-Token` header). |
| **OAuth (sign in)** | Clients that support MCP OAuth sign the person in automatically the first time an account tool is called (the server answers HTTP 401 with `WWW-Authenticate` resource metadata). | Everything the person's role allows. |
| **API key** | Header `Authorization: Bearer vi_live_…` (real) or `vi_test_…` (test mode). The person creates keys in Dashboard → Settings → API keys. | Scoped to one organization and one environment (live or test). |

Never ask the person to paste an API key into the chat unless your client has no safer way to configure headers; prefer OAuth.

### Client setup

**Claude (claude.ai and Claude Desktop):** Settings → Connectors → *Add custom connector* → name `VerifiedInbox`, URL `https://api.getverifiedinbox.com/mcp`. Then enable it in the conversation.

**Claude Desktop (config file, if custom connectors aren't available):**

```json
{
  "mcpServers": {
    "verifiedinbox": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.getverifiedinbox.com/mcp"]
    }
  }
}
```

**Claude Code:**

```bash
claude mcp add --transport http verifiedinbox https://api.getverifiedinbox.com/mcp
# with an API key (test mode shown):
claude mcp add --transport http verifiedinbox https://api.getverifiedinbox.com/mcp \
  --header "Authorization: Bearer vi_test_…"
```

**Cursor** (`~/.cursor/mcp.json` or `.cursor/mcp.json` in a project):

```json
{
  "mcpServers": {
    "verifiedinbox": { "url": "https://api.getverifiedinbox.com/mcp" }
  }
}
```

With an API key:

```json
{
  "mcpServers": {
    "verifiedinbox": {
      "url": "https://api.getverifiedinbox.com/mcp",
      "headers": { "Authorization": "Bearer vi_test_…" }
    }
  }
}
```

**ChatGPT:** add a custom connector (Settings → Apps & Connectors; on some plans this requires developer mode) with the URL `https://api.getverifiedinbox.com/mcp`. If the person's plan doesn't allow custom connectors, use the [REST API](#rest-api-fallback) if you can make HTTP requests, or guide them through the website at `https://getverifiedinbox.com/verify/new?domain=<their domain>`.

**VS Code / other MCP clients:** add an HTTP MCP server with the URL above, e.g. `.vscode/mcp.json`:

```json
{ "servers": { "verifiedinbox": { "type": "http", "url": "https://api.getverifiedinbox.com/mcp" } } }
```

If you cannot add the server yourself, tell the person exactly which of the steps above to follow, then continue once the tools are available.

### MCP resources and prompts

- Resource `verifiedinbox://get-started` — this guide.
- Resource `verifiedinbox://glossary` — plain-English definitions of every term.
- Prompt `verify_my_domain(domain)` — starts the guided flow.

## The process, step by step

The website shows the same process as an 11-step wizard. Steps 1–5 are **free and anonymous**; steps 6–11 need an account and payment.

**Only the person (or you, on their behalf) moves the wizard forward.** Background work changes outcomes but never completes a step. Every step in `steps` lists its `requirements` (required ones must be met; others are recommended). When a step's `status` is `ready`, call `complete_step` with the `application_id` and the step slug; a `409 step_not_ready` lists what's still missing. Statuses: `complete` (done), `attention` (done earlier, but something it relied on broke: fix it and call `complete_step` again), `ready`, `action_required`, `in_progress`, `blocked` (the current step) and `locked` (later steps).

| # | Step (`slug`) | Phase | Free | What happens |
|---|---|---|---|---|
| 1 | `domain` | Check | ✓ | Domain accepted; blocked-provider and registration check |
| 2 | `email-health` | Check | ✓ | SPF, DKIM and DMARC results with exact fixes; DMARC must be enforced (filter all or block all) |
| 3 | `logo` | Check | ✓ | Logo uploaded or discovered; compliant version prepared; Gmail preview |
| 4 | `trademark` | Check | ✓ | USPTO search (or a registration number is verified) |
| 5 | `eligibility` | Check | ✓ | VMC, CMC or not currently eligible, with evidence, next steps and an estimate |
| 6 | `checkout` | Setup | paid | Sign in and pay through Stripe's hosted checkout |
| 7 | `business` | Setup | paid | Legal company details and the applicant |
| 8 | `logo-approval` | Setup | paid | The person approves the exact final logo file |
| 9 | `dns` | Setup | paid | Ownership and logo (BIMI) records; DMARC from step 2 shown as done |
| 10 | `certificate` | Certificate | paid | Final re-check, order, issuer review (a few business days), issuance |
| 11 | `go-live` | Live | paid | Logo published, test email, display confirmed; monitoring and renewals on |

### Free steps (anonymous)

**Step 0 — explain (optional).** `get_started` returns the process, steps and pricing. Use it if the person asks "how does this work?".

**Step 1 — check the domain.** `check_domain` with `{ "domain": "acme.com" }` (emails and URLs are accepted too). It returns a `verdict` (`ok`, `blocked_provider`, `invalid`, `not_registered`), the mailbox provider, whether DMARC and BIMI exist, and a plain-English `summary`. If the verdict is `blocked_provider`, explain why (see [Shared email providers](#shared-email-providers-cannot-be-used)) and ask for their company domain. If `not_registered`, tell them the domain must be registered first (with a registrar such as Cloudflare or GoDaddy).

**Step 2 — start (or resume) the application.** `start_application` with `{ "domain": "acme.com" }` returns the `application_id`, a `guest_token` (only the first time), the wizard `steps`, `next_actions` and a `web_url`. It is idempotent: calling it again for the same domain returns the existing application. Background work (DNS scan, website logo discovery, web-archive history) starts immediately.

**Step 3 — email security.** Ask the person how email is used on the domain and record it with `set_email_usage` (`none`: new domain or no email yet; `low`: little email; `active`: email every day). The answer decides the recommended path: `none`/`low` publish the blocking DMARC record straight away; `active` follows the staged rollout, though the person may skip ahead (explain the risk). After they change DNS, call `recheck_email_security`: it returns SPF, DKIM and DMARC status, `findings` with ready-made `fix` records, and `dmarc_rollout` with every stage's exact record, what to monitor and what happens to email. If no DKIM key was found, ask for their selector and call `verify_dkim_selectors`. Summarize the 1–3 things that matter. The step needs DMARC enforced (plus SPF and DKIM unless no email is sent); see [Safe DMARC rollout](#safe-dmarc-rollout). `check_email_security` runs the same inspection for any domain without an application.

**Step 4 — logo.** `submit_logo` with the `application_id` and one of: SVG text (`svg`), a public URL (`url`), or `use_discovered: true` to use the logo found on their website. Max 512 KB. The original file is kept byte-for-byte; a compliant SVG Tiny P/S copy is produced. Then call `get_logo_status`: it returns the compliance analysis, the list of changes made during conversion (flagging any that change the look), a visual comparison score, and preview URLs. Share the preview with the person. If the logo can't be used (raster only, too complex), explain and ask for a better file (an SVG from their designer or brand guidelines).

**Step 5 — trademark.** Submitting the logo starts a USPTO search automatically. `get_trademark_status` returns `match_found`, `no_match`, `needs_review` or `searching`, plus candidates. If the person knows their registration or serial number, call `search_trademark` with it to verify that exact record; you can also pass the owner name or mark text to refine the search. Searches are rate-limited for anonymous users; don't loop.

**Step 6 — eligibility.** `get_eligibility` returns `vmc_eligible`, `cmc_eligible` or `not_currently_eligible`, the requirements for each route (met or not, with evidence), `next_steps`, and `estimated_eligible_on` when a date is known. Explain the result in one or two sentences.

**Step 7 — estimate.** `get_estimate` with `product` (`vmc` or `cmc`) returns line items (our plan + the issuer's fee, marked as estimated), the total per year and the refund policy. Always show the total before suggesting payment.

**If not currently eligible:** offer `watch_eligibility` (we email them when they qualify) and the paid trademark filing service (email `trademark@getverifiedinbox.com`). See [Trademark logic](#trademark-logic).

### Paid steps (account required)

**Sign in and claim.** Account tools need the person to be signed in:

- If your client supports MCP OAuth, call the account tool (for example `get_account`); the client will open a sign-in window. Then call `claim_application` with the `application_id` and the `guest_token` to move the anonymous draft into their account (atomic; if their organization already has an application for the domain, the more advanced one is kept and you're told which).
- Otherwise call `create_resume_link` and give the person the link. They open it, sign in on the website, and the draft is claimed automatically. You can continue later with an API key or OAuth.

**Checkout.** `create_checkout` with `{ "application_id", "product": "vmc" | "cmc" }` returns a Stripe `checkout_url` (expires). Give the link to the person; **you cannot pay, and you must never ask for card details**. After they pay, `get_application` shows `payment: "paid"` (confirmation comes from Stripe, usually within seconds).

**Business details.** `submit_business_details` with the legal company name, jurisdiction (e.g. `us_de`), registration number, address, and the applicant (name, work email, title, phone), plus `authority_attested: true` only if the person confirms they are authorized to act for the company. Then `get_business_status`. If it returns `needs_info`, ask the person exactly what's requested.

**Logo approval (the person decides).** Show the person the original and the converted logo side by side (URLs from `get_logo_status`). Only after they explicitly say it looks right, call `approve_logo` with the `converted_sha256` of the version they reviewed.

**DNS records (the person, or their IT, adds them).** `get_dns_records` returns every record to add, each with `host`, `type`, `value`, `purpose` and live `status` (`ok`, `missing`, `mismatch`, `warning`):

- Domain ownership: `TXT` at `_verifiedinbox.<domain>`
- DMARC: `TXT` at `_dmarc.<domain>` (at the current safe rollout stage)
- BIMI: `TXT` at `default._bimi.<domain>` pointing to the hosted logo and certificate
- SPF/DKIM advice when needed

Present them as a short copy-paste list and say where to paste them (their DNS host, which is detected and returned). After they've added them, call `verify_dns`: it checks the domain's **authoritative nameservers** directly, so correct changes show up within seconds. Never claim you changed DNS yourself; in this release DNS is never changed on the person's behalf.

**DKIM and a real test email (optional but recommended).** `verify_dkim_selectors` checks selectors the person supplies. `create_test_message` returns an address; ask the person to send a normal email from their domain to it, then call `get_test_message_result` to see SPF, DKIM and DMARC alignment of that real message.

**Certificate.** Ordering happens automatically once the DNS step is completed. Right before the order is sent, a **final re-check** verifies everything the issuer will look at, live (domain, email protection, approved logo, company, trademark, DNS records); it repeats daily while the issuer reviews. Anything that fails holds the order and marks its step `attention`: help the person fix it, then call `complete_step` for that step again. `run_final_check` re-runs it on demand. `get_certificate` returns the status, `final_check`, `customer_actions` (for example "approve the email from DigiCert" or a verification call) and, once issued, the expiry date. Issuer review usually takes a few business days. Relay customer actions clearly and promptly.

**Go live.** When the certificate is issued, the BIMI record points to the hosted files. `get_application` shows `bimi: "published"` when everything is reachable and matches. Ask the person to send an email to a Gmail address and look at it; when they confirm they see the logo (and checkmark for VMC), call `confirm_inbox_display` with `{ "mailbox": "gmail", "observed": true }`. Monitoring and renewal start automatically.

**After going live.** `get_account` lists every organization, application, status and pending action. `list_orders` shows payments. `renew_certificate` renews early, `reissue_certificate` gets a new certificate (e.g. after a logo change). `revoke_certificate` permanently cancels it and requires `confirm: "REVOKE <domain>"`; only do this after the person explicitly asks and confirms.

Free tools that work on an application accept `guest_token`; account tools accept `environment` (`live` or `test`). The table below lists every argument.

### Complete tool reference

Every MCP tool, what it does, its arguments (`*` = required), whether it needs an account, and the REST operation(s) it wraps. Generated from the OpenAPI schema and the server's tool list.

<!-- BEGIN GENERATED: tools (make contract) -->

| Tool | What it does | Arguments | Access | API operations |
|---|---|---|---|---|
| `get_started` | Explains the whole process (free checks, paid setup, certificate, go-live), pricing, what the user must do themselves, and how to continue later. Call this first if you're new to VerifiedInbox. | — | Free | `GET /v1/meta` |
| `check_domain` | Free, instant check of an email domain: can it get a verified logo? Detects shared providers that can't be used (gmail.com, outlook.com…), unregistered domains, the mailbox provider and a DMARC/BIMI summary. Accepts a domain, URL or email address. | `domain`* | Free | `POST /v1/checks/domain` |
| `check_email_security` | Free full inspection of SPF, DKIM, DMARC and BIMI with plain-English findings and exact fixes. Uses the domain's authoritative nameservers (sees changes within seconds). | `domain`*, `dkim_selectors` | Free | `POST /v1/checks/email-auth` |
| `start_application` | Starts the verification for a domain, or returns the existing one. Anonymous callers receive a guest_token — tell the user to keep it (with the application_id) to continue in a later conversation. Background checks start immediately. Returns the full state and next_actions. | `domain`*, `environment`, `guest_token` | Free | `POST /v1/applications` |
| `list_applications` | Lists the verifications visible to the caller (guest drafts for a guest_token, or the account's domains). | `environment`, `guest_token` | Free | `GET /v1/applications` |
| `get_application` | Full current state: separate outcomes (eligibility, payment, business, ownership, logo, trademark, certificate, BIMI, inbox display), the 11 wizard steps with status, running background work, and next_actions (what to do next and which tool to use). Call this whenever you need to know where things stand. | `application_id`*, `guest_token` | Free | `GET /v1/applications/{application_id}`<br>`GET /v1/applications/{application_id}/next-steps` |
| `complete_step` | Moves the verification to the next step once the current step's required items are met (each step lists them in `requirements`; status `ready` means it can be completed). Background work never completes steps; this does, on the user's behalf. Also re-confirms an earlier step marked `attention` after it was fixed. Confirm with the user before completing a step they haven't reviewed. | `application_id`*, `step`*, `guest_token` | Free | `POST /v1/applications/{application_id}/steps/{step}/complete` |
| `set_email_usage` | Ask the user how email is used on their domain and record the answer: none (new domain, no email yet), low (little email) or active (email sent every day). none/low can switch on full protection (block all) right away; active should follow the staged rollout, though the user may skip ahead. Returns the email security report with the recommended DMARC record. | `application_id`*, `email_usage`*, `guest_token` | Free | `PUT /v1/applications/{application_id}/email-usage` |
| `recheck_email_security` | Re-checks SPF, DKIM and DMARC for the application right now (after the user published records) and returns the report plus the DMARC rollout plan: every stage's exact record, what to monitor and what happens to email at that stage. | `application_id`*, `guest_token` | Free | `POST /v1/applications/{application_id}/email-health/check` |
| `submit_logo` | Provide the company logo: SVG text (preferred), a URL to an SVG, or use_discovered=true to use the logo found on the company website. The original is kept untouched; an inbox-ready SVG Tiny P/S version is produced automatically and a US trademark search starts. | `application_id`*, `guest_token`, `svg`, `url`, `use_discovered` | Free | `PUT /v1/applications/{application_id}/logo` |
| `get_logo_status` | Logo processing status, compliance issues, the list of changes made for the inbox version (lossy ones flagged), visual difference, and preview URLs. Also lists logos discovered on the website. | `application_id`*, `guest_token` | Free | `GET /v1/applications/{application_id}/logo`<br>`GET /v1/applications/{application_id}/logo-candidates` |
| `search_trademark` | Starts (or re-runs) the USPTO trademark search, or verifies a specific US serial/registration number the user provides. A registered trademark matching the logo unlocks the blue checkmark (VMC). Rate-limited for anonymous users. | `application_id`*, `guest_token`, `mark_text`, `owner_name`, `serial_or_registration_number` | Free | `POST /v1/applications/{application_id}/trademark/search`<br>`POST /v1/applications/{application_id}/trademark/claim` |
| `get_trademark_status` | Trademark search result: matched registration (with similarity to the logo), candidates, and what it means. | `application_id`*, `guest_token` | Free | `GET /v1/applications/{application_id}/trademark` |
| `get_eligibility` | Outcome: vmc_eligible (logo + blue checkmark), cmc_eligible (logo only, no checkmark), not_currently_eligible (with evidence, estimated date and next steps such as the trademark filing service at trademark@getverifiedinbox.com), or assessing. | `application_id`*, `guest_token` | Free | `GET /v1/applications/{application_id}/eligibility` |
| `get_estimate` | Itemized yearly price before payment: plan (CMC $899 or VMC $1,499 per domain) plus the certificate issuer's fee (pass-through, no markup, ~$750–$1,750). Full refund if issuance is rejected. | `application_id`*, `guest_token`, `product` | Free | `GET /v1/applications/{application_id}/estimate` |
| `watch_eligibility` | Emails the user when the domain becomes eligible (we re-check daily). Use for not_currently_eligible outcomes. | `application_id`*, `email`*, `guest_token` | Free | `POST /v1/applications/{application_id}/eligibility/watch` |
| `create_resume_link` | Creates a one-time link (valid 24h) that opens this verification in the web app — useful for visual steps like reviewing the logo or copying DNS records. Optionally emails it. | `application_id`*, `email`, `guest_token` | Free | `POST /v1/applications/{application_id}/resume-links` |
| `explain_term` | Plain-English explanation of a term such as BIMI, VMC, CMC, DMARC, SPF, DKIM, selector, alignment, SVG Tiny P/S. | `term`* | Free | `GET /v1/glossary/{term}` |
| `contact_support` | Sends a message to the VerifiedInbox team (a human replies by email within one business day). Include the user's email. | `message`*, `application_id`, `email`, `guest_token`, `kind`, `name` | Free | `POST /v1/support` |
| `send_feedback` | Sends feedback or a feature request to the VerifiedInbox team. | `message`*, `email`, `guest_token`, `kind` | Free | `POST /v1/support` |
| `get_account` | Organizations, environment (live/test), every domain with its status and pending actions, and recent orders. | `environment` | Account | `GET /v1/me`<br>`GET /v1/applications`<br>`GET /v1/orders` |
| `claim_application` | Atomically moves a guest draft (application_id + guest_token) into the signed-in account. If the account already has the domain, keeps the more advanced one and reports which. | `application_id`*, `guest_token`*, `environment` | Account (`applications:write`) | `POST /v1/applications/{application_id}/claim` |
| `create_checkout` | Creates a Stripe checkout link for the chosen plan. Only a human can pay: give the link to the user, and confirm the price first (see get_estimate). | `application_id`*, `product`*, `environment`, `idempotency_key` | Account (`billing:write`) | `POST /v1/applications/{application_id}/checkout` |
| `submit_business_details` | Legal company details + the applicant (starts business registration verification). Requires payment. jurisdiction is the US state code like us_de. | `address`*, `applicant`*, `application_id`*, `jurisdiction`*, `legal_name`*, `authority_attested`, `environment`, `registration_number` | Account (`applications:write`) | `PUT /v1/applications/{application_id}/business` |
| `get_business_status` | Business verification status, matched registry record and applicant authority. | `application_id`*, `environment` | Account | `GET /v1/applications/{application_id}/business` |
| `approve_logo` | Approves the exact inbox-ready logo the user reviewed (pass converted_sha256 from get_logo_status). Ask the user to look at the preview first (create_resume_link helps). | `application_id`*, `converted_sha256`*, `environment` | Account (`applications:write`) | `POST /v1/applications/{application_id}/logo/approve` |
| `get_dns_records` | Every DNS record the user must add (ownership TXT, DMARC at the right rollout stage, BIMI) with copy-paste values and live status from the authoritative nameservers. The user adds them at their DNS provider. | `application_id`*, `environment` | Account | `GET /v1/applications/{application_id}/dns` |
| `verify_dns` | Re-checks the DNS records right now (and watches closely for the next minutes). | `application_id`*, `environment` | Account | `POST /v1/applications/{application_id}/dns/verify` |
| `verify_dkim_selectors` | Checks DKIM selectors the user provides. Needed only when the common selectors we try automatically found no key; the user's email provider shows the selector in its DKIM settings. | `application_id`*, `selectors`*, `guest_token` | Free | `POST /v1/applications/{application_id}/dkim-selectors` |
| `create_test_message` | Returns an address the user sends a real email to; we then report SPF/DKIM/DMARC alignment on that actual message. | `application_id`*, `environment` | Account | `POST /v1/applications/{application_id}/test-messages` |
| `get_test_message_result` | Result of the test email: SPF, DKIM, DMARC alignment and findings. | `application_id`*, `test_message_id`*, `environment` | Account | `GET /v1/applications/{application_id}/test-messages/{test_message_id}` |
| `get_certificate` | Certificate status timeline, prerequisites (with the step that fixes each), the latest final check, actions the issuer needs from the user, validity and renewal dates. | `application_id`*, `environment` | Account | `GET /v1/applications/{application_id}/certificate` |
| `run_final_check` | Re-verifies live everything the certificate issuer checks (domain, email protection, logo, company, trademark, DNS records). Runs automatically before the order is submitted and daily during the issuer's review; anything that fails marks its step `attention` and holds the order. | `application_id`*, `environment` | Account | `POST /v1/applications/{application_id}/certificate/check` |
| `order_certificate` | Submits the certificate order (normally automatic once prerequisites are met). Safe to call repeatedly. | `application_id`*, `environment`, `idempotency_key` | Account (`certificates:write`) | `POST /v1/applications/{application_id}/certificate/order` |
| `reissue_certificate` | Requests a reissue (e.g. after a logo change). Re-checks domain ownership first. | `application_id`*, `reason`*, `environment`, `idempotency_key` | Account (`certificates:write`) | `POST /v1/applications/{application_id}/certificate/reissue` |
| `renew_certificate` | Starts the renewal early (renewal is otherwise automatic 45 days before expiry). | `application_id`*, `environment`, `idempotency_key` | Account (`certificates:write`) | `POST /v1/applications/{application_id}/certificate/renew` |
| `revoke_certificate` | PERMANENTLY revokes the certificate; the logo disappears from inboxes. Only with explicit user confirmation: confirm must be exactly "REVOKE <domain>". | `application_id`*, `confirm`*, `reason`*, `environment`, `idempotency_key` | Account (`certificates:write`) | `POST /v1/applications/{application_id}/certificate/revoke` |
| `confirm_inbox_display` | Records that the user saw their logo (and checkmark for VMC) in a mailbox such as Gmail — the final 'display observed' outcome. | `application_id`*, `environment`, `mailbox`, `observed` | Account (`applications:write`) | `POST /v1/applications/{application_id}/inbox-display` |
| `list_orders` | Orders and payments for the account. | `environment` | Account | `GET /v1/orders`<br>`GET /v1/orders/{order_id}` |

\* required.
<!-- END GENERATED: tools -->

## Continuing across conversations

All state lives on the server. Nothing resets when a conversation ends.

- **Save** the `application_id` and, while anonymous, the `guest_token` (valid 30 days, extended on use, 90 days maximum). Tell the person to keep them, or store them in your memory/notes if your client allows.
- **New conversation:** call `list_applications` or `get_application` with the `guest_token`, then read `current_step` and `next_actions` and continue.
- **Switch to the browser:** `create_resume_link` returns a one-time link valid for 24 hours. It opens the exact step in the web app.
- **After sign-in:** once claimed, the person's account (OAuth or API key) is enough; the guest token is no longer needed.
- **Edits are safe:** responses include a `version`. If you send `If-Match` and get `409 version_conflict`, re-read the application and try again. Omitting `If-Match` means "last write wins".

## What only the person can do

You can do almost everything, but some actions are deliberately human-only. Guide the person through each:

| Action | Why | How to guide them |
|---|---|---|
| **Pay** | Agents cannot spend money | Show the estimate, then share the Stripe checkout link from `create_checkout` |
| **Add DNS records** | Only they (or their IT) can change the domain | Give the exact host/type/value list and where to paste it; then run `verify_dns` |
| **Approve the final logo** | It's their brand | Show original vs. converted; call `approve_logo` only after an explicit yes |
| **Confirm authority** | Legal attestation | Ask whether they may act for the company before `authority_attested: true` |
| **Respond to the issuer** | DigiCert may email or call them | Relay `customer_actions` from `get_certificate` |
| **Confirm display** | We can't see their inbox | Ask them to check Gmail, then call `confirm_inbox_display` |

## Shared email providers cannot be used

Addresses at shared providers such as gmail.com, outlook.com, hotmail.com, yahoo.com, icloud.com, proton.me or aol.com cannot get a logo or checkmark. These domains belong to the provider and are shared by millions of people; the logo shown for them is the provider's own. The person needs their **own domain** (like `yourcompany.com`). The API returns `blocked_provider` (HTTP 422) with a plain-English reason; the full list is at `GET https://api.getverifiedinbox.com/v1/providers/blocked`.

## Trademark logic

- **VMC requires a registered trademark** for the logo. The first release checks the **US Patent and Trademark Office (USPTO) only**. Other offices are not yet supported; a human at VerifiedInbox can review special cases (contact support).
- We match the logo against USPTO records automatically (AI vision with a perceptual-hash fallback); a person at VerifiedInbox can verify a match manually when it's ambiguous (`needs_review`).
- **No registered trademark?**
  - If the logo has been in **public use for 12+ months** (we check web archive history), offer a **CMC**: logo, no checkmark.
  - Offer the **trademark filing service**: the person emails `trademark@getverifiedinbox.com`. Registration usually takes several months; they can start with a CMC meanwhile, and move to a VMC later.
- **Neither route yet** (new company, new logo, no trademark): the outcome is `not_currently_eligible`. Explain what's missing and when they may qualify (`estimated_eligible_on`), offer `watch_eligibility` (email reminder), and the trademark service.

## Safe DMARC rollout

Logos only show when the domain's DMARC policy is at enforcement (`p=quarantine` or `p=reject`, 100% of mail). How fast to get there depends on how email is used on the domain (`set_email_usage`):

- **No email yet (`none`)** or **little email (`low`):** publish the blocking record (`p=reject`) straight away. There is little or nothing to break; if a real email ever bounces, the reports show which service needs setting up. `dmarc_rollout.path` is `direct` and `recommended_record` is the blocking record.
- **Email every day (`active`):** tightening too fast can send the company's own newsletters or invoices to spam if some sending service isn't set up yet. The staged plan (`dmarc_rollout.plan`, each stage with its exact record, what to monitor and what happens to email):
  1. **Watch:** `p=none` with reporting (`rua=`), suggested 14 days, while every sending service is set up with SPF/DKIM.
  2. **Filter some:** `p=quarantine; pct=25`, suggested 7 days.
  3. **Filter all:** `p=quarantine` (100%). This meets the requirement.
  4. **Block all (recommended):** `p=reject`.

The waiting times are suggestions, never enforced: the person may skip ahead. If they want to, explain the risk plainly (real emails from a service that isn't set up yet could go to spam or bounce) and give them the record of the stage they choose.

## Pricing

- **Free:** domain check, full email security report, logo preparation and preview, USPTO trademark lookup, eligibility result and price estimate.
- **CMC plan:** $899 per domain per year. **VMC plan:** $1,499 per domain per year. Includes business verification, logo preparation, certificate ordering, hosting of the logo and certificate, monitoring, automatic renewals and reminders, and support.
- **Certificate issuer fee:** charged by the issuer (DigiCert), passed through **without markup**, collected at the same checkout as a **separate line item**. About **$750–$1,750 per year**; current estimates: VMC ~$1,350, CMC ~$950. Example totals: VMC ≈ $2,849/year, CMC ≈ $1,849/year.
- The **estimated total is always shown before payment** (`get_estimate`).
- **Full refund** if the certificate issuer rejects the application.
- Prices are per domain. Payment is by Stripe's hosted checkout.

## Test mode (sandbox)

Signed-in users can switch between **live** and **test** environments (like Stripe). In test mode nothing is charged (Stripe test mode), certificates come from a simulated issuer, and data is kept separate. Use `vi_test_…` API keys or pass `environment: "test"` to account tools. Use test mode when the person wants to see the whole flow before paying, or when you are building an integration.

## REST API fallback

Use this if MCP isn't available but you can make HTTP requests. Every tool above has an equivalent REST operation.

- **OpenAPI 3.1 document (complete contract):** `https://getverifiedinbox.com/openapi.json` (also `https://api.getverifiedinbox.com/openapi.json`). Load it if you can; each operation lists who may call it (`x-access`), whether it needs an `Idempotency-Key` (`x-idempotency`) and the matching MCP tool (`x-mcp-tools`).
- **Base URL:** `https://api.getverifiedinbox.com` (API paths start with `/v1`). JSON bodies, UTF-8. Money is in **cents** (USD).
- **Auth headers:** none for public endpoints; `VI-Guest-Token: vi_guest_…` (or `Authorization: Bearer vi_guest_…`) to continue an anonymous application; `Authorization: Bearer vi_live_…` / `vi_test_…` for an account. A guest token can be combined with an account credential (send it in `VI-Guest-Token`) to claim.
- **Idempotency:** send `Idempotency-Key: <unique per intent>` where an operation's `x-idempotency` says so: required for checkout and certificate operations, optional when starting an application.
- Human-readable reference: [API docs](https://getverifiedinbox.com/docs/api.md).

<!-- BEGIN GENERATED: endpoints (make contract) -->

### Meta

Service metadata, health and this contract.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /health` | Liveness check | Public — no credentials needed | — |
| `GET /openapi.json` | This OpenAPI document | Public — no credentials needed | — |
| `GET /ready` | Readiness check | Public — no credentials needed | — |
| `GET /v1/meta` | Pricing, steps and live/mocked integrations | Public — no credentials needed | `get_started` |

### Checks

Free, repeatable public checks of any domain.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `POST /v1/checks/domain` | Quick domain eligibility check | Public — no credentials needed | `check_domain` |
| `POST /v1/checks/email-auth` | Full SPF/DKIM/DMARC/BIMI inspection | Public — no credentials needed | `check_email_security` |
| `GET /v1/providers/blocked` | Shared mailbox domains that can't be used | Public — no credentials needed | — |

### Glossary

Plain-English definitions of every term we use.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/glossary` | All glossary terms | Public — no credentials needed | — |
| `GET /v1/glossary/{term}` | One glossary term | Public — no credentials needed | `explain_term` |

### Guest sessions

Anonymous credentials and resume links.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `POST /v1/guest-sessions` | Create a guest credential | Public — no credentials needed | — |
| `DELETE /v1/guest-sessions/current` | Revoke the current guest session | Free — guest or account | — |
| `POST /v1/resume` | Exchange a one-time resume token | Public — no credentials needed | — |

### Applications

The server-side state of one domain's journey.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications` | List my verifications | Free — guest or account | `list_applications`, `get_account` |
| `POST /v1/applications` | Start (or resume) a verification | Public — no credentials needed | `start_application` |
| `GET /v1/applications/{application_id}` | Get a verification | Free — guest or account | `get_application` |
| `PATCH /v1/applications/{application_id}` | Choose product / contact email | Free — guest or account | — |
| `POST /v1/applications/{application_id}/archive` | Archive (unpaid only) | Free — guest or account | — |
| `POST /v1/applications/{application_id}/claim` | Move a guest draft into the account | Account required | `claim_application` |
| `GET /v1/applications/{application_id}/events` | Timeline of the verification | Free — guest or account | — |
| `GET /v1/applications/{application_id}/next-steps` | Current step and next actions | Free — guest or account | `get_application` |
| `POST /v1/applications/{application_id}/refresh` | Re-run checks now | Free — guest or account | — |
| `POST /v1/applications/{application_id}/resume-links` | One-time link to continue in a browser | Free — guest or account | `create_resume_link` |
| `POST /v1/applications/{application_id}/steps/{step}/complete` | Complete a wizard step and move on | Free — guest or account | `complete_step` |

### Email health

SPF, DKIM, DMARC and BIMI for an application.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `POST /v1/applications/{application_id}/dkim-selectors` | Verify DKIM selectors you supply | Free — guest or account | `verify_dkim_selectors` |
| `GET /v1/applications/{application_id}/email-health` | Latest email-security report + DMARC rollout plan | Free — guest or account | — |
| `POST /v1/applications/{application_id}/email-health/check` | Re-check email security now | Free — guest or account | `recheck_email_security` |
| `PUT /v1/applications/{application_id}/email-usage` | How email is used on the domain | Free — guest or account | `set_email_usage` |

### Logo

Logo intake, SVG Tiny P/S conversion and approval.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications/{application_id}/logo` | Logo status, analysis and changes | Free — guest or account | `get_logo_status` |
| `PUT /v1/applications/{application_id}/logo` | Submit the logo | Free — guest or account | `submit_logo` |
| `GET /v1/applications/{application_id}/logo-candidates` | Logos found on the website | Free — guest or account | `get_logo_status` |
| `POST /v1/applications/{application_id}/logo/approve` | Approve the reviewed inbox-ready logo | Paid plan required | `approve_logo` |
| `GET /v1/applications/{application_id}/logo/converted.svg` | Inbox-ready SVG Tiny P/S file | Free — guest or account | — |
| `GET /v1/applications/{application_id}/logo/original.svg` | Original logo file | Free — guest or account | — |
| `GET /v1/applications/{application_id}/logo/preview.png` | Rendered PNG preview | Free — guest or account | — |

### Trademark

USPTO trademark search and verification.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications/{application_id}/trademark` | Trademark result | Free — guest or account | `get_trademark_status` |
| `POST /v1/applications/{application_id}/trademark/claim` | Verify a specific USPTO number | Free — guest or account | `search_trademark` |
| `POST /v1/applications/{application_id}/trademark/search` | (Re)start the USPTO search | Free — guest or account | `search_trademark` |

### Eligibility

VMC / CMC / not-yet-eligible outcome and price estimate.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications/{application_id}/eligibility` | VMC / CMC / not-yet-eligible with evidence | Free — guest or account | `get_eligibility` |
| `POST /v1/applications/{application_id}/eligibility/watch` | Email me when this domain qualifies | Free — guest or account | `watch_eligibility` |
| `GET /v1/applications/{application_id}/estimate` | Itemized yearly price | Free — guest or account | `get_estimate` |

### Checkout

Stripe hosted checkout (agents create links; people pay).

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `POST /v1/applications/{application_id}/checkout` | Create a Stripe checkout link | Account required | `create_checkout` |

### Business

Legal company verification.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications/{application_id}/business` | Company verification status | Free — guest or account | `get_business_status` |
| `PUT /v1/applications/{application_id}/business` | Submit legal company details | Paid plan required | `submit_business_details` |

### DNS

The DNS records to add, with live status.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications/{application_id}/dns` | Every DNS record to add, with live status | Paid plan required | `get_dns_records` |
| `POST /v1/applications/{application_id}/dns/verify` | Re-check DNS now | Paid plan required | `verify_dns` |

### Test messages

Authentication results on a real email.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `POST /v1/applications/{application_id}/test-messages` | Get an address to send a real test email to | Account required | `create_test_message` |
| `GET /v1/applications/{application_id}/test-messages/{test_message_id}` | Authentication results of the test email | Free — guest or account | `get_test_message_result` |

### Certificate

Certificate order, status, reissue, renewal and revocation.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications/{application_id}/certificate` | Certificate status, prerequisites, final check and history | Free — guest or account | `get_certificate` |
| `POST /v1/applications/{application_id}/certificate/check` | Re-check everything the issuer will verify | Paid plan required | `run_final_check` |
| `POST /v1/applications/{application_id}/certificate/order` | Submit the order (normally automatic) | Paid plan required | `order_certificate` |
| `POST /v1/applications/{application_id}/certificate/reissue` | Reissue the certificate | Paid plan required | `reissue_certificate` |
| `POST /v1/applications/{application_id}/certificate/renew` | Renew early | Paid plan required | `renew_certificate` |
| `POST /v1/applications/{application_id}/certificate/revoke` | Revoke permanently | Paid plan required | `revoke_certificate` |

### Go live

BIMI publication and display confirmation.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/applications/{application_id}/go-live` | BIMI publication, test email, display, monitoring, renewal | Free — guest or account | — |
| `POST /v1/applications/{application_id}/inbox-display` | Record that the logo was seen in a mailbox | Paid plan required | `confirm_inbox_display` |

### Account

Profile, organizations, environment, API keys, orders.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /v1/api-keys` | API keys | Account required | — |
| `POST /v1/api-keys` | Create an API key (web session) | Account required | — |
| `DELETE /v1/api-keys/{api_key_id}` | Revoke an API key | Account required | — |
| `POST /v1/billing/portal` | Stripe billing portal link | Account required | — |
| `GET /v1/me` | Who am I (works anonymously too) | Public — no credentials needed | `get_account` |
| `POST /v1/me/environment` | Switch live/test mode (web session) | Account required | — |
| `POST /v1/me/organization` | Switch organization (web session) | Account required | — |
| `GET /v1/notifications` | Notification log | Account required | — |
| `GET /v1/orders` | Orders and payments | Account required | `get_account`, `list_orders` |
| `GET /v1/orders/{order_id}` | One order | Account required | `list_orders` |
| `GET /v1/organizations` | My organizations | Account required | — |
| `POST /v1/organizations` | Create an organization | Account required | — |
| `GET /v1/organizations/{organization_id}` | One organization | Account required | — |
| `PATCH /v1/organizations/{organization_id}` | Rename an organization | Account required | — |
| `GET /v1/organizations/{organization_id}/members` | Organization members | Account required | — |

### Support

Contact a human, feedback and feature requests.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `POST /v1/support` | Contact a human, feedback, feature request, partnership | Public — no credentials needed | `contact_support`, `send_feedback` |

### Hosting

Public logo and certificate files referenced by BIMI records.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /bimi/test/{domain}/{file}` | Hosted BIMI assets (test mode) | Public — no credentials needed | — |
| `GET /bimi/{domain}/{file}` | Hosted BIMI logo / certificate | Public — no credentials needed | — |

### MCP

Model Context Protocol endpoint and OAuth discovery.

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `GET /.well-known/oauth-protected-resource` | OAuth protected-resource metadata (RFC 9728) | Public — no credentials needed | — |
| `GET /.well-known/oauth-protected-resource/mcp` | OAuth protected-resource metadata for /mcp | Public — no credentials needed | — |
| `POST /mcp` | MCP endpoint (Streamable HTTP, JSON responses) | Public — no credentials needed | — |

### Test mode

Sandbox helpers (no real payments).

| Method & path | Summary | Access | MCP tool |
|---|---|---|---|
| `POST /v1/dev/mock-checkout/{order_id}/complete` | Simulate payment of a mock checkout | Account required | — |
<!-- END GENERATED: endpoints -->

Example:

```bash
# 1. Quick check (no credentials)
curl -s https://api.getverifiedinbox.com/v1/checks/domain \
  -H 'Content-Type: application/json' -d '{"domain":"acme.com"}'

# 2. Start an application; save application.id and guest_token from the response
curl -s https://api.getverifiedinbox.com/v1/applications \
  -H 'Content-Type: application/json' -H 'Idempotency-Key: start-acme-1' \
  -d '{"domain":"acme.com"}'

# 3. Continue later with the guest token
curl -s https://api.getverifiedinbox.com/v1/applications/APPLICATION_ID \
  -H 'VI-Guest-Token: vi_guest_…'
```

## Errors and limits

Errors look like `{ "error": { "code", "message", "details"?, "next_action"? } }`. The `message` is plain English and safe to show the person. MCP tool failures return `isError: true` with the same message and `next_actions`.

| Code (HTTP) | Meaning | What to do |
|---|---|---|
| `unauthenticated` (401) | This needs an account | Sign in via OAuth, use an API key, or give the person a resume link |
| `payment_required` (402) | This step is paid | Show the estimate and create a checkout link |
| `insufficient_scope` / `forbidden` (403) | The key lacks a scope | Ask the person for a key with the needed scope (`applications:read`, `applications:write`, `billing:write`, `certificates:write`, `support:write`) |
| `not_found` (404) | Wrong id, or no access | Check the id and credentials (we never reveal whether someone else's application exists) |
| `version_conflict` (409) | Someone else changed it | Re-read the application and retry |
| `blocked_provider` (422) | Shared email domain | Ask for their own company domain |
| `rate_limited` (429) | Too many requests | Wait `Retry-After` / `retry_after_seconds`, then retry once |
| `upstream_unavailable` (503) | A provider is temporarily down | Retry later; long-running work continues in the background |

Anonymous usage is rate-limited per IP and per guest, and expensive work (trademark searches, AI logo comparison) has a daily budget. Poll gently: when background work is running, check again after a minute or when the person comes back, not in a tight loop.

## Help, support and feedback

- `contact_support` — message a human (use `kind: "contact_human"` when the person asks for a person, `support` for help with a step). Include the domain and `application_id`. A human replies by email, usually within one business day.
- `send_feedback` — feedback or a feature request.
- `explain_term` — plain-English definition of any term (DMARC, BIMI, VMC…).
- Email: `support@getverifiedinbox.com` · trademark filing: `trademark@getverifiedinbox.com` · web: [getverifiedinbox.com/support](https://getverifiedinbox.com/support.md).

Everything can be done self-service; humans are there if the person wants one.

## How to behave

- **Plain language.** Say "fake-email protection" before "DMARC p=quarantine". Offer technical detail if they ask.
- **Be honest about outcomes.** Never claim the checkmark or logo display is guaranteed; Gmail decides. Never promise a checkmark to someone on the CMC route.
- **Never ask for passwords**, card numbers, DNS-provider logins or one-time codes. Payment happens only on Stripe's page; DNS changes happen in their DNS provider.
- **Confirm before consequential actions:** creating a checkout (show the total first), attesting authority, approving the logo, and especially revoking a certificate.
- **Use `next_actions`.** Every response tells you what's next, whether it needs sign-in or payment, and which tool to call.
- **Keep continuity.** Save the `application_id` and `guest_token`; at the start of a new conversation, look up the existing application instead of starting over.
- **Respect the person's time.** Batch what they need to do (e.g. all DNS records at once) and explain how long waits usually take.
- If anything is unclear or stuck, use `contact_support`, and tell the person a human will follow up by email.
