Public API v1
Build custom integrations with OAuth 2.0, REST endpoints, webhooks, and rate limits
On this page
Overview
The BlueClerk Public API v1 lets builders, contractors, and integrators build custom apps, sync data, and automate workflows. Authenticate via OAuth 2.0 with PKCE, access 13 REST endpoints for leads, tickets, jobs, properties, estimates, invoices, contacts, and more, and receive real-time webhook notifications when records change. Available on paid plans with per-tier rate limits.
NEW: Contact Sync Endpoint - The API now includes a POST /api/v1/contacts endpoint that lets you create or update customer contacts programmatically. When you send contact data with a matching email address, the system automatically updates the existing contact instead of creating a duplicate. This is perfect for syncing customer databases from Apollo or other CRM systems.
NEW: FREE tier restrictions - The FREE tier is now excluded from API access. Users must upgrade to STARTER or higher to use the Public API. FREE tier tokens will be rejected with 403 errors, and rate limits are set to 0 for all FREE accounts.
Authentication
OAuth 2.0 Authorization Code Flow with PKCE
The API uses OAuth 2.0 for secure authentication:
- Register your client - Contact the BlueClerk partners team or use the CLI tool to get a client ID and secret
- Redirect users to
/oauth/authorizewith your client ID, redirect URI, and PKCE code challenge - User authorizes your app
- Receive authorization code at your redirect URI
- Exchange code for access token by POSTing to
/oauth/tokenwith the code and PKCE verifier - Use access token to make authenticated API requests
Available Endpoints
Leads
GET /api/v1/leads- List all leads with pagination and filteringPOST /api/v1/leads- Create a new lead
Tickets
GET /api/v1/tickets- List all tickets with filtering by statusGET /api/v1/tickets/:id- Get a single ticket by IDPOST /api/v1/tickets- Create a new ticket
Jobs
GET /api/v1/jobs- List all jobs with filtering by status and dateGET /api/v1/jobs/:id- Get a single job by ID
Properties
GET /api/v1/properties- List all propertiesGET /api/v1/properties/:id- Get a single property with full details
Estimates
GET /api/v1/estimates- List all estimatesGET /api/v1/estimates/:id- Get a single estimate with line items
Invoices
GET /api/v1/invoices- List all invoicesGET /api/v1/invoices/:id- Get a single invoice with line items and payments
Contacts
POST /api/v1/contacts- Create or update customer contacts
Contact Sync Endpoint
Creating or Updating Contacts
The contacts endpoint automatically handles create vs. update logic based on email address:
Endpoint: POST /api/v1/contacts
Request Body:
{
"email": "john@example.com",
"firstName": "John",
"lastName": "Smith",
"phone": "512-555-1234",
"title": "Owner",
"companyName": "Smith Plumbing",
"address": "123 Main St",
"city": "Austin",
"state": "TX",
"zip": "78701"
}
Required Fields:
email- Used to match existing contacts
Optional Fields:
firstName,lastName- Contact namephone- Contact phone numbertitle- Job title (e.g., "Owner", "Manager")companyName- Company name for business contactsaddress,city,state,zip- Contact address
Response:
{
"id": "cm4abc123",
"email": "john@example.com",
"firstName": "John",
"lastName": "Smith",
"phone": "512-555-1234",
"isNew": false
}
The isNew field indicates whether a new contact was created (true) or an existing contact was updated (false).
Automatic Deduplication
When you POST to /api/v1/contacts:
- Email lookup - The system searches for an existing contact with that email address in your company
- Update existing - If found, the contact is updated with any new fields you provide
- Create new - If not found, a new contact is created with the provided data
- Return contact ID - The response always includes the contact ID (existing or new)
This ensures you never create duplicate contacts when syncing data from external systems.
Rate Limits
Rate limits are enforced per OAuth client per tier:
- FREE: 0 requests/minute (API access disabled)
- STARTER: 60 requests/minute
- PRO: 300 requests/minute
- ENTERPRISE: 1000 requests/minute
When you exceed your rate limit, you'll receive a 429 Too Many Requests response with a Retry-After header indicating when you can try again.
Webhooks
Subscribing to Events
Register webhook URLs to receive real-time notifications when records change:
lead.createdticket.created,ticket.updatedjob.created,job.updated,job.completedinvoice.created,invoice.sent,invoice.paidestimate.created,estimate.sent,estimate.approved
Webhook Payload
All webhooks include:
{
"event": "ticket.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"id": "cm4abc123",
...
}
}
Webhook Security
Webhooks include an X-Webhook-Signature header with an HMAC-SHA256 signature of the payload. Verify this signature using your client secret to ensure webhooks are authentic.
Error Handling
The API returns standard HTTP status codes:
200 OK- Request succeeded201 Created- Resource created successfully400 Bad Request- Invalid request parameters401 Unauthorized- Invalid or missing access token403 Forbidden- Insufficient permissions or FREE tier restriction404 Not Found- Resource doesn't exist429 Too Many Requests- Rate limit exceeded500 Internal Server Error- Server error
Error responses include a JSON body with details:
{
"error": "Invalid request",
"message": "Missing required field: email"
}
Getting Started
- Contact BlueClerk to register your OAuth client
- Implement OAuth flow in your application
- Test with sandbox data using your development credentials
- Go live with production credentials
For detailed API documentation and code examples, visit the Developer Portal or contact the BlueClerk partners team.