Build with theShipToVerified REST API
Create verification sessions, embed our widget on your checkout, and listen for signed webhooks. Everything you need to ship a verified order.
Base URL https://api.shiptoverified.com
Developer-First Design
Everything you need to integrate identity verification in hours, not weeks.
RESTful Design
Clean, predictable URLs and standard HTTP methods. JSON in, JSON out.
Signed Webhooks
Real-time notifications with HMAC-SHA256 signatures and automatic retries with exponential backoff.
Embedded Widget
Ship a single JavaScript snippet and let your customers complete ID capture without leaving checkout.
Sandbox-Ready
Test integrations end-to-end before going live. Reach out for sandbox credentials.
Authentication
Every request to the public API requires two headers issued from your dashboard.
Required headers
X-API-Key— your merchant API key (e.g.vfy_live_xxxxx).X-API-Secret— the paired secret. Treat like a password; never expose it client-side.
curl https://api.shiptoverified.com/api/v1/merchants/me \
-H "X-API-Key: vfy_live_xxxxxxxxxxxxx" \
-H "X-API-Secret: sk_xxxxxxxxxxxxxxxxxxxx"Rotate compromised credentials from your dashboard, under Settings → API Keys. The previous pair is invalidated immediately.
Verification Endpoints
The core of the integration: create a verification, then drive it to completion.
/api/v1/verificationsCreate a verification session for a customer order. The response includes a short-lived widget_token you can hand to the embedded widget on your storefront.
// Request body
{
"transaction_id": "ORD-12345",
"customer_email": "customer@example.com",
"target_name": "Jane Q. Buyer",
"target_address": {
"line1": "123 Main St",
"city": "Los Angeles",
"state": "CA",
"postal_code": "90001",
"country": "US"
}
}
// 201 Created
{
"id": "ver_abc123",
"transaction_id": "ORD-12345",
"status": "pending",
"widget_token": "eyJhbGci...",
"created_at": "2025-01-15T18:04:11Z"
}/api/v1/verifications/{id}Retrieve the current state of a verification. Prefer webhooks over polling for completion notifications.
// 200 OK
{
"id": "ver_abc123",
"status": "verified",
"name_match": { "is_match": true, "score": 0.95, "method": "llm" },
"address_match": { "is_match": true, "score": 0.92, "method": "llm" },
"verified_name": "Jane Q. Buyer",
"verified_at": "2025-01-15T18:07:42Z"
}/api/v1/verifications/{id}/processSubmit the front of the customer’s ID document for OCR and matching. Supply either image_base64 or image_url.
// Request body
{
"image_base64": "data:image/jpeg;base64,/9j/4AAQ..."
}/api/v1/verifications/{id}/secondary-proofSubmit a secondary proof of address (utility bill, lease, bank statement). Only valid when requires_secondary_proof is true.
/api/v1/verifications/{id}/use-id-nameResolve a name mismatch by accepting the name extracted from the ID document.
/api/v1/verifications/{id}/use-id-addressResolve an address mismatch by accepting the address extracted from the ID document.
/api/v1/verifications/{id}/acknowledgeFinalize a verification once name and address are resolved. Fires the verification.completed webhook and marks the verification verified.
/api/v1/verifications/{id}Cancel a pending verification. Invalidates the widget token and fires the verification.cancelled webhook.
Merchant Endpoints
Manage your account, settings, and API credentials programmatically.
/api/v1/merchants/meReturn the merchant account that owns the API credentials in this request.
/api/v1/merchants/me/settingsRead non-sensitive merchant settings (branding, verification rules, notifications).
/api/v1/merchants/me/settingsUpdate merchant settings. Only fields included in the body are changed.
Verification Status Lifecycle
Every verification moves through a deterministic set of states.
pendingVerification created, awaiting an ID submission from the customer.
processingAn ID has been submitted and is being analyzed.
awaiting_actionA name/address mismatch needs to be resolved (use ID data, request secondary proof, etc.).
verifiedVerification complete and acknowledged.
failedDocument could not be processed or verification could not be completed.
cancelledVerification was cancelled by the merchant.
Webhooks
Configure a webhook URL in your dashboard and we'll POST signed events to it as verifications progress.
Events
verification.createdEmitted right after a verification is created via POST /verifications.verification.completedEmitted when the verification transitions to verified after acknowledgment. Carries verified_name, verified_address, and updated_fields (the order fields the customer replaced with their ID values).verification.cancelledEmitted when a verification is cancelled via DELETE /verifications/{id}.
Headers we send
X-VerifyID-Event— event name (e.g.verification.completed).X-VerifyID-Signature—t=<ts>,v1=<hmac_sha256(ts.payload, secret)>.User-Agent—VerifyID-Webhook/1.0.
Example payload
{
"event": "verification.completed",
"timestamp": "2025-01-15T18:07:42Z",
"verification_id": "ver_abc123",
"transaction_id": "ORD-12345",
"customer_id": "cus_4f12",
"status": "verified",
"verified_name": "Jane Q. Buyer",
"verified_address": {
"line1": "123 Main St", "city": "Los Angeles",
"state": "CA", "postal_code": "90001", "country": "US"
},
"updated_fields": [],
"verified_at": "2025-01-15T18:07:42Z",
"method": "primary_id"
}Delivery & retries
We retry non-2xx responses with backoff at 1 min, 5 min, 15 min, 1 hr, and 2 hr. Respond with any 2xx status within 30 seconds to acknowledge delivery. Always verify the signature before trusting payload contents.
Widget Events
If you embed the widget without a backend webhook listener, subscribe to the same lifecycle in the browser with STV.on(...). Every detail carries orderId.
Reacting to a result
On verified, the detail includes verifiedName, verifiedAddress, and updatedFields — the order fields the customer replaced with their ID values ("name" and/or "address", or empty). Apply them to your order without diffing what you originally submitted.
<script src="https://api.shiptoverified.com/widget/v1.js"></script>
<script>
STV.on("verified", function (d) {
// d = { orderId, verifiedName, verifiedAddress, updatedFields }
if (d.updatedFields.length) applyToOrder(d.verifiedName, d.verifiedAddress);
releaseOrder();
});
STV.on("failed", function (d) { routeToManualReview(d.reason); });
STV.on("error", function (d) { console.error(d.message); });
STV.init({ widgetToken: "WIDGET_TOKEN", orderId: "ORD-12345", apiUrl: "https://api.shiptoverified.com" });
</script>Available events
mounted— the widget rendered its UI.verified— identity verified; detail carries verifiedName, verifiedAddress, updatedFields.failed— the customer did not pass; detail carries reason.error— a technical failure (expired session, unreadable file); detail carries message.address-review/address-updated/address-unverified— fire only in the standalone address-only (Radar) validation flow, not the ID flow.
Errors
Errors are returned as JSON with a detail field. Conventional HTTP status codes indicate the error class.
400Verification is in a state that does not accept the requested action (e.g. processing an already-verified session).
401Missing or invalid X-API-Key / X-API-Secret headers.
402Your subscription is inactive. Reactivate billing before creating verifications.
404Verification not found for this merchant.
422Request body failed validation. Check detail for field-level errors.
500Unexpected server error. Safe to retry with exponential backoff.
Quick Start
Create your first verification in three steps.
1. Get your API credentials
Sign up for a free dashboard account; your API key + secret appear under Settings → API.
2. Create a verification
curl -X POST https://api.shiptoverified.com/api/v1/verifications \
-H "X-API-Key: vfy_live_xxxxxxxxxxxxx" \
-H "X-API-Secret: sk_xxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"transaction_id": "ORD-12345",
"customer_email": "customer@example.com",
"target_name": "Jane Q. Buyer",
"target_address": {
"line1": "123 Main St",
"city": "Los Angeles",
"state": "CA",
"postal_code": "90001",
"country": "US"
}
}'3. Embed the widget
On your order-confirmation page, load the standalone bundle and hand it the widget_token from step 2 via STV.init(...). The widget walks the customer through ID capture; react to the result with STV.on(...) (see Widget Events) or the verification.completed webhook.
<!-- On your order-confirmation page -->
<div id="shiptoverified-widget"></div>
<script src="https://api.shiptoverified.com/widget/v1.js"></script>
<script>
STV.init({
widgetToken: "WIDGET_TOKEN_FROM_STEP_2",
orderId: "ORD-12345",
apiUrl: "https://api.shiptoverified.com",
});
</script>BigCommerce and WooCommerce merchants don't need to embed the script manually — install the ShipToVerified app from the marketplace and the widget is injected for you.
Ready to Integrate?
Get your API keys and start verifying customers in minutes. Our team is here to help with integration support.