Skip to main content
We handle — Bots, dupes, and fraud before they get to you. All you decide is where to put the human check in your flow and what happens when someone passes.
These endpoints are public and heavily rate limited. Grab an API key to remove the limits.
1

Create a verification

Step 1: Create a verification

Call POST /v2/verification/create from your backend with a return URL. You get back a link — send your user there.
const response = await fetch(
  "https://api.connect.verifyyou.com/v2/verification/create",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      redirect: "https://yourapp.com/verified",
    }),
  }
);

const data = await response.json();
const verificationUrl = data.verification_url;
// "https://verifyyou.com/i/A3KF9X"
Response
{
  "verification_url": "https://verifyyou.com/i/A3KF9X",
  "external_id": "d4f8e2a1-..."
}
ParameterDescription
redirectWhere to return the user after verification. vy_token and vy_status query parameters are appended.
You can add external_ids to help keep track of accounts. See External IDs for details.
Redirect the user to verification_url — open it as a redirect, in a modal webview, or a new tab.
2

We verify them

Step 2: We verify them

Once the user lands on our flow, VerifyYou runs a two-stage check automatically:
  1. Phone number check — a verified phone number acts as a persistent identifier that follows the user across devices, browsers, and sessions.
  2. Liveness + uniqueness scan — confirms a real human is present and they haven’t verified under a different account.
Desktop vs. mobile. If your user hits the flow on desktop, we hand them off to their phone via a QR code — they scan, complete the liveness capture on mobile, and (on success) the desktop session automatically advances and redirects back to your redirect URL. Users who start on mobile stay on mobile and complete the whole flow on one device. Either way, your app just gets one redirect back with the same query params — you don’t need to branch your integration on device type.
A denied result isn’t a single thing — it means the user failed one of a few checks:
  • Liveness — the capture didn’t confirm a real person was present (e.g. photo of a photo, screen replay, mask).
  • Uniqueness — the person has already verified under another account, either in your app or elsewhere on our network.
  • Risk signals — patterns consistent with fraudulent attempts.
We don’t return the specific reason per attempt on purpose. Exposing which check failed would give bad actors a map of what to try next. That said, we’re working on getting this data back to you in a shape that’s actually useful — more on that down the road.
When done, we redirect back to your redirect URL with query params appended:
https://yourapp.com/verified?vy_token=vt:a1b2c3d4-e5f6-7890-abcd-ef1234567890&vy_status=approved
ParamValues
vy_statusapproved — passed all checks. denied — didn’t pass.
vy_tokenShort-lived verification token (expires after 15 minutes). Use this in step 3 to confirm server-side.
Want to try the flow right now? Generate a test phone number with the sandbox — no API key needed:
curl -s https://api.connect.verifyyou.com/v2/sandbox/phone-number -H "Content-Type: application/json" -d '{}'
Running the flow yourself? There are a few quirks worth knowing — test phone numbers, account stickiness across browsers, and human review. See Testing the flow before you start.
app.get("/verified", (req, res) => {
  const vyToken = req.query.vy_token;
  const vyStatus = req.query.vy_status;
});
3

Confirm the result

Step 3: Confirm the result

Never trust the vy_status query param alone — anyone can fake a URL. Call POST /v2/verification/status from your backend to confirm.Option A — check by token:
const response = await fetch(
  "https://api.connect.verifyyou.com/v2/verification/status",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ token: vyToken }),
  }
);

const data = await response.json();
if (data.verification_complete) {
  console.log("User is verified!");
}
Option B — check by external ID:Use this when the token has expired (after 15 minutes), or when you want to check status without a redirect flow.
const response = await fetch(
  "https://api.connect.verifyyou.com/v2/verification/status",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ external_id: "user_8f3a29c1" }),
  }
);

const data = await response.json();
Response
{
  "verification_complete": true,
  "external_id": "user_8f3a29c1"
}
That’s it. Two endpoints, one redirect, one check — your user is verified as a real, unique human.

API Reference

Full endpoint docs with interactive playground