Overview
Socious Verify lets your application ask a person to prove something about themselves — that they passed identity verification, that the phone number or address they gave you is really theirs, that they hold a work certificate, that they are a member of your organization — and get back a signed answer you can act on.
The person keeps their credentials in the Socious Wallet on their own device. Your application never stores them, and never sees anything the person did not agree to share for this request.
A credential proves a value, not just that a check once ran: the wallet’s phone and address credentials carry the verified phone number (E.164) and the verified address as claims, so a successful share hands your application the value itself, signed. Phone and address coverage needs Premium+ — see Plans, tiers and usage.
This documentation is for developers. If you are looking for the non-technical product guide — how to run KYB, create schemas and issue credentials from the dashboard — start with the Socious Verify Guide.
Base URLs
| URL | |
|---|---|
| REST API | https://api.shinid.com |
| Dashboard and hosted pages | https://app.shinid.com |
There is one environment. Integration testing uses sandbox verifications — a flag on a verification rather than a separate host — so you test against the same API, the same key and the same validation code. See Sandbox mode.
An organization on the dashboard is a team, not a single login: members are invited by email and carry owner, admin or member roles, and API calls act for an organization you belong to — see Authentication.
The two things you can build
Verify someone. You define a verification request once (which credential, which
conditions), then run it against as many people as you like. Each run is a verification
individual that moves through a short status lifecycle until it is VERIFIED or
FAILED. This is the path most integrations need, and it is the one your API key
reaches. Start at Verify a person — hosted page.
Issue credentials. Your organization can be the issuer: you define a schema, add recipients, and send them credentials they claim into their wallet. Today this runs through the dashboard rather than through an API key — see Issuing credentials for exactly what is and is not reachable programmatically.
How a verification actually runs
- Your backend opens a verification for one person, identified by your own
customer_id. - The person is shown a connection link — as a QR code on desktop, or opened directly on mobile, where it launches the Socious Wallet.
- The wallet connects, Socious Verify sends the proof request, and the person approves sharing.
- Socious Verify checks the presented credential’s signature, its issuer, and every condition you set.
- Your backend reads the result.
Steps 2 and 3 happen on the person’s device and take as long as they take. Everything your backend does is either a redirect (step 2) or a read (step 5), so the integration is small: two calls in the hosted flow, four in the direct one.
The whole integration, in code
The direct flow above, end to end. The first three calls take no key; only the last — the one that changes state in your system — uses your Secret Key, server-side:
const BASE = 'https://api.shinid.com';
// 1. Open a run for one of your users.
// Idempotent on (customer_id, verification_id) — safe to call on every page load.
const individual = await fetch(`${BASE}/verifications/individuals`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ verification_id: VERIFICATION_ID, customer_id: user.id }),
}).then((r) => r.json());
// 2. Get a connection link — render it as a QR code on desktop; on mobile,
// open it directly and it hands off to the Socious Wallet.
// A link lives 2 minutes; call again to refresh an expired one.
const { connection_url } = await fetch(
`${BASE}/verifications/${individual.id}/connect`,
).then((r) => r.json());
// 3. Poll while the person approves in their wallet — no key, so this can run
// in the browser to drive your UI. Stop on VERIFIED or FAILED.
const pending = await fetch(
`${BASE}/verifications/${individual.id}/verify`,
).then((r) => r.json());
// 4. Decide from your backend, with your key — never from the browser's poll.
const result = await fetch(
`${BASE}/verifications/${VERIFICATION_ID}/individuals/${user.id}`,
{ headers: { apikey: process.env.SHINID_SECRET_KEY } },
).then((r) => r.json());
if (result.status === 'VERIFIED') {
// Grant access. result.body carries the claims the person shared —
// for a phone credential, that includes the verified number itself.
}
VERIFICATION_ID comes from the dashboard, where you define what gets asked for —
see Verification requests. If you do not need the
QR code inside your own UI, the hosted flow replaces steps
1–3 with a single redirect.
See it working
verify-demo.socious.io is this exact integration, running live — a voting-eligibility app for a governance organization that requires independent identity, phone and address verification before a member may vote.
- Member view — the verifications this member still owes, a button into the Socious Wallet to complete each one, and the ballot once they are eligible.
- Admin view — every member, whether they may vote, and for those who may not, exactly which requirement is unmet — per-requirement reasons instead of one opaque boolean.
It runs live against api.shinid.com — real wallet connections, real presentations —
and the wallet’s identity check exposes selectable outcomes, so you can produce an
approval, an address mismatch, a high-risk phone number or a liveness failure on demand
and watch what your own integration would see. The client behind it is the four calls
above plus a per-requirement policy evaluator; nothing more. To drive your own
integration the same way without a wallet at all, see
Sandbox mode.
What to read next
| If you want to | Read |
|---|---|
| Get an API key and understand what it can reach | Authentication |
| Ship the fastest working integration | Verify a person — hosted page |
| Test your integration without a person or a wallet | Sandbox mode |
| Render the QR code inside your own UI | Verify a person — direct API |
| Define what gets asked for, and pin the issuer | Verification requests |
| Cover your people’s wallet verifications | Organization codes |
| Know why a call returned 402 | Plans, tiers and usage |
| Look up one endpoint | API reference |
Support
Contact us through the contact page. For anything about a specific run, include the verification ID and the individual ID — with those two we can see exactly where it stopped.