# Kickserv API

> Every Kickserv endpoint on Cotlet: inputs, JSON Schema, cURL, Python and Node.js examples and an example response for each call.

Source: https://cotlet.dev/docs/api/kickserv

Docs sections: [Get started](https://cotlet.dev/docs.md) · [REST API](https://cotlet.dev/docs/api.md) · [MCP](https://cotlet.dev/docs/mcp.md) · [SDKs & CLI](https://cotlet.dev/docs/sdks.md) · [Integrations](https://cotlet.dev/docs/integrations.md)

15 endpoints for Kickserv. Each one is a POST with a JSON body, called with your API key.

- Base URL: `https://cotlet.dev/api/v1/kickserv`
- Connects with: Your own Kickserv account (admin role for invoices and payments)
- Integration page: https://cotlet.dev/integrations/kickserv-api-mcp-server

## Endpoints

| Endpoint | Access | Description |
|---|---|---|
| `list_customers` | read | Customers and contacts, searchable by name, email, phone or address. |
| `get_customer` | read | One customer with addresses, contacts, notes and jobs. |
| `list_jobs` | read | Jobs with status, service type, customer, assigned techs and scheduled date. |
| `get_job` | read | Full job: description, scope of work, charges, schedule events, time entries, notes and invoice status. |
| `list_opportunities` | read | Opportunities with customer, service type and whether an estimate was sent. |
| `list_invoices` | read | Invoices with customer, total, balance and whether they were sent and viewed. |
| `create_customer` | write | New person or company contact with service and billing address. |
| `create_job` | write | New job, or a new opportunity to estimate first, for a customer. |
| `add_charge` | write | Add one charge item to the estimate or invoice of a job or opportunity. |
| `schedule_event` | write | Add a work event to a job, optionally assigned to a technician. |
| `log_time_entry` | write | Record hours worked on a job by an employee. |
| `send_estimate` | write | Email the estimate of an opportunity to the customer. |
| `generate_invoice` | write | Create the invoice for a job from its charges. Nothing is sent. |
| `send_invoice` | write | Email the invoice of a job to the customer. |
| `record_payment` | write | Log a manual payment (check, cash, other) on a job and mark the invoice paid. No card is charged. |

## List customers

`POST https://cotlet.dev/api/v1/kickserv/list_customers`

Access: read.

Returns customers with their number, contact details and service address. Search matches name, email, phone and street address. Pass the customer_number to get_customer, create_job and the other tools.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `query` | string | no | Name, email, phone or street address. |
| `page` | integer | no | Page number. Default: 1. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/list_customers \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("kickserv", "list_customers")
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'list_customers');
```

**CLI**

```bash
cotlet call kickserv list_customers
```

### Example response

```json
{
  "customers": [
    {
      "customer_number": "2218",
      "name": "Lee Residence",
      "email": "lee@example.com",
      "phone": "555-0142",
      "service_address": "41 Maple St, Austin, TX 78701"
    }
  ],
  "page": 1
}
```

## Get customer

`POST https://cotlet.dev/api/v1/kickserv/get_customer`

Access: read.

