Developers
Every endpoint in the Polemica CRM — companies, contacts, deals, quotes, payments, and the lead-gate scanner. Built to be used directly, or handed straight to an AI agent.
Setup
Base URL
https://your-subdomain.polemica.ca
API Key
pk_crm_…
Settings → API & Integrations
Every request below uses these two values. The master key (pk_crm_…) unlocks every endpoint. A separate scanner key (sk_scan_…) is scoped to POST /scanner/scans only.
Authentication
X-Api-Key: {API_KEY}
OR
Authorization: Bearer {API_KEY}
For AI Agents
Copy the block below into ChatGPT, Claude, or any agent's custom instructions. It knows every endpoint, which fields are required, and the order operations need to happen in — like fetching pipeline stages before creating a deal.
# Polemica CRM — API Reference
## SETUP — Ask the user these two questions before anything else:
1. "What is your Polemica base URL?" (format: https://your-subdomain.polemica.ca)
2. "What is your Polemica API key?" (format: pk_crm_…, found in Settings → API & Integrations)
Store answers as BASE_URL and API_KEY. Use them in every request below.
Do NOT make any API call until you have both values confirmed by the user.
## Authentication
Header: X-Api-Key: {API_KEY}
OR: Authorization: Bearer {API_KEY}
Master key (pk_crm_…) unlocks all endpoints.
Scanner key (sk_scan_…) is for POST /scanner/scans only.
## Global Search
GET {BASE_URL}/search?q={query}
Use this first when user mentions a name, company, or email.
## Companies
GET {BASE_URL}/companies params: q, province, limit, offset
GET {BASE_URL}/companies/{id}
POST {BASE_URL}/companies body: { name(req), domain, website, industry, size, city, province, phone }
GET {BASE_URL}/companies/{id}/contacts
## Contacts
GET {BASE_URL}/contacts params: q, company_id, limit
GET {BASE_URL}/contacts/{id}
POST {BASE_URL}/contacts body: { name(req), email, phone, title, company_id, linkedin_url }
## Pipeline / Deals
GET {BASE_URL}/pipelines ← call this first to get pipeline IDs
GET {BASE_URL}/pipelines/{id}/stages ← call this to get stage IDs
GET {BASE_URL}/pipelines/{id}/cards
GET {BASE_URL}/cards/{id}
POST {BASE_URL}/cards body: { stage_id(req), title(req), contact_name, contact_email, contact_phone, value, source, company_id }
POST {BASE_URL}/cards/{id}/notes body: { text(req), author }
POST {BASE_URL}/cards/{id}/tasks body: { title(req), due_date, assignee }
RULE: Always call GET /pipelines then GET /pipelines/{id}/stages before creating a deal.
## Products
GET {BASE_URL}/products params: q, category
GET {BASE_URL}/products/{id}
GET {BASE_URL}/products/sku/{sku}
GET {BASE_URL}/products/categories
## Quotes
GET {BASE_URL}/quotes
GET {BASE_URL}/quotes/{id}
POST {BASE_URL}/quotes body: { company_id, contact_name, currency(default CAD), valid_until, notes }
POST {BASE_URL}/quotes/{id}/lines body: { description(req), qty(req), unit_price(req), product_id, discount_pct, tax_pct(default 5) }
## Payments
GET {BASE_URL}/payments
POST {BASE_URL}/payments body: { amount(req), currency, method(e-transfer/credit_card/cash), quote_id, company_id, note }
## Shipments
GET {BASE_URL}/shipments
POST {BASE_URL}/shipments body: { quote_id, carrier, tracking, destination, shipped_at }
## Communications
GET {BASE_URL}/communications
GET {BASE_URL}/communications/threads
POST {BASE_URL}/communications body: { channel(req: email/call/sms/meeting), direction(req: inbound/outbound), body, contact_email, card_id }
## Inbox
GET {BASE_URL}/inbox/forms
GET {BASE_URL}/inbox/bookings
POST {BASE_URL}/inbox/forms/{id}/to-crm
## Scanner / Lead Gates
POST {BASE_URL}/scanner/scans key: sk_scan_… — body: { url(req), scan_data(req), label }
returns: { scan_id, token, result_url }
POST {BASE_URL}/scanner/leads public, no key — body: { token(req), email(req), name, phone, company }
GET {BASE_URL}/scanner/results/{token} only works after lead submitted
## Errors
200 OK | 201 Created | 400 Bad request | 401 Invalid key | 403 Forbidden | 404 Not found | 422 Missing field
Error body: { "detail": "message" }
## Agent rules
- Always confirm with user before creating, updating, or deleting records.
- Search first (GET /search) before creating, to avoid duplicates.
- If a required field is missing, ask the user — do not guess.
Endpoints
Global Search
Use this first when a name, company, or email comes up — before creating a new record.
Companies
Contacts
Pipeline / Deals
Always call GET /pipelines then GET /pipelines/{id}/stages before creating a deal.
Products
Quotes
Payments
Shipments
Communications
Inbox
Scanner / Lead Gates
Errors
Error responses have the shape { "detail": "message" }.
Agent Rules
FAQ
Where do I get my API key?
In your Polemica CRM, go to Settings → API & Integrations. The master key starts with pk_crm_ and unlocks every endpoint below. A separate scanner key (sk_scan_…) is issued for the lead-gate scanner endpoint only.
Can I give this page to an AI agent (ChatGPT, Claude, etc.)?
Yes — that's what the copy block below is for. Paste it into your agent's custom instructions along with your base URL and API key, and it knows every endpoint, required field, and the order operations need to happen in (e.g. fetching pipeline stages before creating a deal).
Is the scanner lead endpoint really public?
Yes. POST /scanner/leads is intentionally unauthenticated — it is what your public-facing lead-gate scanner calls when a visitor submits their email to unlock a scan result. Every other endpoint requires a key.
What happens if I send a request with a missing required field?
You get a 422 with a JSON body like { "detail": "message" } naming the missing field. Required fields are marked (req) in each endpoint's body definition below.