Credential Verification
The credential verification API provides a single endpoint for validating any VeraID-issued credential at runtime. Use it to authenticate non-human identities at your API gateway, within a service mesh, or as part of custom authentication middleware.
Verification Endpoint
Endpoint: POST /api/v1/credentials/verify
The verification endpoint accepts a credential value and returns its validity status along with the associated identity and credential metadata.
Request
| Field | Type | Required | Description |
|---|---|---|---|
credential | string | Yes | The full credential value (e.g., kd_live_abc...) |
curl -X POST https://app.veraid.io/api/v1/credentials/verify \ -H "Content-Type: application/json" \ -d '{ "credential": "kd_live_aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2u" }'Response: Valid Credential
When the credential is valid, the response includes the identity and credential metadata needed to make authorization decisions downstream.
{ "valid": true, "identity": { "id": "idt_3a1f8c29-b7d4-4e2a-9c8f-1d5e7a2b4c6d", "name": "payment-processor", "type": "SERVICE_ACCOUNT", "status": "ACTIVE", "riskScore": 12, "tags": ["production", "pci-scope"], "metadata": { "team": "payments", "environment": "production" } }, "credential": { "id": "crd_9f24d67e-a1b3-4c5d-8e7f-2a3b4c5d6e7f", "type": "API_KEY", "status": "ACTIVE", "scopes": ["identities:read", "credentials:read"], "expiresAt": "2026-06-19T00:00:00Z", "usageCount": 1424, "usageLimit": 10000 }}Response: Invalid Credential
When the credential is invalid, expired, revoked, or does not exist, the response indicates failure without disclosing the specific reason to prevent information leakage.
{ "valid": false, "identity": null, "credential": null}Verification Checks
When a credential is submitted for verification, VeraID performs the following checks in order. The credential is rejected if any check fails.
- Existence — The credential hash matches a record in the database
- Status — The credential status is
ACTIVE(notREVOKED,EXPIRED, orROTATEDpast its grace period) - Identity status — The associated identity is
ACTIVE(notSUSPENDEDorREVOKED) - Expiration — The current time is before the credential’s
expiresAttimestamp - Usage limit — The credential’s
usageCounthas not exceeded itsusageLimit - IP allowlist — If the identity has
allowedIPsconfigured, the request source IP must match - Origin allowlist — If the identity has
allowedOriginsconfigured, the requestOriginheader must match
Use Cases
API Gateway Middleware
Place the verification endpoint at the entry point of your API to authenticate all incoming NHI requests before they reach your application layer.
// Express middleware exampleimport { Request, Response, NextFunction } from "express";
async function verifyCredential( req: Request, res: Response, next: NextFunction) { const authHeader = req.headers.authorization;
if (!authHeader?.startsWith("Bearer kd_")) { return res.status(401).json({ error: "Missing or invalid credential" }); }
const credential = authHeader.replace("Bearer ", "");
const response = await fetch( "https://app.veraid.io/api/v1/credentials/verify", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ credential }), } );
const result = await response.json();
if (!result.valid) { return res.status(401).json({ error: "Invalid credential" }); }
// Attach identity and credential metadata to the request req.identity = result.identity; req.credential = result.credential;
next();}Service Mesh Validation
In a service mesh architecture, use the verification endpoint as an external authorization service. Each service validates incoming credentials before processing requests, ensuring that compromised services cannot make unauthorized lateral calls.
// Sidecar proxy authorization checkasync function authorizeRequest(credential: string, requiredScopes: string[]) { const response = await fetch( "https://app.veraid.io/api/v1/credentials/verify", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ credential }), } );
const result = await response.json();
if (!result.valid) { return { authorized: false, reason: "Invalid credential" }; }
// Check that the credential has all required scopes const hasScopes = requiredScopes.every((scope) => result.credential.scopes.includes(scope) );
if (!hasScopes) { return { authorized: false, reason: "Insufficient scopes" }; }
// Check risk score threshold if (result.identity.riskScore >= 75) { return { authorized: false, reason: "Identity risk score too high" }; }
return { authorized: true, identity: result.identity };}Custom Auth Middleware
Build custom authentication flows that combine VeraID credential verification with your own authorization logic.
// Next.js API route middlewareimport { NextRequest, NextResponse } from "next/server";
export async function middleware(req: NextRequest) { const credential = req.headers.get("x-api-key");
if (!credential) { return NextResponse.json( { error: "API key required" }, { status: 401 } ); }
const verifyResponse = await fetch( "https://app.veraid.io/api/v1/credentials/verify", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ credential }), } );
const result = await verifyResponse.json();
if (!result.valid) { return NextResponse.json( { error: "Invalid API key" }, { status: 401 } ); }
// Forward identity context to downstream handlers const headers = new Headers(req.headers); headers.set("x-identity-id", result.identity.id); headers.set("x-identity-type", result.identity.type); headers.set("x-identity-risk-score", String(result.identity.riskScore)); headers.set("x-credential-scopes", result.credential.scopes.join(","));
return NextResponse.next({ headers });}Performance Considerations
The verification endpoint is optimized for high-throughput, low-latency authentication.
| Metric | Value |
|---|---|
| Average latency | < 15ms (p50), < 50ms (p99) |
| Rate limit | 10,000 requests/second per tenant |
| Caching | Credential hashes cached in Redis for sub-millisecond lookups |
| Availability | 99.99% SLA |
Error Responses
| Status Code | Meaning |
|---|---|
200 | Verification completed (check valid field for result) |
400 | Malformed request body or missing credential field |
429 | Rate limit exceeded |
500 | Internal verification error (retry with backoff) |
What’s Next
- Credential Overview — Understand credential types, formats, and encryption
- Credential Rotation — Configure automated rotation with zero-downtime grace periods
- Policies Overview — Define access control policies based on identity and credential attributes