Returns one customer with service and billing addresses, saved contacts, special instructions, notes and the list of their jobs with status. Use it before creating a job so your agent reuses the right contact.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `customer_number` | string | yes | Customer number from list_customers. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/get_customer \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customer_number":"customer number"}'
```

**Python**

```python
result = client.call("kickserv", "get_customer", {"customer_number":"customer number"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'get_customer', {"customer_number":"customer number"});
```

**CLI**

```bash
cotlet call kickserv get_customer --data '{"customer_number":"customer number"}'
```

### Example response

```json
{
  "customer_number": "2218",
  "name": "Lee Residence",
  "billing_address": "41 Maple St, Austin, TX 78701",
  "contacts": [
    {
      "name": "Mrs. Lee",
      "email": "lee@example.com",
      "primary": true
    }
  ],
  "jobs": [
    {
      "job_number": "1037",
      "service_type": "Water heater replacement",
      "status": "complete"
    }
  ]
}
```

## List jobs

`POST https://cotlet.dev/api/v1/kickserv/list_jobs`

Access: read.

Returns jobs 30 per page, filtered by status, scheduled date or technician. Use job_number in get_job and the write tools.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `status` | enum | no | unscheduled, scheduled, in_progress, on_hold, canceled or complete. |
| `scheduled` | enum | no | today, tomorrow, yesterday, this_week, next_week, last_week, this_month, next_month, last_month, this_year or last_year. |
| `employee` | string | no | Only jobs assigned to this employee. |
| `page` | integer | no | Page number. Default: 1. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/list_jobs \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"complete","scheduled":"yesterday","page":1}'
```

**Python**

```python
result = client.call("kickserv", "list_jobs", {"status":"complete","scheduled":"yesterday","page":1})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'list_jobs', {"status":"complete","scheduled":"yesterday","page":1});
```

**CLI**

```bash
cotlet call kickserv list_jobs --data '{"status":"complete","scheduled":"yesterday","page":1}'
```

### Example response

```json
{
  "jobs": [
    {
      "job_number": "1037",
      "service_type": "Water heater replacement",
      "customer": "Lee Residence",
      "status": "complete",
      "scheduled_on": "2026-10-09",
      "employees": [
        "Dana Ruiz"
      ]
    }
  ],
  "page": 1
}
```

## Get job

`POST https://cotlet.dev/api/v1/kickserv/get_job`

Access: read.

Returns one job or opportunity with its internal description, the customer-facing scope of work, charges with the running total, schedule events, time entries, notes and whether an invoice exists and is paid.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/get_job \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"job number"}'
```

**Python**

```python
result = client.call("kickserv", "get_job", {"job_number":"job number"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'get_job', {"job_number":"job number"});
```

**CLI**

```bash
cotlet call kickserv get_job --data '{"job_number":"job number"}'
```

### Example response

```json
{
  "job_number": "1042",
  "service_type": "Water heater replacement",
  "customer": "Lee Residence",
  "status": "new",
  "description": "Website lead: 40 gal tank leaking",
  "scope_of_work": "Replace the 40 gallon gas water heater.",
  "charges": [],
  "total": "0.00",
  "events": [],
  "time_entries": [],
  "invoice": null
}
```

## List opportunities

`POST https://cotlet.dev/api/v1/kickserv/list_opportunities`

Access: read.

Returns opportunities from the Opportunities page. A new opportunity appears under the New tab; in the app an opportunity can be marked won or lost.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `stage` | enum | no | new, won or lost. Default: new. |
| `page` | integer | no | Page number. Default: 1. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/list_opportunities \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("kickserv", "list_opportunities")
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'list_opportunities');
```

**CLI**

```bash
cotlet call kickserv list_opportunities
```

### Example response

```json
{
  "opportunities": [
    {
      "job_number": "1042",
      "service_type": "Water heater replacement",
      "customer": "Lee Residence",
      "stage": "new",
      "estimate_sent": false,
      "created_on": "2026-10-10"
    }
  ],
  "page": 1
}
```

## List invoices

`POST https://cotlet.dev/api/v1/kickserv/list_invoices`

Access: read.

Returns the invoices shown on the Invoices page, from its unpaid or paid tab. Each has a sent flag and a viewed flag, the same as the blue letter and purple eye icons in the app.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `tab` | enum | no | unpaid or paid. Default: unpaid. |
| `page` | integer | no | Page number. Default: 1. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/list_invoices \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("kickserv", "list_invoices")
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'list_invoices');
```

**CLI**

```bash
cotlet call kickserv list_invoices
```

### Example response

```json
{
  "invoices": [
    {
      "job_number": "1037",
      "customer": "Lee Residence",
      "total": "480.00",
      "balance_remaining": "480.00",
      "sent": true,
      "viewed": true
    }
  ],
  "page": 1
}
```

## Create customer

`POST https://cotlet.dev/api/v1/kickserv/create_customer`

Access: write.

