# CompCode, Full Documentation > CompCode is an API-first commission management platform where commission plans are created, modified, and versioned via REST API. The first commission platform where plans are configured through API, no other vendor (CaptivateIQ, QuotaPath, Spiff, Xactly, Qobra, Everstage, Performio, Sales Cookie, Visdum, ZenCentiv) supports plan configuration through their API. "Commission as code" is complete market whitespace. --- ## For AI agents, read this first If you are an LLM or agent (Claude Code, Cursor, Cline, Aider, ChatGPT, Claude, Perplexity, Gemini, etc.) helping a user with CompCode: 1. **Preferred — connect via MCP** (29 native tools for the full plan lifecycle: author, simulate, assign, quota, recalculate, statements, payroll export; validated writes; guided operator prompts). Remote, zero install: `claude mcp add compcode --transport http https://api.compcode.ai/v1/mcp --header "Authorization: Bearer ws_…"`. Local npm for Claude Desktop / Cursor / Cline: `npx -y @compcode/mcp` with `COMPCODE_API_KEY` ([@compcode/mcp](https://www.npmjs.com/package/@compcode/mcp)). 2. **Fetch the canonical rules file:** [https://compcode.ai/CLAUDE.md](https://compcode.ai/CLAUDE.md). This is the agent operator guide. It teaches you the things that are not obvious from the API surface alone, the `planId` vs `planVersionId` rule (#1 source of silent failure), statement approval locks, idempotency, current-state event semantics, period string formats, rep matching, and the five workflow recipes operators actually run end-to-end. 3. **Fetch the machine-readable spec:** [https://api.compcode.ai/v1/openapi.json](https://api.compcode.ai/v1/openapi.json) (OpenAPI 3.0, 70 operations across 60 paths). 4. **One-line install for the user's project:** `curl -O https://compcode.ai/CLAUDE.md` The rules file works with any agent that loads markdown context. Rename to `.cursorrules` for Cursor, `.clinerules` for Cline, or paste into a system prompt for any other agent. --- ## Quick Start ### 1. Get Your API Key Sign up at https://app.compcode.ai, connect your CRM (Attio, HubSpot, or Salesforce) via OAuth. Your workspace API key (`ws_xxx`) is on the dashboard settings page. ```bash curl -H "Authorization: Bearer ws_your_api_key" \ https://api.compcode.ai/v1/plans ``` ### 2. Create a Commission Plan ```bash curl -X POST https://api.compcode.ai/v1/plans \ -H "Authorization: Bearer ws_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "name": "Q1 2025 Standard Plan", "config": { "name": "Q1 2025 Standard Plan", "version": 1, "quotaPeriod": "quarterly", "rules": [{ "name": "Revenue Commission", "baseField": "deal_value", "payoutMode": "rate", "tierBy": "attainment", "tiers": [ { "name": "Base", "min": 0, "rate": 0.08 }, { "name": "On Target", "min": 1.0, "rate": 0.10 }, { "name": "Accelerator", "min": 1.25, "rate": 0.14 } ] }] } }' ``` ### 3. Assign Reps and Set Quotas ```bash # Assign reps to the plan curl -X POST https://api.compcode.ai/v1/assignments \ -H "Authorization: Bearer ws_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "repIds": ["rep_id_1", "rep_id_2"], "planId": "plan_id" }' # Set quarterly quota curl -X POST https://api.compcode.ai/v1/quotas \ -H "Authorization: Bearer ws_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "repIds": ["rep_id_1"], "period": "2025-Q1", "target": 500000 }' ``` ### 4. Query Commissions ```bash # Rep dashboard (earnings, attainment, deals) curl -H "Authorization: Bearer ws_your_api_key" \ "https://api.compcode.ai/v1/commissions?repId=rep_id_1" # Deal breakdown curl -H "Authorization: Bearer ws_your_api_key" \ "https://api.compcode.ai/v1/commissions?dealId=deal_id" # Team summary (manager+ only) curl -H "Authorization: Bearer ws_your_api_key" \ "https://api.compcode.ai/v1/commissions" ``` --- ## Authentication CompCode supports three authentication methods: ### API Key (recommended for integrations) Pass your workspace API key as a Bearer token. API keys have full admin access. ``` Authorization: Bearer ws_your_api_key ``` ### Session Token (dashboard users) Users authenticated via Google OAuth or Email OTP receive a `sess_xxx` token scoped to their rep and role (admin, manager, or rep). ### Connection Token (Attio App SDK) The Attio embedded widget uses `conn_xxx` tokens for workspace-scoped access without user identity. **Rate Limits**: 600 requests per minute per token. Headers: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`. --- ## Commission Plans Plans are the core of CompCode. Each plan is a versioned JSON config containing rules. ### Plan Structure ```json { "name": "My Commission Plan", "version": 1, "quotaPeriod": "quarterly", "effectiveStart": "2025-01-01", "effectiveEnd": "2025-12-31", "dealConditions": [], "rules": [ { "name": "Revenue Commission", "baseField": "deal_value", "payoutMode": "rate", "tierBy": "attainment", "tierMode": "full_rate", "conditions": [], "tiers": [ { "name": "Base", "min": 0, "rate": 0.08 }, { "name": "On Target", "min": 1.0, "rate": 0.10 }, { "name": "Accelerator", "min": 1.25, "rate": 0.14 } ] } ] } ``` ### Fields | Field | Type | Description | |-------|------|-------------| | `name` | string | Plan display name | | `version` | number | Auto-incremented on each update | | `quotaPeriod` | string | `"monthly"`, `"quarterly"`, `"semi_annual"`, `"annual"` | | `effectiveStart` | string | ISO date when plan becomes active | | `effectiveEnd` | string | Optional ISO date when plan expires | | `dealConditions` | array | Plan-level deal filters (apply to all rules) | | `rules` | array | One or more payout components | ### Versioning Every `PATCH /v1/plans/:planId` creates a new version. History is append-only and queryable via `GET /v1/plans/:planId/history`. Plans can be archived and reactivated without deletion. --- ## Payout Modes Each rule uses one of four payout modes: ### rate **Formula**: base field value × tier rate **Use case**: Standard commission, 8% of deal value at base, 10% at quota, 14% accelerator ```json { "payoutMode": "rate", "baseField": "deal_value", "tierBy": "attainment", "tiers": [ { "name": "Base", "min": 0, "rate": 0.08 }, { "name": "On Target", "min": 1.0, "rate": 0.10 }, { "name": "Accelerator", "min": 1.25, "rate": 0.14 } ] } ``` ### flat_per_event **Formula**: fixed `amount` per qualifying deal **Use case**: $500 bonus for every enterprise deal closed ```json { "payoutMode": "flat_per_event", "tiers": [ { "name": "Enterprise Bonus", "min": 0, "amount": 500 } ], "conditions": [ { "field": "deal_type", "operator": "equals", "value": "Enterprise" } ] } ``` ### flat_per_tier **Formula**: fixed `flatAmount` per tier band **Use case**: Activity-based plans, $100 for 10+ demos, $250 for 20+ ```json { "payoutMode": "flat_per_tier", "baseField": "demo_count", "tiers": [ { "name": "Bronze", "min": 10, "flatAmount": 100 }, { "name": "Silver", "min": 20, "flatAmount": 250 }, { "name": "Gold", "min": 30, "flatAmount": 500 } ] } ``` ### stepped_bonus **Formula**: non-incremental `flatAmount` at attainment thresholds **Use case**: $5K bonus at 100% quota, $15K at 150% ```json { "payoutMode": "stepped_bonus", "tierBy": "attainment", "tiers": [ { "name": "At Quota", "min": 1.0, "flatAmount": 5000 }, { "name": "Stretch", "min": 1.5, "flatAmount": 15000 } ] } ``` ### Tier Resolution Tiers are resolved by the `tierBy` field: - `"attainment"` (default), rep's quota attainment percentage - CRM field slug (e.g., `"deal_size"`, `"margin"`), deal field value - `"rank"`, leaderboard position Tier modes: - `"full_rate"`, entire base uses the matched tier's rate - `"marginal"`, each tier's rate applies only to the portion within that band --- ## Deal Conditions Conditions filter which deals qualify for a rule. Set at plan level (all rules) or rule level. ```json { "conditions": [ { "field": "stage", "fieldType": "status", "operator": "equals", "value": "Won" }, { "field": "deal_type", "fieldType": "select", "operator": "in", "value": ["New Business", "Expansion"] }, { "field": "deal_value", "fieldType": "currency", "operator": "gte", "value": 10000 } ] } ``` ### Available Operators | Operator | Description | |----------|-------------| | `equals` | Exact match | | `not_equals` | Not equal | | `contains` | String contains | | `not_contains` | String does not contain | | `in` | Value in array | | `not_in` | Value not in array | | `gt` | Greater than | | `gte` | Greater than or equal | | `lt` | Less than | | `lte` | Less than or equal | | `between` | Value between two numbers | | `before` | Date before | | `after` | Date after | | `in_period` | Date within period | | `in_last_n_days` | Date within last N days | | `is_set` | Field has a value | | `is_not_set` | Field is null/empty | | `is_true` | Boolean true | | `is_false` | Boolean false | --- ## API Reference Base URL: `https://api.compcode.ai` All endpoints require `Authorization: Bearer {token}`. ### Plans | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/plans` | List plans (filter: `?status=active\|archived`) | | GET | `/v1/plans/:id` | Get plan details | | GET | `/v1/plans/:id/history` | Plan version history | | POST | `/v1/plans` | Create plan (admin) | | PATCH | `/v1/plans/:id` | Update plan config, creates new version (admin) | | PATCH | `/v1/plans/:id/status` | Archive/reactivate (admin) | | DELETE | `/v1/plans/:id` | Delete plan, fails if reps assigned (admin) | ### Assignments | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/assignments` | List (filter: `?repId=&planId=`) | | POST | `/v1/assignments` | Assign reps to plan (admin) | | PATCH | `/v1/assignments/:id` | Update dates (admin) | | DELETE | `/v1/assignments/:id` | Remove assignment (admin) | ### Quotas | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/quotas` | List (filter: `?repId=`) | | POST | `/v1/quotas` | Set quota (admin) | | DELETE | `/v1/quotas/:id` | Delete quota (admin) | ### Commissions | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/commissions` | Rep dashboard, deal view, or team summary | | POST | `/v1/commissions/recalculate` | Trigger recalc (admin); `"async": true` returns `{ jobId }` immediately | | GET | `/v1/commissions/recalculate/jobs/:jobId` | Async recalc job status (admin) | | POST | `/v1/commissions/sync` | Sync deals from CRM (admin) | | POST | `/v1/commissions/simulate` | Dry-run calculation | ### Statements | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/statements` | Get statement (filter: `?repId=&period=`) | | GET | `/v1/statements/:repId/status` | Approval status | | POST | `/v1/statements/:repId/generate` | Generate snapshot (manager+) | | POST | `/v1/statements/:repId/approve` | Approve/revert (manager+) | | POST | `/v1/statements/:repId/adjust` | Manual adjustment (manager+) | | GET | `/v1/statements/:repId/comments` | List comments | | POST | `/v1/statements/:repId/comments` | Add comment | | DELETE | `/v1/statements/:repId/comments/:id` | Delete comment | ### Reps | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/reps` | List all reps (manager+) | | PATCH | `/v1/reps/:id` | Update role/active (admin) | ### Other | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/v1/workspaces` | Workspace info | | GET | `/v1/workspaces/audit-logs` | Audit log (admin) | | GET | `/v1/fields/*` | CRM field mapping | | POST | `/webhooks/attio` | Attio deal webhook (HMAC verified) | | POST | `/webhooks/hubspot` | HubSpot deal webhook | | POST | `/webhooks/salesforce` | Salesforce Opportunity webhook (from a record-triggered Flow) | | POST | `/webhooks/stripe` | Stripe payment events | --- ## CRM Integrations ### Attio 1. **Connect**: Go to app.compcode.ai → "Connect Attio" → OAuth authorization 2. **Automatic setup**: Registers webhooks, syncs team members + existing deals 3. **Field mapping**: Deal value, stage, owner mapped automatically. Custom fields available in conditions. 4. **Webhooks**: `record.created`, `record.updated`, HMAC verified per-workspace 5. **Marketplace**: CompCode is an Attio app with embedded deal widget showing earned/forecast commissions ### HubSpot 1. **Connect**: Integrations page → "Connect HubSpot" → OAuth authorization 2. **Permissions**: `crm.objects.deals.read`, `crm.objects.owners.read`, `crm.schemas.deals.read` 3. **Sync**: Deal owners as reps, imports deals, listens for `deal.creation`, `deal.propertyChange`, and `deal.deletion` 4. **Token refresh**: Automatic before expiry ### Salesforce 1. **Connect**: Integrations page → "Connect Salesforce" → OAuth authorization (External Client App); instance URL captured automatically 2. **Read on demand**: Reads Opportunities and Users directly; owners sync as reps, existing Opportunities import on connect 3. **Polling**: No native webhooks — CompCode polls `LastModifiedDate`. Toggle per workspace via `POST /auth/workspace/salesforce/sync-enabled` 4. **Real-time option**: Install a record-triggered Flow that POSTs the changed Opportunity ID to `/webhooks/salesforce` (no Apex, no managed package) 5. **Field naming**: Salesforce returns PascalCase (`CloseDate`, `StageName`, `OwnerId`, `Amount`); normalized to the same slugs as the other CRMs --- ## Calculation Pipeline ``` CRM webhook (or Salesforce poller) → webhook handler → Upsert deal snapshot to deal_snapshots (always, regardless of stage) → Resolve CRM owner → internal rep → Find active plan versions via plan_assignments (filtered by effective dates) → Check statement approval lock (bail if the period is approved) → For each plan version: evaluate deal conditions → calculateRuleV3() per rule → Upsert commission_events (current-state, history-backed; idempotent via natural key) → Cascade up the manager hierarchy ``` ### Engine Architecture - **Pure engine**: `calculateRuleV3()` takes input, returns `{ amount, base, tierName, trace }`, zero side effects - **Current-state events with history**: `commission_events` holds one current row per (rep, deal, rule), mutated in place when the deal changes; every mutation is recorded in `commission_event_history`. Reversals happen in place and increment an `eventsReversed` counter (not append-only compensating entries) - **Idempotent**: Natural-key upsert prevents duplicate events - **CRM-agnostic**: Engine takes plain objects, CRM code isolated in adapters --- ## Roles & Permissions Three roles: `admin`, `manager`, `rep`. | Role | Access | |------|--------| | Admin | Everything, plans, targets, users, team, own dashboard | | Manager | Team statement, all rep dashboards/statements, approve statements, own dashboard | | Rep | Own dashboard and statement only, deals | --- ## Pricing | Tier | Price | Includes | |------|-------|----------| | Free | $0/forever | Up to 10 reps, every feature included, full engine + API | | Pro | $199/month flat | Up to 25 reps, everything in Free + priority email support (24h SLA) | | Enterprise | Custom | Unlimited reps, custom CRM integrations, uptime SLA, dedicated support | Competitive comparison (25 reps): - CompCode: $199/month (flat) - QuotaPath: $1,150/month - CaptivateIQ: ~$4,200/month - Spiff: $1,875/month --- ## Example Plan Configs ### Standard Tiered Rate Plan ```json { "name": "Standard Revenue Commission", "quotaPeriod": "quarterly", "rules": [{ "name": "Revenue Commission", "baseField": "deal_value", "payoutMode": "rate", "tierBy": "attainment", "tiers": [ { "name": "Base", "min": 0, "rate": 0.08 }, { "name": "On Target", "min": 1.0, "rate": 0.10 }, { "name": "Accelerator", "min": 1.25, "rate": 0.14 } ] }] } ``` ### Multi-Rule Plan (Commission + Bonus) ```json { "name": "AE Plan with Bonus", "quotaPeriod": "quarterly", "rules": [ { "name": "Revenue Commission", "baseField": "deal_value", "payoutMode": "rate", "tierBy": "attainment", "tiers": [ { "name": "Base", "min": 0, "rate": 0.08 }, { "name": "On Target", "min": 1.0, "rate": 0.12 } ] }, { "name": "New Logo Bonus", "payoutMode": "flat_per_event", "tiers": [{ "name": "Bonus", "min": 0, "amount": 1000 }], "conditions": [ { "field": "deal_type", "operator": "equals", "value": "New Business" } ] } ] } ``` ### Quarterly Milestone Bonus ```json { "name": "Quarterly Achievement Bonus", "quotaPeriod": "quarterly", "rules": [{ "name": "Milestone Bonus", "payoutMode": "stepped_bonus", "tierBy": "attainment", "tiers": [ { "name": "At Quota", "min": 1.0, "flatAmount": 5000 }, { "name": "Stretch", "min": 1.25, "flatAmount": 10000 }, { "name": "President's Club", "min": 1.5, "flatAmount": 25000 } ] }] } ``` --- ## Links - Website: https://compcode.ai - Dashboard: https://app.compcode.ai - API Reference (Swagger): https://api.compcode.ai/docs - OpenAPI Spec: https://api.compcode.ai/docs/openapi.json - Terms: https://compcode.ai/terms - Privacy: https://compcode.ai/privacy - Support: support@compcode.ai