← Back to appMCA Manager Helpmcamgr.com
Browse help topics

Using the API

MCA Manager exposes a REST API (v1) for automating intake, syncing deals and payments, and integrating your stack. Everything below is also in the machine-readable spec at /api/openapi.json and the interactive API reference, where you can send real requests and download a Postman collection.

Authentication and scopes

Requests authenticate with a per-tenant API key sent as a bearer token on your company host:

Authorization: Bearer mca_live_…

Keys are created under Settings → API keys (guide) with per-resource scopes (deals:read, payments:write, *:read…; write implies read), an optional expiry and an IP allow-list. A test key (mca_test_…) is served by your sandbox tenant, or read-only until one exists.

Start with GET /api/v1/whoami: it returns the key's scopes, the tenant it is pointed at and the rate limit.

Responses and errors

Every response carries X-Request-Id. Errors share one envelope:

{ "error": "request did not validate", "code": "validation_error",
  "details": [{ "path": "amount", "message": "money must be a decimal string…" }],
  "requestId": "6f0c…" }

| Status | Codes | |---|---| | 400 | validation_error, invalid_id, invalid_json, invalid_sort, invalid_expand, invalid_cursor, bad_request | | 401 | unauthorized (missing, invalid or expired key) | | 403 | forbidden (scope missing, key read-only, address not allowed) | | 404 | not_found | | 409 | conflict (illegal state transition, funding block, duplicate) | | 422 | invalid_reference, idempotency_key_reused | | 429 | rate_limitedRetry-After: 60 | | 500 | internal_error — quote the requestId |

Lists: pagination, sorting, filtering

GET /api/v1/deals?state=FUNDED&limit=100&sort=fundedAt:desc&expand=merchant&fields=id,dealNumber,fundedAmount
→ { "deals": [...], "count": 100, "hasMore": true, "nextCursor": "MTA0Mg" }
  • limit (1–200, default 50) and cursor (pass nextCursor back) page through results; cursors are stable under inserts.
  • sort=field:asc|desc from each resource's documented sortable fields; id is always available and used as the tiebreak.
  • expand= includes relations (e.g. merchant,payments on deals); fields= returns only the named columns (plus id).
  • ids=1,2,3, q= (free text where supported), createdSince, createdBefore, updatedSince work everywhere; each resource adds its own filters (deal state, payment status/type/scheduledSince, lead status/source…).

Writes

  • Send Idempotency-Key on POSTs. The first request runs; a repeat with the same key and body returns the stored response (Idempotency-Replayed: true) for 24 hours; the same key with a different body is refused with 422.
  • Money is a decimal string with at most two places ("425.00"); a cent-exact number is accepted, anything else is rejected. Amounts come back as decimal strings.
  • Timestamps are UTC ISO-8601; dates as YYYY-MM-DD.
  • Deal and payment writes run the same code as the staff screens: a deal created through the API gets its deal number, house submission and stip matrix; PATCH /deals/{id} with state runs the state machine and funding blocks; marking a payment PAID posts the ledger entry. Every write is audited and emits the matching webhook event.

Rate limits

120 requests per minute per key. X-RateLimit-Limit and X-RateLimit-Remaining are on every response; a 429 carries Retry-After. Back off and retry with the same Idempotency-Key on writes.

Versioning

The API is versioned in the path (/api/v1). Additive changes — new fields, filters, endpoints, events — ship without notice and are listed in the changelog below. Breaking changes ship as /api/v2 with at least 12 months of overlap, and deprecated operations carry a Deprecation header during that time.

Examples

Create a lead from a website form (cURL):

curl -X POST https://acme.mcamgr.com/api/v1/leads \
  -H "Authorization: Bearer mca_live_…" -H "Content-Type: application/json" \
  -H "Idempotency-Key: form-8841" \
  -d '{ "businessName": "Acme Diner LLC", "contactName": "Pat Owner", "email": "pat@example.com", "phone": "555-0100", "source": "website" }'

Page through funded deals (Node):

let cursor = null;
do {
  const r = await fetch(`https://acme.mcamgr.com/api/v1/deals?state=FUNDED&limit=200${cursor ? `&cursor=${cursor}` : ""}`, { headers: { Authorization: `Bearer ${KEY}` } });
  const page = await r.json();
  for (const deal of page.deals) sync(deal);
  cursor = page.nextCursor;
} while (cursor);

Mark a payment paid (Python):

import requests
r = requests.patch("https://acme.mcamgr.com/api/v1/payments/9001",
    headers={"Authorization": f"Bearer {KEY}"}, json={"status": "PAID", "clearedDate": "2026-09-22"})
r.raise_for_status(); print(r.headers["X-Request-Id"], r.json()["payment"]["status"])

API changelog

  • v630 — OpenAPI generated from the code (every operation, real request/response schemas), full-method explorer with Postman export.
  • v629 — API keys: scopes, live/test kinds, expiry, IP allow-list, rotation; GET /whoami.
  • v628 — Error envelope with requestId, X-RateLimit-*, cursor pagination, sort/expand/fields/ids/date windows, per-resource filters, Idempotency-Key, decimal-string money; deal and payment writes through the shared services.
  • v626 — Webhook envelope { id, event, version, occurredAt, data }, new lifecycle events, /webhook-endpoints management, inbound idempotency.
  • v625 — Webhook delivery log, retries, auto-pause; https-only endpoints.
  • v624 — Merchant contacts return ssnLast4 only.

Can’t find what you need? Return to the app or contact your administrator.

Using the API - Help