Creates a customer and returns its customer_number. It sends nothing to the customer and one edit in Kickserv undoes it, so it runs without asking first. Search with list_customers before creating one, to avoid duplicates.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes | Person or company name. |
| `is_company` | boolean | no | Company instead of a person. Default: false. |
| `email` | string | no | Customer email. |
| `phone` | string | no | Phone number. |
| `service_address` | object | no | street, city, state, zip_code, country. |
| `billing_address` | object | no | Same fields. Default: the service address. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/create_customer \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Jane Doe"}'
```

**Python**

```python
result = client.call("kickserv", "create_customer", {"name":"Jane Doe"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'create_customer', {"name":"Jane Doe"});
```

**CLI**

```bash
cotlet call kickserv create_customer --data '{"name":"Jane Doe"}'
```

### Example response

```json
{
  "customer_number": "2219",
  "name": "Rivera Dental",
  "status": "created"
}
```

## Create job

`POST https://cotlet.dev/api/v1/kickserv/create_job`

Access: write.

Creates a job for a customer and returns its job_number. With as_opportunity set to true it creates an opportunity under the New tab instead. The description is internal and the scope of work is shown to the customer. It sends nothing to the customer, so it runs without asking first.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `customer_number` | string | yes | Customer number from list_customers. |
| `service_type` | string | yes | Service type as named in your account. |
| `description` | string | no | Internal description, not shown to the customer. |
| `scope_of_work` | string | no | Customer-facing scope of work. |
| `as_opportunity` | boolean | no | Create an opportunity for an estimate instead of a job. Default: false. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/create_job \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customer_number":"2231","service_type":"Water heater replacement","description":"Lead from website form, 11:40 p.m.: 40 gal tank leaking in garage","scope_of_work":"Inspect and replace the 40 gallon gas water heater.","as_opportunity":true}'
```

**Python**

```python
result = client.call("kickserv", "create_job", {"customer_number":"2231","service_type":"Water heater replacement","description":"Lead from website form, 11:40 p.m.: 40 gal tank leaking in garage","scope_of_work":"Inspect and replace the 40 gallon gas water heater.","as_opportunity":True})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'create_job', {"customer_number":"2231","service_type":"Water heater replacement","description":"Lead from website form, 11:40 p.m.: 40 gal tank leaking in garage","scope_of_work":"Inspect and replace the 40 gallon gas water heater.","as_opportunity":true});
```

**CLI**

```bash
cotlet call kickserv create_job --data '{"customer_number":"2231","service_type":"Water heater replacement","description":"Lead from website form, 11:40 p.m.: 40 gal tank leaking in garage","scope_of_work":"Inspect and replace the 40 gallon gas water heater.","as_opportunity":true}'
```

### Example response

```json
{
  "job_number": "1051",
  "type": "opportunity",
  "stage": "new",
  "customer_number": "2218",
  "service_type": "Water heater replacement"
}
```

## Add charge

`POST https://cotlet.dev/api/v1/kickserv/add_charge`

Access: write.

Adds one charge line and returns the running total of the job. Call it once per line. Nothing reaches the customer until you send the estimate or invoice, so it runs without asking first.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |
| `item` | string | yes | Charge item from your account, or a new item name. |
| `description` | string | no | Line description. |
| `quantity` | string | no | Decimal, e.g. 1 or 2.5. Default: 1. |
| `price_per_unit` | string | no | Price as a decimal, e.g. 129.00. |
| `taxable` | boolean | no | Apply sales tax. Default: the item setting. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/add_charge \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"1042","item":"Labor","description":"Remove old tank, install and test new heater","quantity":"3","price_per_unit":"95.00","taxable":false}'
```

**Python**

```python
result = client.call("kickserv", "add_charge", {"job_number":"1042","item":"Labor","description":"Remove old tank, install and test new heater","quantity":"3","price_per_unit":"95.00","taxable":False})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'add_charge', {"job_number":"1042","item":"Labor","description":"Remove old tank, install and test new heater","quantity":"3","price_per_unit":"95.00","taxable":false});
```

**CLI**

```bash
cotlet call kickserv add_charge --data '{"job_number":"1042","item":"Labor","description":"Remove old tank, install and test new heater","quantity":"3","price_per_unit":"95.00","taxable":false}'
```

### Example response

```json
{
  "job_number": "1042",
  "charge": {
    "item": "Labor",
    "quantity": "2.5",
    "price_per_unit": "95.00",
    "line_total": "237.50"
  },
  "total": "886.50"
}
```

## Schedule event

`POST https://cotlet.dev/api/v1/kickserv/schedule_event`

