COI automation in NowCerts connects NowCerts webhooks to a small service that creates or updates CRM records, then uses the SendCertificate API to email certificates and records every send for tracking. We built this for a commercial P&C agency so COI requests stop piling up in inboxes. This guide shows the exact pattern we shipped and the gotchas we solved.
Definition: Certificates of Insurance automation is a workflow that receives certificate events from the AMS, issues approved certificates via API, updates the CRM, and emails holders with an auditable trail.
What problem does this solve?
Most agencies handle COIs by watching a shared inbox, keying holder details into NowCerts, exporting or emailing the ACORD form, then updating the CRM manually. That chain is slow and brittle. We replaced it with a webhook driven flow that updates the CRM and dispatches the certificate in one pass.
| Manual COI handling | Automated with NowCerts + CRM |
|---|---|
| Staff monitors inbox for COI requests | NowCerts webhook fires on holder or certificate changes |
| Copy holder details into the CRM later (or never) | Service upserts the account/contact in your CRM immediately |
| Email the COI as an attachment from Outlook | Service calls SendCertificate to email the holder from NowCerts |
| Track who got what in spreadsheets | Every send is logged with IDs and timestamps in a dashboard |
| Risk of sending held certificates | Approve step respected, holds are not released until approved |
How does the NowCerts COI automation work?
At a high level: NowCerts pushes a webhook whenever a certificate or holder changes. Our service consumes the webhook, normalizes the data, upserts the CRM record, and if rules allow, emails the certificate through NowCerts using the SendCertificate endpoint. If the certificate is in a hold state, we queue it until an Approve call is made, then release it using the Approve endpoint.
- NowCerts webhooks: First class webhook feature that posts JSON to your URL for events including MasterCertificate and CertificateHolder insert, update, and delete.
- Orchestration service: A lightweight Node or Python service handles inbound webhooks, retry, mapping, idempotency, and send rules. We host it on Vercel or Railway.
- CRM sink: We write holder and request details into the CRM so producers and account managers see COI status and history.
- SendCertificate action: The service calls the NowCerts SendCertificate API to email the COI when rules pass.
- Approve release: For held certificates, the service waits for approval and then calls the Approve endpoint to release the send.
Step-by-step: how do you build this integration?
1) Configure the NowCerts webhook URL
Point NowCerts at your public webhook endpoint. Webhooks deliver JSON for certificate and holder changes. In our deployments we terminate HTTPS at the edge and verify origin by checking expected fields and agency identifiers. Multiple webhook endpoints may not be supported in-product, so we route internally if we need to fan out.
# Example: expose a local Next.js API route for testing
yarn add localtunnel
npx localtunnel --port 3000 --subdomain your-agency-coi
# Set webhook URL in NowCerts Agency Profile to:
# https://your-agency-coi.loca.lt/api/nowcerts/webhookGotcha: Webhook configuration appears as a single URL in Agency Profile. If you need multiple downstream consumers, implement routing in your service.
2) Receive and validate certificate events
We normalize the payload, enforce idempotency on a stable key, and branch by event type. The example below shows a Next.js handler writing a durable job to process the event.
// pages/api/nowcerts/webhook.ts
import type { NextApiRequest, NextApiResponse } from "next";
import crypto from "crypto";
import { enqueue } from "../../lib/jobs";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "POST") return res.status(405).end();
const payload = req.body; // NowCerts posts JSON
// Build a stable idempotency key
const idem = crypto.createHash("sha256").update(JSON.stringify({
type: payload?.EventType,
id: payload?.EntityId,
ts: payload?.Timestamp
})).digest("hex");
await enqueue("process-coi-event", { idem, payload });
return res.status(202).json({ ok: true });
}Gotcha: Documentation gaps exist on some events. Plan to log unknown shapes and validate against the Postman collection and live test traffic.
3) Upsert the account and contact in your CRM
We map holder and insured details into the CRM so the team has one view of status. Keep it vendor neutral: push to your CRM's contact and company objects and tag the record with a NowCerts ID to prevent duplicates.
// lib/crm.ts
export async function upsertCrmContact({ email, name, phone, externalId }: any) {
const resp = await fetch(process.env.CRM_UPSERT_URL as string, {
method: "POST",
headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.CRM_TOKEN}` },
body: JSON.stringify({ email, name, phone, externalId, source: "nowcerts" })
});
if (!resp.ok) throw new Error(`CRM upsert failed: ${resp.status}`);
return resp.json();
}Gotcha: Use a dedicated externalId field in the CRM to enforce idempotent upserts. Avoid concatenated name keys which will drift.
4) Call SendCertificate to email the COI
NowCerts exposes a public REST API at api.nowcerts.com. We invoke the SendCertificate endpoint to deliver the COI by email. Authentication uses NowCerts' user authentication and token refresh flow. The exact auth type is agency specific, so follow the official Postman collection.
// lib/nowcerts.ts
export async function sendCertificate({ token, body }: { token: string, body: any }) {
const resp = await fetch("https://api.nowcerts.com/api/SendCertificate/SendCertificate", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token // per NowCerts User Authentication
},
body: JSON.stringify(body) // body per agency's Postman-tested payload
});
if (!resp.ok) throw new Error(`SendCertificate failed: ${resp.status}`);
return resp.json();
}Gotcha: Some certificates are held. Your automation must respect holds. Do not attempt to send until approved.
5) Release held certificates with Approve when required
If your workflow uses an approval hold, release it explicitly before sending. The API exposes a dedicated Approve action.
export async function approveCertificate({ token, approvalBody }: { token: string, approvalBody: any }) {
const resp = await fetch("https://api.nowcerts.com/api/SendCertificate/Approve", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token
},
body: JSON.stringify(approvalBody)
});
if (!resp.ok) throw new Error(`Approve failed: ${resp.status}`);
return resp.json();
}Gotcha: Skipping Approve on held certificates results in no send even though your job completes. We gate our send step behind a status check and only release when the approval is confirmed.
6) Log every send for audit and service visibility
Store the NowCerts IDs, holder email, delivery channel, and timestamps in a small Postgres table. Surface that log in your internal dashboard and mirror key fields back to the CRM timeline.
-- schema.sql
create table coi_sends (
id uuid primary key default gen_random_uuid(),
nowcerts_certificate_id text not null,
holder_email text not null,
delivery_channel text not null, -- email or fax
approved boolean not null default false,
sent_at timestamptz,
created_at timestamptz not null default now()
);
create index on coi_sends(nowcerts_certificate_id);Gotcha: If you also enable in-app Excel exports, label those files with the NowCerts certificate ID so file shares match your audit log when a client asks who received what.
Where does this usually get complicated?
- No native Zapier or Make app: There is no official NowCerts app in Zapier or Make. Expect to build with Webhooks or HTTP modules and handle mapping and error retries yourself.
- Approval hold behavior: The API includes an explicit Approve step to release held certificates. If you skip it, nothing sends. We enforce a preflight approval check in code.
- Documentation gaps: Several API Help entries show No documentation available. We validated requests against the live Help pages and the Postman collection before promoting to production.
- Single webhook URL: Webhook configuration appears as one URL in Agency Profile. If you need multiple consumers, route internally and keep your external URL constant.
- Auth specifics vary: NowCerts documents user authentication and token refresh. The exact auth type is not stated publicly in detail. We follow the official Postman collection and store tokens securely.
What does this change for an insurance agency?
For the agency we implemented, COIs stopped clogging the shared inbox. Certificates issued from the NowCerts API, CRM records stayed up to date, and service staff worked exceptions instead of re-keying data. As a broader reference point, McKinsey estimates that about 30 percent of activities in 60 percent of occupations could be automated, which tracks with the service-heavy COI workload we saw. Source: https://www.mckinsey.com/capabilities/operations/our-insights/what-is-automation
Frequently asked questions
Does NowCerts have an API to send certificates?
Yes. NowCerts exposes a public REST API at api.nowcerts.com. You can send certificates via POST to the SendCertificate endpoint and release held certificates via POST to the Approve endpoint. Follow the official Help and Postman collection for request details and authentication.
Can NowCerts trigger my automation when a holder is added or a certificate changes?
Yes. NowCerts has first class webhooks. You can configure a webhook URL and receive JSON events for many actions, including MasterCertificate and CertificateHolder insert, update, and delete. We use those events to drive CRM upserts and sends.
Is there a Zapier or Make connector for NowCerts?
No official app exists in Zapier or Make at this time. You can still integrate using Zapier Webhooks or Make HTTP modules. Expect to build your own request mapping, retries, and error handling rather than relying on a native connector.
How do you prevent duplicate sends and duplicate CRM contacts?
We compute an idempotency key from the event payload and store it. For CRM records, we upsert by a stable externalId that points to the NowCerts ID. For sends, we log NowCerts certificate IDs and block a second send unless a resend is explicitly requested.
Can the system handle approvals before sending?
Yes. If your internal policy holds certificates for review, we queue the send step until the approval condition is met. Then we call the Approve endpoint before invoking SendCertificate so that held certificates release cleanly.
If you want COIs to move from inbox-bound requests to tracked, automated sends that update your CRM and email the holder in one pass, we have shipped this exact pattern. See our broader CRM automation services at /services#crm-automation, our related post on bridging a similar AMS gap in /blog/ezlynx-zapier-integration-gap-bridge, and when you are ready to scope your agency's flow, /book.
Want us to build this for you?
15-minute discovery call. No pitch. We tell you what to automate first.
Book a Discovery Call