Authentication
All API requests require a bearer token issued when your membership is approved. Pass it in the Authorization header.
Authorization: Bearer ibp_live_xxxxxxxxxxxxxxxxxxxxxxxx
Keep your API key secret. Rotate it any time from your member dashboard. Test keys prefixed ibp_test_ work against sandbox data and never produce billable output.
Base URL
https://api.insuranceblueprint.org/v1
All requests and responses use JSON (Content-Type: application/json). Dates are ISO 8601 (YYYY-MM-DD). Monetary values are decimal strings.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_data | Request body failed schema validation. Check errors[] in the response. |
401 | unauthorized | Missing or invalid API key. |
403 | forbidden | Your membership doesn't include this form type. |
404 | not_found | The requested form or resource doesn't exist. |
429 | rate_limited | Too many requests. See Retry-After header. |
500 | server_error | Something went wrong on our end. Retrying is safe. |
Generate a Form
Render an insurance form from structured data. Returns a URL to the rendered form and optionally an inline HTML or base64 PDF.
Request parameters
| Field | Type | Description |
|---|---|---|
form_type required |
string |
IBP form type. POI or COI are live. See forms library for all values. |
output_format required |
enum |
pdf, html, or json. Use json to get the validated data back without rendering. |
output_target optional |
enum |
desktop (default), phone, or print. Controls layout and typography optimizations. |
data required |
object |
Form data object. Must conform to IBP-DM-002 for the given form_type. |
webhook_url optional |
string |
If set, the response is delivered asynchronously via POST to this URL instead of inline. |
Code examples
curl -X POST https://api.insuranceblueprint.org/v1/forms/generate \ -H "Authorization: Bearer ibp_live_xxxx" \ -H "Content-Type: application/json" \ -d '{ "form_type": "POI", "output_format": "pdf", "output_target": "print", "data": { "policy_identifier": "IBP-2026-PA-00142", "lob_major_cd": "Personal", "lob_minor_cd": "Personal/Automobile", "effective_dt": "2026-01-01", "expiration_dt": "2027-01-01", "parties": [ { "role": "carrier", "party": { "party_type": "organization", "display_name": "Acme Insurance Company", "identifiers": [{ "identifier_type": "naic", "value": "12345" }] } }, { "role": "named_insured", "is_primary_ind": true, "party": { "party_type": "person", "display_name": "John A. Smith", "addresses": [{ "line1": "456 Elm Avenue", "city": "Springfield", "state": "MO", "postal_code": "65801" }] } } ], "insurables": [ { "insurable_identifier": "INS-VEH-1", "insurable_type": "object", "insurable_subtype": "vehicle", "attributes": { "year": 2022, "make": "Toyota", "model": "Camry" }, "identifiers": [{ "identifier_type": "vin", "value": "4T1B11HK1NU123456" }] } ], "coverages": [ { "coverage_cd": "INS/US/PERS/BI", "insurable_identifier": "INS-VEH-1", "limit_per_occurrence_amt": 100000, "limit_aggregate_amt": 300000 }, { "coverage_cd": "INS/US/PERS/PD", "insurable_identifier": "INS-VEH-1", "limit_per_occurrence_amt": 100000 }, { "coverage_cd": "INS/US/PERS/COMP", "insurable_identifier": "INS-VEH-1", "deductible_amt": 500 }, { "coverage_cd": "INS/US/PERS/COLL", "insurable_identifier": "INS-VEH-1", "deductible_amt": 500 } ] } }'
const response = await fetch('https://api.insuranceblueprint.org/v1/forms/generate', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ form_type: 'POI', output_format: 'pdf', output_target: 'print', data: { policy_identifier: 'IBP-2026-PA-00142', lob_major_cd: 'Personal', lob_minor_cd: 'Personal/Automobile', effective_dt: '2026-01-01', expiration_dt: '2027-01-01', parties: [ { role: 'carrier', party: { party_type: 'organization', display_name: 'Acme Insurance Company', identifiers: [{ identifier_type: 'naic', value: '12345' }] } }, { role: 'named_insured', is_primary_ind: true, party: { party_type: 'person', display_name: 'John A. Smith', addresses: [{ line1: '456 Elm Avenue', city: 'Springfield', state: 'MO', postal_code: '65801' }] } } ], insurables: [ { insurable_identifier: 'INS-VEH-1', insurable_type: 'object', insurable_subtype: 'vehicle', attributes: { year: 2022, make: 'Toyota', model: 'Camry' }, identifiers: [{ identifier_type: 'vin', value: '4T1B11HK1NU123456' }] } ], coverages: [ { coverage_cd: 'INS/US/PERS/BI', insurable_identifier: 'INS-VEH-1', limit_per_occurrence_amt: 100000, limit_aggregate_amt: 300000 }, { coverage_cd: 'INS/US/PERS/PD', insurable_identifier: 'INS-VEH-1', limit_per_occurrence_amt: 100000 }, { coverage_cd: 'INS/US/PERS/COMP', insurable_identifier: 'INS-VEH-1', deductible_amt: 500 }, { coverage_cd: 'INS/US/PERS/COLL', insurable_identifier: 'INS-VEH-1', deductible_amt: 500 } ] } }) }); const { form_url, form_id } = await response.json(); console.log('Form ready:', form_url);
import requests payload = { "form_type": "POI", "output_format": "pdf", "output_target": "print", "data": { "policy_identifier": "IBP-2026-PA-00142", "lob_major_cd": "Personal", "lob_minor_cd": "Personal/Automobile", "effective_dt": "2026-01-01", "expiration_dt": "2027-01-01", "parties": [ {"role": "carrier", "party": {"party_type": "organization", "display_name": "Acme Insurance Company", "identifiers": [{"identifier_type": "naic", "value": "12345"}]}}, {"role": "named_insured", "is_primary_ind": True, "party": {"party_type": "person", "display_name": "John A. Smith", "addresses": [{"line1": "456 Elm Avenue", "city": "Springfield", "state": "MO", "postal_code": "65801"}]}} ], "insurables": [ {"insurable_identifier": "INS-VEH-1", "insurable_type": "object", "insurable_subtype": "vehicle", "attributes": {"year": 2022, "make": "Toyota", "model": "Camry"}, "identifiers": [{"identifier_type": "vin", "value": "4T1B11HK1NU123456"}]} ], "coverages": [ {"coverage_cd": "INS/US/PERS/BI", "insurable_identifier": "INS-VEH-1", "limit_per_occurrence_amt": 100000, "limit_aggregate_amt": 300000}, {"coverage_cd": "INS/US/PERS/PD", "insurable_identifier": "INS-VEH-1", "limit_per_occurrence_amt": 100000}, {"coverage_cd": "INS/US/PERS/COMP", "insurable_identifier": "INS-VEH-1", "deductible_amt": 500}, {"coverage_cd": "INS/US/PERS/COLL", "insurable_identifier": "INS-VEH-1", "deductible_amt": 500} ] } } r = requests.post( "https://api.insuranceblueprint.org/v1/forms/generate", headers={"Authorization": f"Bearer {api_key}"}, json=payload ) r.raise_for_status() form_url = r.json()["form_url"] print(f"Form ready: {form_url}")
Response
{
"form_id": "frm_01j9xyz",
"form_type": "POI",
"data_model": "IBP-DM-002",
"created_at": "2026-08-21T14:22:11Z",
"form_url": "https://cdn.ibp.org/forms/frm_01j9xyz.pdf",
"expires_at": "2026-09-21T14:22:11Z", // CDN URL TTL
"data": { /* validated IBP-DM-002 payload echoed back */ }
}
Parse a Form
Submit a completed insurance form — as a PDF, image, or filled HTML — and receive structured JSON conforming to IBP-DM-002. Use this to ingest forms from any source into your system.
Request parameters
| Field | Type | Description |
|---|---|---|
form_type optional |
string |
Hint the parser with the expected form type. If omitted, the API infers it from the document. |
source_url required* |
string |
URL of the form PDF or image. Mutually exclusive with source_base64. |
source_base64 required* |
string |
Base64-encoded PDF or image. Mutually exclusive with source_url. Max 10 MB. |
source_mime optional |
string |
MIME type of the source (application/pdf, image/jpeg, image/png). Required with source_base64. |
* Provide exactly one of source_url or source_base64.
Code examples
curl -X POST https://api.insuranceblueprint.org/v1/forms/parse \ -H "Authorization: Bearer ibp_live_xxxx" \ -H "Content-Type: application/json" \ -d '{ "form_type": "POI", "source_url": "https://your-system.com/uploads/poi-scan.pdf" }'
const response = await fetch('https://api.insuranceblueprint.org/v1/forms/parse', { method: 'POST', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ form_type: 'POI', source_url: 'https://your-system.com/uploads/poi-scan.pdf' }) }); const { data, confidence } = await response.json(); // data conforms to IBP-DM-002 console.log('Insured:', data.parties.find(p => p.role === 'named_insured').party.display_name); console.log('Confidence:', confidence); // 0.0 – 1.0
r = requests.post(
"https://api.insuranceblueprint.org/v1/forms/parse",
headers={"Authorization": f"Bearer {api_key}"},
json={
"form_type": "POI",
"source_url": "https://your-system.com/uploads/poi-scan.pdf"
}
)
result = r.json()
data = result["data"] # IBP-DM-002 payload
confidence = result["confidence"] # 0.0 – 1.0
Response
{
"parse_id": "prs_01j9xyz",
"form_type": "POI",
"confidence": 0.97, // overall extraction confidence
"created_at": "2026-08-21T14:31:08Z",
"data": {
"form_type": "POI",
"data_model": "IBP-DM-002",
"policy_identifier": "IBP-2026-PA-00142",
"effective_dt": "2026-01-01",
// ... full IBP-DM-002 fields
},
"field_confidence": {
"policy_identifier": 0.99,
"insurables[0].identifiers.vin": 0.95,
"effective_dt":0.98
}
}
Validate Data
Check a data payload against IBP-DM-002 without rendering a form. Returns field-level validation errors. Useful for pre-flight checks before calling /generate.
// Request { "form_type": "POI", "data": { /* ... */ } } // Response — valid { "valid": true, "errors": [] } // Response — invalid { "valid": false, "errors": [ { "field": "insurables[0].identifiers.vin", "message": "VIN must be 17 characters" }, { "field": "effective_dt", "message": "Required field is missing" } ] }
Webhooks
Register an HTTPS endpoint in your member dashboard. IBP will POST event payloads to it as forms are generated, submitted, or parsed. All deliveries include a signature for verification.
| Field | Type | Description |
|---|---|---|
url required |
string |
Your HTTPS endpoint. Must return 2xx within 10 seconds. |
events required |
string[] |
List of events to subscribe to. Use ["*"] for all events. |
form_types optional |
string[] |
Filter events to specific form types. Omit to receive all types. |
Webhook Events
| Event | Triggered when |
|---|---|
form.generated | A form was successfully rendered from data via /generate. |
form.parsed | A completed form was successfully parsed via /parse. |
form.submitted | A form rendered by IBP was completed and submitted by an end user. |
form.expired | A CDN-hosted form URL expired. |
validation.failed | A /generate or /parse call was rejected due to schema errors. |
Payload shape
{
"id": "evt_01j9abc",
"event": "form.generated",
"api_version":"2026-08-21",
"created_at": "2026-08-21T14:22:11Z",
"form_type": "POI",
"form_id": "frm_01j9xyz",
"outputs": {
"pdf_url": "https://cdn.ibp.org/forms/frm_01j9xyz.pdf",
"html_url": "https://cdn.ibp.org/forms/frm_01j9xyz.html"
},
"data": { /* full IBP-DM-002 payload */ }
}
Webhook Security
Every webhook delivery includes an IBP-Signature header. Verify it before processing the payload.
const crypto = require('crypto'); function verifyWebhook(rawBody, signature, secret) { const expected = 'sha256=' + crypto .createHmac('sha256', secret) .update(rawBody) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expected) ); }
import hmac, hashlib def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool: expected = "sha256=" + hmac.new( secret.encode(), raw_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(signature, expected)
Data Model: POI
Fields required and optional for form_type: "POI" (Personal Auto Proof of Insurance). Full schema: IBP-DM-002.
| Field | Type | Required | Notes |
|---|---|---|---|
policy_identifier | string | yes | Carrier-issued policy number |
effective_dt | date | yes | ISO 8601 date |
expiration_dt | date | yes | ISO 8601 date |
lob_major_cd | codelist | yes | Personal |
lob_minor_cd | codelist | yes | Personal/Automobile |
parties[].role | enum | yes | carrier, named_insured, driver, owner |
parties[].party.display_name | string | yes | Person or organization name |
parties[].party.identifiers[] | Identifier[] | opt | e.g. naic on the carrier party |
parties[].party.addresses[] | Address[] | opt | line1, city, state, postal_code |
insurables[].insurable_identifier | string | yes | Stable key referenced by coverages |
insurables[].insurable_subtype | enum | yes | vehicle |
insurables[].attributes.year | integer | yes | 4-digit model year |
insurables[].attributes.make | string | yes | |
insurables[].attributes.model | string | yes | |
insurables[].identifiers[] | Identifier[] | yes | 17-character vin |
coverages[].coverage_cd | codelist | yes | e.g. INS/US/PERS/BI, INS/US/PERS/PD, INS/US/PERS/COMP, INS/US/PERS/COLL |
coverages[].insurable_identifier | string | opt | References insurables[].insurable_identifier |
coverages[].limit_per_occurrence_amt | decimal | opt | Required for BI, PD |
coverages[].limit_aggregate_amt | decimal | opt | BI aggregate limit |
coverages[].deductible_amt | decimal | opt | Required for COMP, COLL |
Data Model: COI
Fields for form_type: "COI" (Commercial Certificate of Insurance). Full schema: IBP-DM-002.
| Field | Type | Required | Notes |
|---|---|---|---|
lob_major_cd | codelist | yes | Commercial |
lob_minor_cd | codelist | opt | Prefixed sub-line when single-line (e.g. Commercial/Trucking) |
parties[].role | enum | yes | carrier, named_insured, certificate_holder, additional_insured, producer |
parties[].party.display_name | string | yes | Name for each party role |
parties[].party.addresses[] | Address[] | yes | Required for named insured & certificate holder |
parties[].is_primary_ind | boolean | opt | Marks the primary party in a role |
coverages[].coverage_cd | codelist | yes | e.g. INS/US/COMM/GL, INS/US/COMM/AUTO, INS/US/COMM/UMBRELLA, INS/US/COMM/WC |
coverages[].policy_identifier | string | yes | Per coverage line |
coverages[].effective_dt | date | yes | Per coverage line |
coverages[].expiration_dt | date | yes | Per coverage line |
coverages[].limit_per_occurrence_amt | decimal | opt | |
coverages[].limit_aggregate_amt | decimal | opt | |
coverages[].forms[] | FormRef[] | opt | Attached endorsement forms |
description_of_operations | string | opt | Max 500 chars |
cancellation_notice_days | integer | opt | Default 30 |