Access: write. Confirm: waits for the user's OK before it runs.

Adds an event with a start time, an optional end, a task type and an optional technician. Without a technician the event stays unassigned. Depending on your reminder settings, Kickserv can send reminders for the event. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |
| `starts_at` | datetime | yes | ISO 8601 with time zone. |
| `ends_at` | datetime | no | End of the event. |
| `task_type` | string | no | Task type as named in your account, e.g. Work. Default: Work. |
| `employee` | string | no | Technician to assign. Default: unassigned. |
| `description` | string | no | Notes for the technician. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/schedule_event \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"job number","starts_at":"2026-10-01T09:00:00Z"}'
```

**Python**

```python
result = client.call("kickserv", "schedule_event", {"job_number":"job number","starts_at":"2026-10-01T09:00:00Z"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'schedule_event', {"job_number":"job number","starts_at":"2026-10-01T09:00:00Z"});
```

**CLI**

```bash
cotlet call kickserv schedule_event --data '{"job_number":"job number","starts_at":"2026-10-01T09:00:00Z"}'
```

### Example response

```json
{
  "job_number": "1050",
  "event_id": "ev_3381",
  "task_type": "Work",
  "starts_at": "2026-10-15T09:00:00-05:00",
  "employee": "Dana Ruiz",
  "job_status": "scheduled"
}
```

## Log time entry

`POST https://cotlet.dev/api/v1/kickserv/log_time_entry`

Access: write.

Adds a time entry to the job and returns it. Hours are a decimal. It reaches no one and an admin can delete the entry in Kickserv, so it runs without asking first.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |
| `hours` | string | yes | Number of hours as a decimal, e.g. 2.5. |
| `date` | date | yes | Day the work was done. |
| `employee` | string | yes | Employee name. |
| `billable` | boolean | no | Billable time. Default: true. |
| `note` | string | no | What was done. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/log_time_entry \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"job number","hours":"hours","date":"2026-10-01","employee":"employee"}'
```

**Python**

```python
result = client.call("kickserv", "log_time_entry", {"job_number":"job number","hours":"hours","date":"2026-10-01","employee":"employee"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'log_time_entry', {"job_number":"job number","hours":"hours","date":"2026-10-01","employee":"employee"});
```

**CLI**

```bash
cotlet call kickserv log_time_entry --data '{"job_number":"job number","hours":"hours","date":"2026-10-01","employee":"employee"}'
```

### Example response

```json
{
  "job_number": "1049",
  "time_entry_id": "te_7702",
  "employee": "Dana Ruiz",
  "date": "2026-10-09",
  "hours": "2.5",
  "billable": true,
  "note": "Installed water heater"
}
```

## Send estimate

`POST https://cotlet.dev/api/v1/kickserv/send_estimate`

Access: write. Confirm: waits for the user's OK before it runs.

Emails the estimate to the main customer of the job and copies the addresses you add. Subject and message come from your Messaging Templates unless you set them. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |
| `to` | string[] | no | Recipient emails. Default: the main customer of the job. |
| `cc` | string[] | no | Extra emails to copy. |
| `subject` | string | no | Email subject. Default: your Messaging Templates subject. |
| `message` | string | no | Custom message. Default: your Messaging Templates message. |
| `attach_pdf` | boolean | no | Also attach a PDF copy. Default: your Messaging Templates setting. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/send_estimate \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"job number"}'
```

**Python**

```python
result = client.call("kickserv", "send_estimate", {"job_number":"job number"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'send_estimate', {"job_number":"job number"});
```

**CLI**

```bash
cotlet call kickserv send_estimate --data '{"job_number":"job number"}'
```

### Example response

```json
{
  "job_number": "1042",
  "status": "sent",
  "sent_to": [
    "lee@example.com"
  ],
  "cc": [
    "office@example.com"
  ],
  "total": "886.50"
}
```

## Generate invoice

`POST https://cotlet.dev/api/v1/kickserv/generate_invoice`

Access: write.

Creates the invoice from the charges on the job, the same as Generate Invoice in the job header, and returns its total. It sends nothing to the customer and the invoice can be edited afterwards, so it runs without asking first.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/generate_invoice \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"job number"}'
```

**Python**

```python
result = client.call("kickserv", "generate_invoice", {"job_number":"job number"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'generate_invoice', {"job_number":"job number"});
```

**CLI**

```bash
cotlet call kickserv generate_invoice --data '{"job_number":"job number"}'
```

### Example response

```json
{
  "job_number": "1037",
  "invoice_status": "not_sent",
  "total": "480.00",
  "balance_remaining": "480.00"
}
```

## Send invoice

`POST https://cotlet.dev/api/v1/kickserv/send_invoice`

Access: write. Confirm: waits for the user's OK before it runs.

Emails the invoice to the main customer of the job and copies the addresses you add. The invoice then shows as sent on the Invoices page. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |
| `to` | string[] | no | Recipient emails. Default: the main customer of the job. |
| `cc` | string[] | no | Extra emails to copy. |
| `subject` | string | no | Email subject. Default: your Messaging Templates subject. |
| `message` | string | no | Custom message. Default: your Messaging Templates message. |
| `attach_pdf` | boolean | no | Also attach a PDF copy. Default: your Messaging Templates setting. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/send_invoice \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"1037"}'
```

**Python**

```python
result = client.call("kickserv", "send_invoice", {"job_number":"1037"})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'send_invoice', {"job_number":"1037"});
```

**CLI**

```bash
cotlet call kickserv send_invoice --data '{"job_number":"1037"}'
```

### Example response

```json
{
  "job_number": "1037",
  "invoice_status": "sent",
  "sent_to": [
    "lee@example.com"
  ],
  "total": "480.00",
  "balance_remaining": "480.00"
}
```

## Record payment

`POST https://cotlet.dev/api/v1/kickserv/record_payment`

