← Back to Clio Integration

Clio Developer Documentation

Technical reference for the CaseHug–Clio Manage integration. API endpoints, data models, webhooks, and authentication flow.

Clio API v4OAuth 2.0REST

Authentication Flow

CaseHug uses OAuth 2.0 Authorization Code flow to connect to Clio Manage.

┌──────────┐     ┌──────────┐     ┌──────────┐
│  Browser │     │ CaseHug  │     │   Clio   │
└────┬─────┘     └────┬─────┘     └────┬─────┘
     │                │                │
     │ 1. Click       │                │
     │ "Connect"      │                │
     │───────────────►│                │
     │                │                │
     │ 2. Generate    │                │
     │ CSRF state     │                │
     │                │                │
     │ 3. Redirect    │                │
     │◄───────────────│                │
     │                │                │
     │ 4. Authorize ──────────────────►│
     │                │                │
     │ 5. Redirect with code ◄─────────│
     │───────────────►│                │
     │                │                │
     │                │ 6. Exchange    │
     │                │ code for token │
     │                │───────────────►│
     │                │                │
     │                │ 7. Token       │
     │                │◄───────────────│
     │                │                │
     │                │ 8. Store token │
     │                │ in DB          │
     │                │                │
     │ 9. Redirect to │                │
     │ dashboard      │                │
     │◄───────────────│                │
     │                │                │

Authorize URL: https://app.clio.com/oauth/authorize

Token URL: https://app.clio.com/oauth/token

Redirect URI: https://calmintake.com/api/v1/integrations/clio/callback

Scopes: matters:read matters:write contacts:read contacts:write documents:read documents:write

Token refresh: Automatic, 5 minutes before expiration. Uses refresh_token grant.

API Endpoints

GET/api/v1/integrations/clio/connect

Initiates OAuth flow. Generates CSRF state, stores in DB, redirects to Clio authorize URL.

Auth: Firm AdminResponse: 302 Redirect to Clio
GET/api/v1/integrations/clio/callback

OAuth callback. Validates CSRF state, exchanges authorization code for tokens, stores in firm_integrations, redirects to dashboard.

Auth: None (OAuth flow)Response: 302 Redirect to dashboard
POST/api/v1/integrations/clio/disconnect

Revokes Clio OAuth access, removes tokens from DB, deactivates integration.

Auth: Firm AdminResponse: { "success": true }
GET/api/v1/integrations/clio/status

Returns connection status, Clio user info, last sync time, and sync settings.

Auth: AuthenticatedResponse: { "connected": true, "clio_user": {...}, "last_sync": {...} }
POST/api/v1/integrations/clio/sync

Sync a specific matter to Clio. Body: { "matter_id": "uuid", "action": "sync_matter" | "pull_matters" }

Auth: AuthenticatedResponse: { "success": true, "clioMatterId": 12345, "documentsUploaded": 3 }
GET/api/v1/integrations/clio/sync

Get sync history for the firm (last 50 syncs). Optional query: ?matter_id=uuid

Auth: AuthenticatedResponse: { "logs": [...] }
POST/api/v1/integrations/clio/webhooks

Receives Clio webhook events. Handles X-Hook-Secret handshake and processes matter/contact/document events.

Auth: Clio webhook signatureResponse: { "received": true }
POST/api/v1/integrations/clio/deauthorize

Clio deauthorization callback. Called by Clio when a user revokes access from Clio settings.

Auth: None (Clio callback)Response: { "ok": true }

Data Models

firm_integrations

Stores OAuth tokens and integration settings per firm

ColumnTypeDescription
idUUIDPrimary key
firm_idUUIDReferences firms(id)
platformTEXT'clio' | 'smokeball' | 'mycase' | 'lawmatics'
access_tokenTEXTClio OAuth access token (encrypted at rest)
refresh_tokenTEXTClio OAuth refresh token
token_expires_atTIMESTAMPTZToken expiration time
settingsJSONBIntegration settings (auto_sync, mappings)
webhook_secretTEXTSecret for verifying Clio webhooks
is_activeBOOLEANWhether integration is active
last_sync_atTIMESTAMPTZLast successful sync timestamp
sync_statusTEXT'idle' | 'syncing' | 'error'

