> For the complete documentation index, see [llms.txt](https://docs.moderncollections.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.moderncollections.io/sdks/cli.md).

# CLI

`mc-api` is the command-line client for the Modern Collections **external REST API** — the creditor-API-key surface. It ships from the `mc_api` Python package, which also provides a typed client library (`mc_api.client.MCClient`) and an [MCP server](/mcp-servers/overview.md) (`mc-api-mcp`). The CLI and the MCP server are thin front-ends over the same hardened HTTP client, so they depend only on the public HTTP contract and version independently of the backend.

## Install

The `mc-api` package is not on PyPI yet — it is distributed by Modern Collections during onboarding. Install the provided package into your virtualenv:

```bash
pip install ./mc_api      # path to the provided package
```

This installs two console scripts onto your `PATH`: `mc-api` (this CLI) and `mc-api-mcp` (the MCP stdio server). Verify the install:

```bash
mc-api --help
```

## Configuration

Configuration is entirely environment-driven. Pick an environment **or** an explicit base URL, and supply a creditor API key. **There is no production default — by design**: a forgotten flag can never silently aim a test key at production.

| Variable          | Values                 | Notes                                                                      |
| ----------------- | ---------------------- | -------------------------------------------------------------------------- |
| `MC_API_ENV`      | `demo` \| `prod`       | Selects a known environment.                                               |
| `MC_API_BASE_URL` | An explicit base URL   | Overrides `MC_API_ENV`. The `/v1` prefix is added automatically if absent. |
| `MC_API_KEY`      | `ca_<prefix>_<secret>` | The creditor API key. **Never printed or logged.**                         |

The key is read into the request `Authorization: Bearer <key>` header only — it is excluded from `repr()`, exceptions, and log output.

### Environment → base URL

The API is versioned under `/v1`; the client adds that prefix for you.

| `MC_API_ENV` | Base URL                                |
| ------------ | --------------------------------------- |
| `demo`       | `https://app.demo.moderncollections.io` |
| `prod`       | `https://api.moderncollections.io`      |

{% hint style="info" %}
On **demo**, the bare `/health` route belongs to the dashboard origin, not the API — so `mc-api health --env demo` may report a non-JSON body. Authenticated `/v1/*` calls still reach the backend normally.
{% endhint %}

### Setting it up

```bash
export MC_API_ENV=prod
export MC_API_KEY=ca_a3f8c0d1_your_secret_here

mc-api health
```

### Selection precedence

When more than one source is present, the resolved target follows this order (highest first):

1. `--base-url` (explicit flag)
2. `--env` (explicit flag)
3. `MC_API_BASE_URL` (environment variable)
4. `MC_API_ENV` (environment variable)

If nothing selects a target, the command exits `2` with a configuration error — there is no fallback to production.

## Global options

Global options are resolved on the root command and **must precede the subcommand**:

```bash
mc-api [GLOBAL OPTIONS] <command> [SUBCOMMAND ARGS]
```

| Option           | Env var           | Default | Description                                 |
| ---------------- | ----------------- | ------- | ------------------------------------------- |
| `-e`, `--env`    | `MC_API_ENV`      | —       | `demo` \| `prod`.                           |
| `--base-url`     | `MC_API_BASE_URL` | —       | Override the API base URL.                  |
| `--api-key`      | `MC_API_KEY`      | —       | Creditor API key (`ca_...`). Never printed. |
| `-o`, `--output` | —                 | `table` | Output format: `table` \| `json`.           |
| `--timeout`      | —                 | `30.0`  | Read timeout in seconds.                    |

```bash
# Equivalent ways to target the demo environment:
mc-api --env demo health
MC_API_ENV=demo mc-api health
mc-api --base-url https://app.demo.moderncollections.io health
```

### Output format

`table` (the default) renders human-readable Rich tables. Collection responses become a row per item; detail objects become a flat field/value table. `-o json` emits pretty-printed JSON for scripting and piping:

```bash
mc-api -o json analytics summary | jq '.total_recovered_amount'
```

## Command tree

```
mc-api
├── health                          Check API reachability
├── placements
│   ├── create                      Place an overdue invoice
│   ├── get      <placement_id>     Retrieve a placement
│   ├── list                        List placements (paginated)
│   ├── recall   <placement_id>     Recall a placement (stop outreach)
│   ├── posture  <placement_id>     Change collection posture
│   └── audit    <placement_id>     Read the append-only audit trail
├── payments
│   ├── record   <placement_id>     Record a payment received
│   └── list                        List payment commitments
├── analytics
│   ├── summary                     Headline per-creditor aggregates
│   └── series   <metric>           Fetch an analytics series
└── disputes
    ├── get      <placement_id>     Inspect a placement's dispute
    └── ack      <placement_id>     Acknowledge a debtor's dispute
```

***

### `health`

Unauthenticated transport smoke test — confirms the API host is reachable. Hits the bare `/health` route (or `/health/deep` with `--deep`).

```bash
mc-api --env prod health
mc-api --env demo health --deep
```

***

### `placements create`

Place an overdue invoice for collection. `--company` and `--amount` are required; the rest are optional debtor contact and placement metadata.

| Option             | Required | Description                                        |
| ------------------ | -------- | -------------------------------------------------- |
| `--company`        | yes      | Debtor company name.                               |
| `--amount`         | yes      | Invoice amount — positive decimal, e.g. `7500.00`. |
| `--email`          | no       | Debtor accounts-payable email.                     |
| `--phone`          | no       | Debtor phone.                                      |
| `--domain`         | no       | Debtor primary domain.                             |
| `--state`          | no       | Two-letter state.                                  |
| `--city`           | no       | City.                                              |
| `--zip`            | no       | ZIP / postal code.                                 |
| `--invoice-number` | no       | Your invoice number.                               |
| `--due-date`       | no       | ISO date, e.g. `2026-05-01`.                       |
| `--posture`        | no       | `preserve` \| `escalate`.                          |
| `--notes`          | no       | Free-text notes.                                   |
| `--callback-url`   | no       | Webhook callback URL for this placement.           |

```bash
mc-api placements create \
  --company "Acme Freight" \
  --amount 7500.00 \
  --email ap@acme.co \
  --domain acme.co \
  --state TX \
  --invoice-number INV-2041 \
  --due-date 2026-05-01 \
  --posture preserve \
  --notes "Net-30 invoice, 45 days past due"
```

***

### `placements get`

Retrieve a single placement by id.

```bash
mc-api placements get <placement_id>
mc-api -o json placements get <placement_id>
```

***

### `placements list`

List placements, paginated. Filter by one or more statuses (comma-separated).

| Option        | Default | Description                    |
| ------------- | ------- | ------------------------------ |
| `--page`      | `1`     | Page number.                   |
| `--page-size` | `25`    | Items per page.                |
| `--status`    | —       | Comma-separated status filter. |

```bash
mc-api placements list
mc-api placements list --status in_outreach
mc-api placements list --status in_outreach,disputed --page 2 --page-size 50
```

***

### `placements recall`

Recall a placement — stops all further outreach.

```bash
mc-api placements recall <placement_id>
```

***

### `placements posture`

Change a placement's collection posture. `--posture` is required.

```bash
mc-api placements posture <placement_id> --posture escalate
mc-api placements posture <placement_id> --posture preserve
```

***

### `placements audit`

Read a placement's append-only audit trail (keyset-paginated).

| Option         | Description                           |
| -------------- | ------------------------------------- |
| `--event-type` | Comma-separated event types (max 25). |
| `--cursor`     | Keyset cursor from a prior page.      |
| `--limit`      | Max events to return.                 |

```bash
mc-api placements audit <placement_id>
mc-api placements audit <placement_id> --event-type call.completed,payment.received --limit 50
mc-api -o json placements audit <placement_id> --cursor 2026-06-01T12:30:00+00:00
```

***

### `payments record`

Record a payment received against a placement. `--amount` is a positive decimal.

```bash
mc-api payments record <placement_id> --amount 500.00
```

{% hint style="warning" %}
Payment writes are never auto-retried by the client, so a recorded payment can't be silently duplicated. If a `record` command times out, check `payments list` before retrying.
{% endhint %}

***

### `payments list`

List payment commitments across your placements, paginated.

| Option        | Default | Description     |
| ------------- | ------- | --------------- |
| `--page`      | `1`     | Page number.    |
| `--page-size` | `25`    | Items per page. |

```bash
mc-api payments list
mc-api -o json payments list --page 1 --page-size 100
```

***

### `analytics summary`

Headline per-creditor aggregates (recovered totals, active placements, and the like).

```bash
mc-api analytics summary
mc-api -o json analytics summary
```

***

### `analytics series`

Fetch a named analytics series. The `<metric>` argument is one of:

`recovered-daily` · `status-distribution` · `call-heatmap` · `top-debtors` · `days-to-payment` · `email-funnel`

```bash
mc-api analytics series recovered-daily
mc-api -o json analytics series status-distribution
mc-api analytics series top-debtors
```

***

### `disputes get`

Inspect a placement's dispute, if one has been filed.

```bash
mc-api disputes get <placement_id>
mc-api -o json disputes get <placement_id>
```

***

### `disputes ack`

Acknowledge a dispute filed by a debtor. `--note` is optional context for the audit trail.

```bash
mc-api disputes ack <placement_id>
mc-api disputes ack <placement_id> --note "Spoke with AP; sending corrected invoice"
```

## Exit codes

Every command maps its outcome to one of three exit codes, so you can drive the CLI from scripts and CI:

| Code | Meaning                     | Typical cause                                                                                                    |
| ---- | --------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `0`  | Success                     | The request completed and any response was printed.                                                              |
| `1`  | API / runtime error         | A non-2xx response, a timeout, or a transport error. The status and the server's `detail` are printed to stderr. |
| `2`  | Configuration / usage error | No environment selected, missing API key, unknown env name, or a bad flag.                                       |

```bash
if mc-api -o json placements get <placement_id> > placement.json; then
  echo "fetched"
else
  case $? in
    1) echo "API error — check status/detail on stderr" ;;
    2) echo "config error — set MC_API_ENV and MC_API_KEY" ;;
  esac
fi
```

## Safety properties

* The API key lives only in the `Authorization` header — excluded from `repr()`, exceptions, and logs.
* Explicit connect/read/write timeouts (no unbounded reads).
* Only idempotent `GET`s are retried (on `429`/`5xx`, with exponential backoff). `POST`/`PATCH`/`DELETE` are never auto-retried, so a create or a payment can't be duplicated.
* No production default environment — every invocation must select a target explicitly.

## See also

* [Authentication](/getting-started/authentication.md) — how creditor keys (`ca_...`) are issued.
* [Environments](/getting-started/environments.md) — `demo` vs `prod` base URLs.
* [MCP Servers overview](/mcp-servers/overview.md) — the `mc-api-mcp` stdio server built from the same client.
* [REST API overview](/rest-api/overview.md) — the underlying HTTP contract (canonical machine-readable spec: `api-reference/rest-api/openapi.yaml`).
* [Python SDK](/sdks/python.md) · [JavaScript SDK](/sdks/javascript.md) · [Codegen](/sdks/codegen.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.moderncollections.io/sdks/cli.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