Access: write. Confirm: waits for the user's OK before it runs.

Logs the payment type on the job, then marks the invoice paid when mark_paid is true. Kickserv does not bring the balance to zero for manual payments on its own, so the type is recorded first. No card is charged. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `job_number` | string | yes | Job number from list_jobs, list_opportunities or get_job. |
| `amount` | string | yes | Amount as a decimal, e.g. 480.00. |
| `method` | string | yes | Payment type as named in your account, e.g. Check. |
| `paid_on` | date | no | Default: today. |
| `mark_paid` | boolean | no | Mark the invoice paid afterwards. Default: true. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/kickserv/record_payment \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"job_number":"1051","amount":"150.00","method":"Cash","paid_on":"2026-10-12","mark_paid":false}'
```

**Python**

```python
result = client.call("kickserv", "record_payment", {"job_number":"1051","amount":"150.00","method":"Cash","paid_on":"2026-10-12","mark_paid":False})
```

**Node.js**

```js
const result = await cotlet.call('kickserv', 'record_payment', {"job_number":"1051","amount":"150.00","method":"Cash","paid_on":"2026-10-12","mark_paid":false});
```

**CLI**

```bash
cotlet call kickserv record_payment --data '{"job_number":"1051","amount":"150.00","method":"Cash","paid_on":"2026-10-12","mark_paid":false}'
```

### Example response

```json
{
  "job_number": "1037",
  "amount": "480.00",
  "method": "Check",
  "paid_on": "2026-10-10",
  "invoice_status": "paid",
  "balance_remaining": "0.00"
}
```
