Agreements API
Agreements represent recurring retainer contracts with clients. They define monthly hour allowances, rates, and billing terms. Each agreement has periods (typically monthly) that track usage and rollover.
The Agreement Object
{
"id": "agr_cuid123456",
"client_id": "cli_xxxxx",
"type_id": "agrtype_xxxxx",
"title": "Monthly Support Retainer",
"status": "active",
"billing": {
"monthly_fee": 5000.00,
"hours_included": 40,
"overage_rate": 150.00,
"billing_day": 1
},
"rollover": {
"enabled": true,
"max_hours": 20,
"expires_months": 3
},
"dates": {
"start_date": "2026-01-01",
"end_date": null,
"next_renewal": "2027-01-01"
},
"contact_id": "con_xxxxx",
"auto_invoice": true,
"invoice_method": "create_draft",
"current_period": {
"id": "per_xxxxx",
"start_date": "2026-01-01",
"end_date": "2026-01-31",
"hours_included": 40,
"hours_used": 28.5,
"hours_remaining": 11.5,
"rollover_hours": 0
},
"notes": "Premium support package with 24/7 coverage",
"created_at": "2025-12-15T10:00:00Z",
"updated_at": "2026-01-20T14:30:00Z"
}Agreement Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (prefix: agr_) |
client_id | string | Required. Associated client |
type_id | string | Agreement type category |
title | string | Required. Agreement name |
status | enum | Agreement status |
billing | object | Billing configuration |
rollover | object | Rollover settings |
dates | object | Contract dates |
contact_id | string | Primary contact |
auto_invoice | boolean | Generate invoices automatically |
invoice_method | enum | create_draft or auto_send |
current_period | object | Current period details |
notes | string | Internal notes |
created_at | datetime | When created |
updated_at | datetime | When last updated |
Agreement Status
| Status | Description |
|---|---|
draft | Not yet active |
active | Currently in effect |
paused | Temporarily suspended |
expired | Past end date |
cancelled | Terminated early |
Billing Object
| Field | Type | Description |
|---|---|---|
monthly_fee | decimal | Monthly retainer fee |
hours_included | decimal | Hours included per month |
overage_rate | decimal | Rate for hours beyond allowance |
billing_day | integer | Day of month to generate invoice (1-28) |
Rollover Object
| Field | Type | Description |
|---|---|---|
enabled | boolean | Allow unused hours to roll over |
max_hours | decimal | Maximum rollover hours (cap) |
expires_months | integer | Months until rollover expires |
List Agreements
/v1/agreementsList all agreementsReturns a paginated list of agreements.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
per_page | integer | 20 | Results per page (max: 100) |
client_id | string | Filter by client | |
status | string | Filter by status | |
type_id | string | Filter by agreement type | |
expiring_soon | boolean | Agreements expiring within 30 days | |
sort | string | created_at | Sort by: created_at, start_date, monthly_fee |
order | string | desc | Sort order: asc, desc |
Request
curl "https://api.govantage.co/v1/agreements?status=active&client_id=cli_xxxxx" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Response
{
"data": [
{
"id": "agr_cuid123456",
"client_id": "cli_xxxxx",
"client_name": "Acme Corporation",
"title": "Monthly Support Retainer",
"status": "active",
"billing": {
"monthly_fee": 5000.00,
"hours_included": 40
},
"current_period": {
"hours_used": 28.5,
"hours_remaining": 11.5,
"percent_used": 71.25
},
"dates": {
"start_date": "2026-01-01"
}
}
],
"pagination": {
"page": 1,
"per_page": 20,
"total": 45,
"total_pages": 3
},
"summary": {
"total_mrr": 125000.00,
"active_agreements": 42,
"expiring_soon": 3
}
}Create an Agreement
/v1/agreementsCreate a new agreementRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
client_id | string | Yes | Client ID |
title | string | Yes | Agreement name |
type_id | string | No | Agreement type ID |
start_date | date | Yes | Contract start date |
end_date | date | No | Contract end date (null = ongoing) |
monthly_fee | decimal | Yes | Monthly fee |
hours_included | decimal | Yes | Hours included per month |
overage_rate | decimal | No | Overage hourly rate |
billing_day | integer | No | Day of month for invoicing (default: 1) |
rollover_enabled | boolean | No | Enable hour rollover |
rollover_max_hours | decimal | No | Maximum rollover cap |
rollover_expires_months | integer | No | Months until rollover expires |
contact_id | string | No | Primary contact |
auto_invoice | boolean | No | Auto-generate invoices |
invoice_method | string | No | create_draft or auto_send |
notes | string | No | Internal notes |
Request
curl -X POST "https://api.govantage.co/v1/agreements" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"client_id": "cli_xxxxx",
"title": "Monthly Support Retainer",
"start_date": "2026-02-01",
"monthly_fee": 5000,
"hours_included": 40,
"overage_rate": 150,
"rollover_enabled": true,
"rollover_max_hours": 20,
"auto_invoice": true,
"invoice_method": "create_draft"
}'Response
{
"data": {
"id": "agr_cuid789012",
"client_id": "cli_xxxxx",
"title": "Monthly Support Retainer",
"status": "active",
"billing": {
"monthly_fee": 5000.00,
"hours_included": 40,
"overage_rate": 150.00,
"billing_day": 1
},
"rollover": {
"enabled": true,
"max_hours": 20,
"expires_months": null
},
"dates": {
"start_date": "2026-02-01",
"end_date": null
},
"current_period": {
"id": "per_xxxxx",
"start_date": "2026-02-01",
"end_date": "2026-02-28",
"hours_included": 40,
"hours_used": 0,
"hours_remaining": 40
},
"created_at": "2026-01-25T10:30:00Z"
}
}When an agreement is created, the first period is automatically generated based on the start date.
Get an Agreement
/v1/agreements/:idRetrieve an agreement by IDQuery Parameters
| Parameter | Type | Description |
|---|---|---|
include | string | Comma-separated: client, periods, time_entries, invoices |
Request
curl "https://api.govantage.co/v1/agreements/agr_cuid123456?include=periods" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Update an Agreement
/v1/agreements/:idUpdate an agreementChanges to monthly_fee, hours_included, or overage_rate take effect from the next period. Current period values are preserved.
Request
curl -X PUT "https://api.govantage.co/v1/agreements/agr_cuid123456" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"monthly_fee": 6000,
"hours_included": 50,
"notes": "Upgraded package starting February"
}'Cancel an Agreement
/v1/agreements/:id/cancelCancel an agreementcurl -X POST "https://api.govantage.co/v1/agreements/agr_cuid123456/cancel" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"effective_date": "2026-01-31",
"reason": "Client ended services"
}'Agreement Periods
Periods represent billing cycles within an agreement (typically monthly).
The Period Object
{
"id": "per_cuid123456",
"agreement_id": "agr_xxxxx",
"start_date": "2026-01-01",
"end_date": "2026-01-31",
"status": "active",
"hours": {
"included": 40,
"rollover_in": 5,
"total_available": 45,
"used": 28.5,
"remaining": 16.5,
"overage": 0
},
"billing": {
"base_fee": 5000.00,
"overage_amount": 0,
"total": 5000.00
},
"invoice_id": null,
"closed_at": null
}List Periods
/v1/agreements/:id/periodsList agreement periodscurl "https://api.govantage.co/v1/agreements/agr_cuid123456/periods?limit=12" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Response
{
"data": [
{
"id": "per_jan2026",
"start_date": "2026-01-01",
"end_date": "2026-01-31",
"status": "active",
"hours": {
"total_available": 45,
"used": 28.5,
"remaining": 16.5
}
},
{
"id": "per_dec2025",
"start_date": "2025-12-01",
"end_date": "2025-12-31",
"status": "closed",
"hours": {
"total_available": 40,
"used": 35,
"remaining": 0,
"rolled_over": 5
},
"invoice_id": "inv_xxxxx"
}
]
}Get Period Details
/v1/agreements/:id/periods/:periodIdGet period detailscurl "https://api.govantage.co/v1/agreements/agr_cuid123456/periods/per_jan2026?include=time_entries" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Close Period Manually
/v1/agreements/:id/periods/:periodId/closeClose a period earlyPeriods are normally closed automatically by a daily cron job. Use this to close early.
curl -X POST "https://api.govantage.co/v1/agreements/agr_cuid123456/periods/per_jan2026/close" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"generate_invoice": true
}'Retainer Usage
Log Time Against Retainer
Time entries can be logged directly against an agreement:
curl -X POST "https://api.govantage.co/v1/time-entries" \
-H "Authorization: Bearer vnt_sk_live_xxxxx" \
-H "Content-Type: application/json" \
-d '{
"user_id": "usr_xxxxx",
"date": "2026-01-25",
"hours": 2.5,
"description": "Monthly maintenance tasks",
"agreement_id": "agr_cuid123456",
"client_id": "cli_xxxxx"
}'When you log time against an agreement, it automatically draws from the current period’s hour allowance. Overage is calculated when hours exceed the allowance.
Check Retainer Balance
/v1/agreements/:id/balanceGet current balancecurl "https://api.govantage.co/v1/agreements/agr_cuid123456/balance" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Response
{
"data": {
"period": {
"start_date": "2026-01-01",
"end_date": "2026-01-31",
"days_remaining": 6
},
"hours": {
"included": 40,
"rollover": 5,
"total_available": 45,
"used": 28.5,
"remaining": 16.5,
"overage": 0,
"burn_rate_daily": 1.4
},
"projection": {
"estimated_end_usage": 36.9,
"estimated_remaining": 8.1,
"will_have_overage": false
},
"value": {
"monthly_fee": 5000.00,
"hours_value": 4275.00,
"remaining_value": 2475.00
}
}
}Drawdown Report
/v1/agreements/drawdownRetainer drawdown summaryGet a summary of all active retainers and their current status.
curl "https://api.govantage.co/v1/agreements/drawdown" \
-H "Authorization: Bearer vnt_sk_live_xxxxx"Response
{
"data": [
{
"agreement_id": "agr_xxxxx",
"client_name": "Acme Corporation",
"title": "Monthly Support Retainer",
"period_end_date": "2026-01-31",
"hours_available": 45,
"hours_used": 28.5,
"percent_used": 63.3,
"status": "on_track"
},
{
"agreement_id": "agr_yyyyy",
"client_name": "Beta Industries",
"title": "Development Retainer",
"period_end_date": "2026-01-31",
"hours_available": 80,
"hours_used": 78,
"percent_used": 97.5,
"status": "near_limit"
}
],
"summary": {
"total_mrr": 125000.00,
"total_hours_available": 850,
"total_hours_used": 625,
"utilization_percent": 73.5
}
}Drawdown Status
| Status | Description |
|---|---|
on_track | Usage is healthy |
under_utilized | Less than 50% used with <25% time remaining |
near_limit | 90%+ used |
over_limit | In overage |
Agreement Types
List Agreement Types
/v1/agreement-typesList agreement types{
"data": [
{ "id": "agrtype_support", "name": "Support Retainer", "default_hours": 40 },
{ "id": "agrtype_dev", "name": "Development Retainer", "default_hours": 80 },
{ "id": "agrtype_hosting", "name": "Hosting & Maintenance", "default_hours": 10 }
]
}Webhooks
Subscribe to agreement events:
| Event | Description |
|---|---|
agreement.created | New agreement created |
agreement.updated | Agreement details changed |
agreement.cancelled | Agreement cancelled |
agreement.period_closed | Period closed |
agreement.near_limit | 90% of hours used |
agreement.over_limit | Hours exceeded allowance |
agreement.expiring_soon | Agreement expiring within 30 days |
Next Steps
- Time Entries API - Log retainer time
- Invoices API - Retainer invoicing
- Clients API - Client management