integration_sync_logs

Audit log of all sync operations

ColumnTypeDescription
idUUIDPrimary key
firm_idUUIDReferences firms(id)
integration_idUUIDReferences firm_integrations(id)
matter_idUUIDCaseHug matter (nullable)
upload_idUUIDCaseHug upload (nullable)
actionTEXT'sync_matter' | 'sync_document' | 'pull_matters'
statusTEXT'pending' | 'success' | 'failed' | 'skipped'
external_idTEXTClio resource ID
error_messageTEXTError details (nullable)
detailsJSONBAdditional metadata

clio_webhook_events

Raw webhook events from Clio for audit trail

ColumnTypeDescription
idUUIDPrimary key
firm_idUUIDMatched firm (nullable)
event_typeTEXT'matter.update' | 'contact.update' | etc.
resource_typeTEXT'matter' | 'contact' | 'document'
resource_idBIGINTClio resource ID
payloadJSONBRaw webhook payload
processedBOOLEANWhether event has been processed
error_messageTEXTProcessing error (nullable)

Webhook Events

Webhook endpoint: POST https://calmintake.com/api/v1/integrations/clio/webhooks

Registration: Clio sends X-Hook-Secret header on first request. CaseHug echoes it back to confirm.

EventDescriptionCaseHug Action
matter.createNew matter created in ClioLogged; no CaseHug action (Clio-origin matters not auto-imported)
matter.updateMatter updated in ClioIf matter is linked in CaseHug, status is updated (Open→active, Closed→closed)
contact.createNew contact created in ClioLogged for audit
contact.updateContact updated in ClioLogged; future: update linked CaseHug client
document.createDocument uploaded to ClioLogged for audit

Field Mapping Schema

CaseHug maps its case types to Clio practice areas. Default mappings are built-in; firms can override via integration settings.

// firm_integrations.settings schema
{
  "auto_sync_on_approval": true,
  "auto_sync_on_matter_created": false,
  "case_type_mappings": {
    "divorce_standard": "Family Law",
    "custody_only": "Family Law",
    "immigration_asylum": "Immigration",
    "personal_injury_auto": "Personal Injury",
    "estate_planning_will": "Estate Planning"
    // ... override any CaseHug case type → Clio practice area name
  }
}

Sync Data Mapping

CaseHug FieldClio FieldNotes
client.first_namecontact.first_namePerson type contact
client.last_namecontact.last_name
client.emailcontact.email_addresses[0]Name: "Work"
client.phonecontact.phone_numbers[0]Name: "Mobile"
matter.titlematter.description
matter.case_numbermatter.custom_number
matter.case_typematter.practice_areaVia mapping table
upload.filedocument → matterUploaded to Clio matter

Error Codes

CodeMeaningResolution
401Unauthorized — access token expired or revokedCaseHug auto-refreshes tokens. If persistent, disconnect and reconnect Clio.
403Forbidden — insufficient Clio permissionsReconnect Clio with a user that has matters/contacts/documents permissions.
404Resource not found — Clio matter or contact deletedThe linked Clio resource was deleted. Sync again to create a new one.
422Validation error — invalid data sent to ClioCheck sync log details for the specific validation error from Clio.
429Rate limited — too many API requestsCaseHug implements exponential backoff. Wait a few minutes and retry.
500/503Clio server error or maintenanceRetry after Clio resolves the issue. Check status.clio.com.

Rate Limits

Clio enforces rate limits via HTTP headers. CaseHug respects these automatically.

Headers: X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After

Strategy: Sequential sync per matter. One matter at a time. Document uploads are serialized.

Backoff: On 429 response, CaseHug waits the Retry-After duration, then retries up to 3 times.

Pagination: List endpoints use limit=200 (Clio max per page) with offset-based pagination.

Need Technical Help?

Reach out to our engineering team for integration support.