API Reference
Integrate Plotwise with your systems using our REST API.
The Plotwise API allows you to programmatically access permit data, manage your watchlist, and integrate with your existing systems.
API Overview
Base URL
https://api.plotwise.us/v1
Authentication
All API requests require authentication via API key:
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.plotwise.us/v1/permitsResponse Format
All responses are JSON:
{
"data": { ... },
"meta": {
"page": 1,
"per_page": 25,
"total": 150
}
}Error Format
{
"error": {
"code": "invalid_request",
"message": "Description of what went wrong"
}
}Getting Started
1. Create API Key
- Go to Organization Settings → Developers
- Click "Create API Key"
- Name your key (e.g., "CRM Integration")
- Select permissions
- Copy key (shown only once)
2. Test Connection
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.plotwise.us/v1/meSuccessful response:
{
"data": {
"organization_id": "org_xxx",
"organization_name": "Your Company",
"permissions": ["read", "write"]
}
}Core Endpoints
Permits
List Watchlist Permits
GET /v1/permitsQuery Parameters:
| Parameter | Type | Description |
|---|---|---|
| page | integer | Page number (default: 1) |
| per_page | integer | Results per page (max: 100) |
| status | string | Filter by status |
| updated_since | datetime | Filter by update date |
Example:
curl -H "Authorization: Bearer $API_KEY" \
"https://api.plotwise.us/v1/permits?status=active&per_page=50"Response:
{
"data": [
{
"uuid": "abc-123-def",
"permit_number": "BLD-24-001234",
"status": "In Review",
"type": "Building",
"description": "New commercial building",
"address": "123 Main St, Miami, FL",
"filed_date": "2024-01-15",
"updated_at": "2024-01-20T10:30:00Z"
}
],
"meta": {
"page": 1,
"per_page": 50,
"total": 127
}
}Get Permit Details
GET /v1/permits/{uuid}Response includes:
- Basic permit information
- Current status
- Associated parties
- Status history
- Your notes and tags
Get Permit History
GET /v1/permits/{uuid}/historyReturns status change history for the permit.
Watchlist Management
Add to Watchlist
POST /v1/watchlistRequest Body:
{
"permit_number": "BLD-24-001234",
"jurisdiction": "miami-dade"
}Or by UUID:
{
"permit_uuid": "abc-123-def"
}Remove from Watchlist
DELETE /v1/watchlist/{permit_uuid}Contacts
List Contacts
GET /v1/contactsGet Contact
GET /v1/contacts/{id}Create Contact
POST /v1/contactsRequest Body:
{
"name": "John Smith",
"company": "ABC Contractors",
"email": "john@abc.com",
"phone": "+14155551234",
"type": "contractor"
}Portfolio Conditions
List Conditions
GET /v1/portfolio/conditionsGet Condition Matches
GET /v1/portfolio/conditions/{id}/permitsReturns permits matching the specified condition.
Webhooks
Webhook Events
Configure webhooks to receive real-time notifications:
| Event | Description |
|---|---|
permit.status_changed | Permit status updated |
permit.fee_changed | Fee added or modified |
permit.inspection_scheduled | Inspection date set |
permit.added_to_watchlist | Permit tracking started |
permit.removed_from_watchlist | Permit tracking ended |
Webhook Payload
{
"event": "permit.status_changed",
"timestamp": "2024-01-23T10:45:00Z",
"organization_id": "org_xxx",
"data": {
"permit_uuid": "abc-123",
"permit_number": "BLD-24-001234",
"previous_status": "Pending",
"new_status": "In Review"
}
}Verifying Webhooks
Verify webhook signatures:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return signature === expected;
}Rate Limits
API requests are rate limited by plan:
| Plan | Rate Limit |
|---|---|
| Starter | 100 requests/minute |
| Professional | 1,000 requests/minute |
| Enterprise | Custom |
Rate limit headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1706012345Pagination
List endpoints support pagination:
GET /v1/permits?page=2&per_page=50Response includes pagination metadata:
{
"meta": {
"page": 2,
"per_page": 50,
"total": 150,
"total_pages": 3
}
}Error Codes
| Code | Status | Description |
|---|---|---|
unauthorized | 401 | Invalid or missing API key |
forbidden | 403 | Insufficient permissions |
not_found | 404 | Resource doesn't exist |
rate_limited | 429 | Too many requests |
invalid_request | 400 | Bad request parameters |
server_error | 500 | Internal server error |
SDKs
JavaScript/TypeScript
npm install @plotwise/sdkimport { Plotwise } from '@plotwise/sdk';
const client = new Plotwise({ apiKey: 'YOUR_API_KEY' });
const permits = await client.permits.list({
status: 'active',
perPage: 50
});Python
pip install plotwisefrom plotwise import Plotwise
client = Plotwise(api_key='YOUR_API_KEY')
permits = client.permits.list(
status='active',
per_page=50
)Best Practices
Caching
- Cache permit data locally when possible
- Use
updated_sinceparameter for incremental sync - Respect cache headers in responses
Error Handling
- Implement exponential backoff for retries
- Handle rate limits gracefully
- Log errors for debugging
Security
- Never expose API keys in client-side code
- Rotate keys periodically
- Use minimum required permissions
Full API Documentation
Complete API documentation with interactive examples:
OpenAPI Specification: https://api.plotwise.us/docs
Includes:
- All endpoints with full parameters
- Interactive API explorer
- Code examples in multiple languages
- Schema definitions