Getting Started with the Billy API
The Billy API lets you automate certificate of insurance (COI) tracking, vendor compliance, and requirement management from any system: your ERP, project management platform, or custom application. It uses conventional HTTP requests in a RESTful architecture, with JSON request and response bodies.
You can read more about integration use cases on our Billy API overview page.
Environments
Billy provides a dedicated sandbox environment for development and testing, separate from production. Your sandbox and production base URLs are shared along with your client credentials when you are granted API access, together with a Postman collection so you can explore every endpoint before writing code.
Authentication
All API requests (except authentication itself) require a valid Bearer token in the Authorization header. Exchange your client credentials for a token, which is valid for 120 minutes (7,200 seconds):
POST /api/v1/authentication/token
{
"grant_type": "basic",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET"
}
The response contains your access_token. Include it on every subsequent request:
curl --request GET \
--url https://{your_base_url}/api/v1/projects \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
When your token expires, simply request a new one.
Pagination and filtering
All list endpoints are paginated. Use page to navigate and per_page to change the page size (default 100). The response headers include total-count (total records), total-page (total pages), and has-more (true when more records exist beyond the current page).
You can also filter any list endpoint by updated_at using a since parameter with an ISO 8601 datetime, which is ideal for incremental syncs:
?page=1&per_page=50&since=2024-12-31T00:00:00
Error responses
400 Bad Request: a required parameter was missing or invalid
401 Unauthorized: the access token is missing or invalid
404 Not Found: the specified resource does not exist
422 Unprocessable Entity: the request body failed validation
428 Precondition Required: a precondition was not met (e.g. rate limit)
500 Internal Server Error: a server error occurred
Key concepts
Projects represent construction or development sites that require insurance coverage.
Vendors are contractors or service providers that need to be insured for projects. You can reference vendors by your own
external_id, which makes ERP integrations straightforward.Contracts associate vendors with projects and define which insurance requirements apply. Each contract's compliance data shows requirement status along with matched policy details (carrier, limits, effective and expiration dates).
Requirement Groups define sets of insurance and document requirements. Project groups apply at the contract level; company groups apply at the vendor level.
Certificates are uploaded COI documents that satisfy insurance requirements.
Custom Forms are questionnaires vendors complete as part of their compliance requirements.
Endpoint overview
Team
GET /api/v1/team: returns your team's details, including theslugandbase_ui_urlfor building deep links into the Billy web app.
Projects
GET /api/v1/projects: list all projectsGET /api/v1/projects/:project_id: get a project by IDPOST /api/v1/projects: create a projectPATCH /api/v1/projects/:project_id: update a projectGET /api/v1/projects/:project_id/additional_insureds: list additional insuredsPOST /api/v1/projects/:project_id/additional_insureds: create an additional insuredPATCH /api/v1/projects/:project_id/additional_insureds/:id: update an additional insuredDELETE /api/v1/projects/:project_id/additional_insureds/:id: delete an additional insured
Vendors
GET /api/v1/vendors: list vendors (includes compliance status and contacts)GET /api/v1/vendors/:vendor_id: get a vendor by Billy IDGET /api/v1/vendors/user_defined/:external_id: get a vendor by your own external IDPOST /api/v1/vendors: create a vendorPATCH /api/v1/vendors/:vendor_id: update a vendorDELETE /api/v1/vendors/:vendor_id: archive a vendor (soft delete)POST /api/v1/vendors/:vendor_id/send_request: email a document request to the vendor's primary contact (rate limited to once per 10 minutes per vendor)POST /api/v1/vendors/bulk: bulk create vendorsPATCH /api/v1/vendors/bulk: bulk update vendorsPOST /api/v1/vendors/bulk_send_request: bulk send document requests
Vendor Contacts and Contacts
POST /api/v1/vendors/:vendor_id/contacts: create a vendor contactPATCH /api/v1/vendors/:vendor_id/contacts/:contact_id: update a vendor contactPUT /api/v1/vendors/:vendor_id/contacts/:contact_id/primary: set the primary contactDELETE /api/v1/vendors/:vendor_id/contacts/:contact_id: archive a vendor contactGET /api/v1/contacts/:contact_id: get a contactPOST /api/v1/contacts: create a contactPATCH /api/v1/contacts/:contact_id: update a contact
Contracts
GET /api/v1/projects/:project_id/contracts: list a project's contracts with full compliance detailGET /api/v1/contracts/:contract_id: get a contract by IDPOST /api/v1/contracts: create a contract (therequirement_group_idis optional and defaults to the project's default group)PATCH /api/v1/contracts/:contract_id: update a contractPOST /api/v1/contracts/:contract_id/send_request: email a document request to the contract's contact (rate limited to once per 10 minutes per contract)POST /api/v1/contracts/bulk: bulk create contractsPATCH /api/v1/contracts/bulk: bulk update contractsPOST /api/v1/contracts/:contract_id/waived_requirements: waive a requirement for a contractDELETE /api/v1/contracts/:contract_id/waived_requirements/:requirement_id: remove a waiver
Requirement Groups
GET /api/v1/requirement_groups/project: list project requirement groupsGET /api/v1/requirement_groups/project/:id: get a project requirement group with its requirementsGET /api/v1/requirement_groups/company: list company requirement groupsGET /api/v1/requirement_groups/company/:id: get a company requirement groupPOST /api/v1/requirement_groups: create a group (kindmust be"project"or"company")POST /api/v1/requirement_groups/:id/copy: copy a group including all its requirementsPATCH /api/v1/requirement_groups/:id: rename a groupDELETE /api/v1/requirement_groups/:id: archive a groupPOST /api/v1/requirement_groups/:requirement_group_id/requirements/insurance: add an insurance requirement with limitsPOST /api/v1/requirement_groups/:requirement_group_id/requirements/document: add a document requirement (e.g. W-9)POST /api/v1/requirement_groups/:requirement_group_id/requirements/custom_form: link a custom form as a requirementDELETE /api/v1/requirement_groups/:requirement_group_id/requirements/:requirement_id: archive a requirement
Certificates
PATCH /api/v1/certificates/:id/review: mark a COI certificate as reviewed. The approved/rejected status is computed based on whether the certificate's policy details meet the requirement limits.
Custom Forms and Responses
GET /api/v1/custom_forms: list published custom formsDELETE /api/v1/custom_forms/:id: archive a custom formGET /api/v1/custom_form_responses: list responses, filtered bycontract_idorvendor_id(at least one is required)PATCH /api/v1/custom_form_responses/:id/review: record an approved/rejected review decision with optional notes
Bulk operations
All bulk endpoints accept up to 200 items per request and return a results array with one entry per input item. Each item is processed independently, so a failure in one item does not prevent the others from being processed:
{
"results": [
{ "status": "ok", "data": { ... } },
{ "status": "error", "errors": { "field": ["message"] } }
]
}
Requests exceeding 200 items are rejected with 400 Bad Request before any items are processed.
Getting API access
API access is available to Billy customers and technology partners. Technology partners also receive developer training and support, a dedicated Slack channel, a development sandbox, and co-branding opportunities.
Contact us or email support@billyforinsurance.com to get set up with client credentials.

