API Reference
OpenCLM exposes a REST API that lets you integrate contract data with your ERP, CRM, or custom tools.
Base URL
https://openclm.yourdomain.com/api
Authentication
All API endpoints require a Bearer token. Obtain a token by:
Option A — API Key (Recommended for integrations)
Create an API key in Settings → API Keys. Use it in the Authorization header:
Authorization: Bearer your-api-key-here
Option B — JWT (User session token)
If you are calling the API from a browser session, the user's JWT from Keycloak is used automatically. For server-to-server calls, use an API key instead.
Contracts
List Contracts
GET /api/contracts
Query parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: draft, under_review, approved, signed, active, expired, terminated |
type | string | Filter by contract type |
owner | string | Filter by owner user ID |
search | string | Full-text search on title and counterparty |
page | integer | Page number (default: 1) |
limit | integer | Results per page (default: 20, max: 100) |
Response:
{
"data": [
{
"id": "ctr_abc123",
"title": "NDA with Acme Corp",
"type": "nda",
"status": "active",
"counterparty": "Acme Corp",
"value": 50000,
"currency": "USD",
"effectiveDate": "2024-01-01",
"expiryDate": "2025-01-01",
"owner": {
"id": "usr_xyz789",
"name": "Jane Smith",
},
"createdAt": "2023-12-15T10:30:00Z",
"updatedAt": "2024-01-02T09:15:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 142,
"totalPages": 8
}
}
Get a Contract
GET /api/contracts/:id
Returns the full contract object including the document body, version history summary, and current workflow state.
Create a Contract
POST /api/contracts
Request body:
{
"title": "Vendor Agreement — TechCorp",
"type": "vendor",
"counterparty": "TechCorp Ltd",
"value": 120000,
"currency": "USD",
"effectiveDate": "2025-01-01",
"expiryDate": "2026-01-01",
"templateId": "tpl_abc123",
"body": "<p>Contract body HTML...</p>"
}
Response: 201 Created with the new contract object.
Update a Contract
PATCH /api/contracts/:id
Send only the fields you want to update.
Delete a Contract
DELETE /api/contracts/:id
Requires contracts:delete permission (Super Admin only).
Clauses
List Clauses
GET /api/clauses?category=liability&search=cap
Get a Clause
GET /api/clauses/:id
Approvals
Submit a Contract for Approval
POST /api/contracts/:id/submit
Triggers the configured approval workflow for the contract.
Get Approval Status
GET /api/contracts/:id/approvals
Returns the current workflow state and each approver's status.
Approve a Contract Step
POST /api/contracts/:id/approvals/:stepId/approve
Request body:
{
"comment": "Approved — terms are acceptable."
}
Webhooks
See Integrations — Webhooks for the webhook payload format.
Rate Limits
| Plan | Rate limit |
|---|---|
| Default | 100 requests / minute per API key |
| Burst | Up to 200 requests in a 10-second window |
Rate limit headers are included in every response:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1712345678
Error Responses
All errors follow the same format:
{
"error": {
"code": "CONTRACT_NOT_FOUND",
"message": "No contract with ID ctr_xyz999 exists in this organisation.",
"statusCode": 404
}
}
Common error codes:
| Code | HTTP Status | Meaning |
|---|---|---|
UNAUTHORISED | 401 | Missing or invalid API token |
FORBIDDEN | 403 | Your role does not permit this action |
CONTRACT_NOT_FOUND | 404 | Contract does not exist |
VALIDATION_ERROR | 422 | Request body failed validation |
RATE_LIMIT_EXCEEDED | 429 | Too many requests |
INTERNAL_ERROR | 500 | Server error — check logs |