A licensed CPA confirms your investors are accredited. We add identity, sanctions, and entity checks in the same flow, and write the verified result straight into your CRM. Your brand on it, not ours.
Verification, a signed CRM webhook, and the developer REST API are live today — generate self-serve API keys in your dashboard. Native per-CRM connectors are in early access.
Accreditation is a paperwork chase. Tax returns, net-worth letters, redactions — collected by email and tracked in a spreadsheet.
Your bank and fund admin want more. Identity and sanctions screening on every investor — usually a second vendor, a second flow.
Entities need their own check. LLCs, trusts, and SPVs require business verification and beneficial-owner review — a third system.
Then someone re-keys it by hand. When it's finally done, "verified" gets typed into your CRM manually, one investor at a time.
A licensed CPA's letter — defensible reasonable-steps evidence under Rule 506(c), not a self-cert checkbox.
Government-ID scan plus a liveness selfie, in about a minute — no separate onboarding app.
OFAC and global watchlists, with optional ongoing monitoring — a match flags for CPA review, never an auto-decline.
For entity investors: official registry confirmation plus beneficial-owner identification.
Your logo, your domain, your fund name on the flow and the emails. Investors see you, not us.
When an investor clears, their record is stamped Accredited / KYC / AML / KYB — verified, automatically. No re-keying.
Drop your branded verification link into your investor flow, or start verifications programmatically from your own system.
Accreditation plus whichever checks you turn on — identity, AML, and KYB for entities — in a single branded experience.
A licensed CPA signs off, and the verified status flows back into that investor's record automatically. You watch it on your dashboard.
Rule 506(c) requires you to take reasonable steps to verify each investor is accredited. A licensed CPA's signed letter is exactly the third-party, professional evidence the SEC's safe harbor contemplates — a self-certification checkbox is not. Every letter is reviewed and signed by a licensed CPA, and every certificate is independently verifiable. It supports, but does not discharge, your own reasonable-steps obligation under Rule 506(c).
CPA-signed accreditation with identity, sanctions, and entity checks, on a co-branded link with a live dashboard. You can run investors through it today.
Create and query verifications programmatically — create a verification, poll its status, and download the signed letter. Generate self-serve API keys in your dashboard. See the docs → Prefer no code? Connect with Zapier or Make →
A signed verification.completed event pushed to your endpoint the moment the CPA signs — wire it to Zapier, Make, your CRM, or your own system. Turn it on in your dashboard. See the docs → No-code setup →
You don't need a developer. With Zapier or Make (formerly Integromat), you can push every signed verification into HubSpot, Salesforce, Pipedrive, Google Sheets, Slack, Notion, or Airtable — and even start verifications from your CRM. Native one-click AccreditedNow apps are on the way; the steps below work right now using Zapier's and Make's built-in webhook and HTTP tools.
verification.completed event; Zapier or Make catches it and creates or updates the record in your CRM.sk_live_...) from your sponsor dashboard — used to start verifications.whsec_...) from the same dashboard — used to receive results. Paste your Zapier or Make catch-hook URL into the dashboard's webhook field, then send yourself a test event.403 firm_not_verified. Receiving results works either way.data.investor.email, data.status, data.certificate_id, data.certificate_url, data.verification_date, data.expiration_date. Turn the Zap on.Method: POST
URL: https://accreditednow.org/v1/verifications
Headers: Authorization : Bearer sk_live_...
Content-Type : application/json
Data: {
"investor": {
"email": "{{email}}",
"first_name": "{{first name}}",
"last_name": "{{last name}}"
},
"billing": "partner"
}
The response includes a hosted_url — add a follow-up step (an email, or a CRM task) to send that link to the investor. billing: "partner" covers it from your seat balance; "investor" lets the investor pay at checkout.
data.* fields.POST https://accreditednow.org/v1/verifications, header Authorization: Bearer sk_live_..., body type JSON with the same fields shown above.Every webhook carries an X-AccreditedNow-Signature header so you can confirm it really came from us. Simple setups often skip this because the catch-hook URL is unguessable, but for a hardened flow, verify the HMAC as described in the webhook docs — a small "Code by Zapier" or Make custom-function step.
Published AccreditedNow apps for Zapier and Make — with a ready-made "New verification completed" trigger and a "Create verification" action — are in the works, so this becomes a few clicks with no webhook URLs to copy. Want early access? Tell us which CRM you use.
Create and read verifications from your own backend. Generate an API key in your sponsor dashboard (API keys section). A key authenticates your server as your firm and only ever touches your own verifications. Use it server-side only — never ship it in a browser or mobile app.
Base URL: https://accreditednow.org/v1
Auth: Authorization: Bearer sk_live_...
Because a CPA signs every letter, verification is asynchronous: you create a verification, the investor completes the flow, and a CPA signs (typically within 24 hours). Learn the outcome from the webhook or by polling the status endpoint below.
POST /v1/verifications
{
"investor": {
"email": "jordan@example.com",
"first_name": "Jordan",
"last_name": "Rivera",
"date_of_birth": "1984-03-22",
"nationality": "US"
},
"type": "individual",
"deal": { "name": "Cedar Point Multifamily Fund II" },
"billing": "partner"
}
-> 201
{
"id": "rec0xX...",
"object": "verification",
"status": "created",
"billing": "partner",
"hosted_url": "https://accreditednow.org/verify?sponsor=cedarpoint"
}
billing is "partner" (a seat from your account covers it) or "investor" (the investor pays at checkout). Send the investor to the returned hosted_url to complete verification. Creating a verification never consumes a seat — a seat is drawn only when the investor completes the flow.
investor.date_of_birth (format YYYY-MM-DD) and investor.nationality (ISO 3166-1 alpha-2, e.g. US) are optional. If you run your own identity verification and keep ours off, pass them and we use them to sharpen the sanctions/AML screen — a date of birth lets the screen drop unrelated same-name matches, which sharply cuts false positives. They are used only for screening, never printed on the letter, and are deleted with the rest of the case data at 90 days. Omit them and the screen simply runs on name alone.
GET /v1/verifications/{id}
-> 200
{
"id": "rec0xX...",
"object": "verification",
"status": "verified",
"type": "individual",
"investor": { "name": "Jordan A. Rivera", "email": "jordan@example.com", "city": "Austin", "state": "Texas" },
"basis": "Net Worth",
"verification_date": "2026-08-17",
"expiration_date": "2026-11-15",
"certificate_id": "ANV-4K2P-9QX7-M3TD",
"certificate_url": "https://accreditednow.org/verify-certificate?id=ANV-4K2P-9QX7-M3TD",
"checks": { "identity_verified": true, "sanctions_screened": true, "business_verified": false },
"deal": "Cedar Point Multifamily Fund II",
"letter_available": true,
"created": "2026-08-16"
}
status is one of created, in_review, verified, expired, declined, or refunded. The response is privacy-safe — it never contains the investor's documents, financial figures, or resume token.
GET /v1/verifications?limit=25&offset=0&status=verified
-> 200
{ "object": "list", "data": [ ... ], "total": 42, "limit": 25, "offset": 0, "has_more": true }
GET /v1/verifications/{id}/letter -> 302 redirect to the signed PDF
GET /v1/verifications/{id}/letter?format=json -> { "id": "...", "letter_url": "https://..." }
Returns the letter only when it has been issued and the investor consented to share it with you; otherwise 404 letter_unavailable.
{ "error": { "type": "unauthorized", "message": "Missing or invalid API key." } }
401 invalid/missing key · 403 firm not verified (create) · 404 unknown verification · 400 invalid request · 429 rate limited (120 requests/min per key — honor the Retry-After header).
Use of the API is governed by our API Terms of Service, which supplement our main Terms of Service. Generating an API key constitutes acceptance.
When an investor you cover clears, we POST a signed verification.completed event to your HTTPS endpoint — so your CRM or portal updates the moment the CPA signs, with no polling. Turn it on in your sponsor dashboard: paste an endpoint URL, copy the signing secret, and send yourself a test event.
{
"id": "evt_ANV-4K2P-9QX7-M3TD.completed",
"event": "verification.completed",
"version": "2026-08-18",
"livemode": true,
"created": "2026-08-17T15:04:22.000Z",
"data": {
"certificate_id": "ANV-4K2P-9QX7-M3TD",
"status": "verified",
"investor": {
"name": "Jordan A. Rivera",
"email": "jordan@example.com",
"city": "Austin",
"state": "Texas",
"type": "individual"
},
"basis": "Net Worth",
"verification_date": "2026-08-17",
"expiration_date": "2026-11-15",
"checks": {
"identity_verified": true,
"sanctions_screened": true,
"business_verified": false
},
"deal": "Cedar Point Multifamily Fund II",
"sponsor_slug": "cedarpoint",
"certificate_url": "https://accreditednow.org/verify-certificate?id=ANV-4K2P-9QX7-M3TD"
}
}
The payload is certificate-level and privacy-safe — it never contains the investor's documents, financials, or resume token. Events for a given case are sent only to the sponsor that owns it.
X-AccreditedNow-Event — the event type, e.g. verification.completed.X-AccreditedNow-Delivery — a stable idempotency key, unique per certificate + event. Dedupe on this; the same event may arrive more than once.X-AccreditedNow-Signature — t=<unix-seconds>,v1=<hex-hmac>.Compute an HMAC-SHA256 over `${t}.${rawBody}` using your signing secret, and compare it to v1 with a constant-time check. Verify against the raw request body, before JSON parsing, and reject a timestamp older than five minutes.
const crypto = require('crypto');
function verify(rawBody, header, secret) {
const p = Object.fromEntries(header.split(',').map(kv => kv.split('=')));
const fresh = Math.abs(Date.now() / 1000 - Number(p.t)) < 300;
const expected = crypto.createHmac('sha256', secret)
.update(p.t + '.' + rawBody).digest('hex');
const a = Buffer.from(expected), b = Buffer.from(p.v1 || '');
return fresh && a.length === b.length && crypto.timingSafeEqual(a, b);
}
2xx within a few seconds. A non-2xx or a timeout triggers a bounded retry (short backoff); persistent failure is surfaced in your dashboard.X-AccreditedNow-Delivery id — dedupe on it so a retry never double-writes.livemode is false for dashboard test events and true for real verifications.Generate a test key (sk_test_...) in your sponsor dashboard (API keys section, Mode: Test). Test mode runs entirely in a sandbox: it never creates a real verification, spends a seat, notifies a CPA, or charges anything, so you can build and validate your whole integration — including your webhook receiver — before touching production. Test and live data are completely separate; a test key only ever sees test verifications.
sk_test_ key exactly like a live key — same base URL, same endpoints, same response shapes.POST /v1/verifications returns a simulated verification (its id is prefixed ver_test_) plus a test_complete_url. The returned hosted_url opens your co-branded flow in safe preview — nothing is submitted or charged.POST /v1/verifications/{id}/complete
Auth: Authorization: Bearer sk_test_...
-> 200
{
"id": "ver_test_9f2c...",
"object": "verification",
"status": "verified",
"livemode": false,
"certificate_id": "ANV-TEST-...-SBOX",
"letter_available": true,
"webhook": "sent"
}
This flips the test verification to verified and fires a real verification.completed webhook (with livemode: false) to your configured endpoint — so you can validate your receiver and signature check end to end. GET /v1/verifications/{id}/letter then returns a sample letter. The /complete action exists only in the sandbox; a real verification is completed by a CPA, never via the API.
When your integration works end to end, swap your sk_test_ key for an sk_live_ key from the dashboard. Nothing else changes.
Design-partner sponsors get priority onboarding, a direct say in the first CRM integrations we build, and founder-level pricing locked in. If you're raising under 506(c) and tired of stitching this together yourself, tell us a little and we'll set up a short call.
Prefer email? Reach us at info [at] accreditednow.org.
Related pages
Developer & API documentation · Embed verification in your platform