Invoice Calculation
Monthly invoice for a single customer email. Aggregates TCV and License Fee per product group.
Document Signing
Send PDF documents for e-signature via DocuSeal and track signing status.
Orders
Browse and search direct orders or reseller orders.
| Enter a search term above and click Search. |
Formula columns
cols AL–BC of the Excel "Raw Data" sheet
Import CSV
Upload a
.csv file or an archive containing one
(.zip, .gz, .tar.gz, .bz2, .xz).
Columns should match the Excel Raw Data sheet (cols A–AK);
headers are matched case-insensitively. Derived columns (AL–BC) are
regenerated automatically after every import. Refund rows (negative
Order value) are stored alongside their sale row, sharing the same
Sales order number.
Fetch from Metabase
Import history
| When | File | Total | Inserted | Updated | Skipped | Failures | Notes |
|---|
Import Scheduler
Automate recurring Metabase fetches. At most one import runs at a time — extras queue behind the active one.
Schedules
| Name | Job / Report | Interval | Next run | Enabled | Actions |
|---|
Queue
Add Schedule
Backfill Jobs
New Backfill Job
| Name | Report | Progress | Status | Recur | Chunk | Delay | Last chunk | Rows | Actions |
|---|---|---|---|---|---|---|---|---|---|
| No backfill jobs. | |||||||||
Execution log
| Schedule | Report | Queued at | Status | Fetched | Imported | Fetch time | Import time | Error |
|---|
Lookup Tables
Edits trigger a recompute of the derived columns on all orders.
▸ Product List All products with their SKU(s), group, customer type, and bundle component groups (if any).
| Product | SKU | Group | Customer Type | Company | Bundle Groups |
|---|
▸ Product Groups Maps product name → SKU / product group / customer type / company.
| Product | SKU | Group | Customer Type | Company |
|---|
▸ Product Bundle Components Maps a bundle product name to the product groups it counts toward in the Product Penetration report.
| Bundle Product | Component Group |
|---|
▸ Product Owner Companies Maps product group → owning company / customer type.
| Group | Company | Customer Type |
|---|
▸ Countries Maps country → continent. Used by region rollups in reports.
| Country | Region |
|---|
▸ Excluded Account / vTiger IDs Account / vTiger IDs excluded from Same vTiger ID and Same Account ID expansion in License Timeline.
| Account / vTiger ID | Note | Added |
|---|
Users
Add users by their Microsoft email. They can sign in via SSO once added.
▶
awaiting approval
| Name | Microsoft Email | Joined | Assign role |
|---|
Active users
| Name | Microsoft Email (SSO) | Type | Role | Created | Last login | Manager |
|---|
API Keys
Issue API keys for external applications to access the CAM REST API (v1).
API Reference & Usage Guide
Authentication — include your key on every request via header or query param:
All responses return
X-Api-Key: cam_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
or
?api_key=cam_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
{"ok": true, ...} on success or {"ok": false, "error": "..."} on failure.
GET
/api/v1/customers/search
Every ordering email at a customer's domain, with VIP status and account owner
email=<address> one of email / c1_id is requiredc1_id=<24-hex C1 identity> resolved to an email, then to its domain
Scope
customers:read. Returns every address at the domain with at least one order in any state. is_vip is true/false/null — null means the CRM privilege status was never set, which is not the same as "not VIP". Refused for generic mail domains.
curl -H "X-Api-Key: cam_..." "https://<host>/api/v1/customers/search?email=it@acme.com"
{"ok": true, "domain": "acme.com", "count": 47, "vip_count": 16,
"customers": [{"email": "it@acme.com", "organization": "Acme",
"order_count": 46, "first_order_date": "2023-02-01", "last_order_date": "2026-07-14",
"gross_order_value": 250.59, "is_vip": true, "privilege_status": "Vip",
"account_owner": "Karla Decastro", "vtiger_account_id": "3414429"}]}
GET
/api/v1/customers/orders
A customer's own order history — not scoped to a reseller
email=<address> / c1_id=<24-hex> one is requiredexpand=domain optional — all addresses at the same domainfrom= / to=YYYY-MM-DD optional — create-date rangeinclude_refunds=1 optional — default excludedpage= / per_page= optional — max 500
Scope
orders:read. Same per-order fields as the partner endpoint, plus billing_model and organization. Unlike /partners/end_customer/direct_orders there is no reseller ownership check and no postpaid-only filter.
curl -H "X-Api-Key: cam_..." "https://<host>/api/v1/customers/orders?email=it@acme.com&from=2026-01-01"
GET
/api/v1/customers/payments
Invoices, balances and payment status for a customer
email=<address> / c1_id=<24-hex> one is requiredexpand=domain optionalstatus=paid|open|partially_paid|overdue optional filterpage= / per_page= optional — max 500
Scope
payments:read. status is derived from balance and due date, not passed through from the source system — the accounting platform is never named and none of its identifiers are exposed.
curl -H "X-Api-Key: cam_..." "https://<host>/api/v1/customers/payments?email=it@acme.com&status=overdue"
{"ok": true, "total": 21,
"summary": {"invoice_count": 21, "total_billed": 440.62, "total_outstanding": 440.62,
"overdue_count": 21, "overdue_amount": 440.62},
"invoices": [{"invoice_number": "42736574-50", "issued_date": "2026-07-07",
"due_date": "2026-07-07", "billed_to": "it@acme.com", "total": 4.80,
"balance": 4.80, "amount_paid": 0.00, "currency": "USD",
"payment_terms": "Due on receipt", "status": "overdue"}]}
GET
/api/v1/usage/active
Active product usage (seats, used, overused, devices online) for one customer
c1_id=<identity> exactly one of c1_id / email is requiredemail=<address> matches the portal, ITSM or order emailexpand=domain optional — also include every account at the same mail domainas_of=YYYY-MM-DD optional — snapshot date (default: latest available)
Requires the
usage:read scope. Returns an array: one customer commonly spans several C1 identities, and a single email can match the portal, ITSM or order address. totals sums the records. Usage is a monthly snapshot, not live — always read as_of. expand=domain is opt-in and refused for generic mail domains.
curl -H "X-Api-Key: cam_..." \
"https://<host>/api/v1/usage/active?email=it@acme.com&expand=domain"
# Response
{
"ok": true,
"matched_by": "domain",
"as_of": "2026-08-01",
"count": 2,
"records": [
{
"c1_id": "5d70ba8716c6550009921fb2",
"c1_email": "it@acme.com",
"itsm_email": "it@acme.com",
"itsm_company": "acme",
"product_type": "Xcitium Dragon Enterprise",
"subdomain": "acme",
"region": "US",
"company_type": "MSP",
"is_suspended": false,
"is_open_edr": false,
"last_login_at": "2026-07-29T11:04:00",
"device_online": 900,
"products": {
"device_management": {"seats": 1250, "used": 1104, "overused": 0},
"mobile_management": {"seats": 0, "used": 0, "overused": 0},
"containment_only": {"seats": 0, "used": 0, "overused": 0},
"xcs": {"seats": 0, "used": 0, "overused": 0},
"mdr_device": {"seats": 0, "used": 0, "overused": 0},
"mdr_cloud": {"seats": 0, "used": 0, "overused": 0},
"mdr_network": {"seats": 0, "used": 0, "overused": 0}
}
}
],
"totals": {
"device_online": 903,
"products": {"device_management": {"seats": 1250, "used": 1104, "overused": 0}}
}
}
GET
/api/v1/products
List all product groups and their products
include_hidden=1 optional — include hidden product groups (default: excluded)curl -H "X-Api-Key: cam_..." https://<host>/api/v1/products
# Response
{
"ok": true,
"product_groups": [
{
"id": 90,
"name": "Endpoint Security",
"category": "Security",
"sort_order": 20,
"products": [
{"id": 5, "name": "Xcitium Advanced Endpoint Protection", "sort_order": 0}
]
}
]
}
GET
/api/v1/partners
List reseller partners with aggregate stats
q=<text> optional — partial match on org name or emailcountry=<code> optional — filter by country code (e.g. US, TR)curl -H "X-Api-Key: cam_..." "https://<host>/api/v1/partners?q=SHI&country=US"
# Response
{
"ok": true,
"total": 12,
"partners": [
{
"organization": "SHI",
"email": "partner@shi.com",
"country": "US",
"order_count": 150,
"total_tcv": 125000.00,
"total_acv": 98000.00,
"first_order_date": "2022-03-01",
"last_order_date": "2026-01-15"
}
]
}
GET
/api/v1/partners/orders
Get orders for a specific reseller partner
partner=<email or org> required — matched against reseller email or organization namefrom=YYYY-MM-DD optional — earliest sale date (inclusive)to=YYYY-MM-DD optional — latest sale date (inclusive)page=1 optional — page number, 1-based (default: 1)per_page=100 optional — rows per page, max 500 (default: 100)curl -H "X-Api-Key: cam_..." \
"https://<host>/api/v1/partners/orders?partner=partner@shi.com&from=2026-01-01&per_page=50"
# Response
{
"ok": true,
"partner": {"organization": "SHI", "email": "partner@shi.com"},
"total": 150,
"page": 1,
"per_page": 50,
"orders": [
{
"sales_order_number": "SO-12345",
"customer_order_number": "PO-99887",
"sale_date": "2026-01-15",
"end_user_organization": "Acme Corp",
"end_user_email": "it@acme.com",
"end_user_country": "US",
"product_name": "AEP",
"product_family": "AEP",
"term": "1 Year",
"endpoints": 50,
"tcv": 1500.00,
"acv": 1500.00,
"order_value": 1500.00,
"global_order_state": "Active"
}
]
}
GET
/api/v1/partners/end_customer/usage
Active device count for a reseller's end customer
partner=<email or org> required — your reseller identifier (same as /api/v1/partners/orders)end_customer=<email> required — end-user email exactly as it appears in your partner ordersas_of=YYYY-MM-DD optional — snapshot date (default: latest available)
Ownership check: the end customer must appear in at least one order under your
partner identifier. Requests for customers outside your portfolio return 404.
curl -H "X-Api-Key: cam_..." \
"https://<host>/api/v1/partners/end_customer/usage?partner=partner@shi.com&end_customer=it@acme.com"
# Response — data available
{
"ok": true,
"partner": {"organization": "SHI", "email": "partner@shi.com"},
"end_customer": "it@acme.com",
"as_of": "2026-06-28",
"device_online": 42,
"data_available": true
}
# Response — no usage data synced yet
{
"ok": true,
"partner": {"organization": "SHI", "email": "partner@shi.com"},
"end_customer": "it@acme.com",
"as_of": null,
"device_online": null,
"data_available": false
}
GET
/api/v1/partners/end_customer/direct_orders
Direct postpaid orders placed by a reseller's end customer
partner=<email or org> required — your reseller identifierend_customer=<email> required — end-user email as it appears in your partner ordersfrom=YYYY-MM-DD optional — earliest create date (inclusive)to=YYYY-MM-DD optional — latest create date (inclusive)include_refunds=1 optional — include refund rows (default: excluded)page=1 optional — page number, 1-based (default: 1)per_page=100 optional — rows per page, max 500 (default: 100)
Ownership check: the end customer must appear in at least one order under your
partner identifier. Only Postpaid direct orders are returned — prepaid orders are excluded. These are orders the customer placed directly with Xcitium, separate from orders routed through you.
curl -H "X-Api-Key: cam_..." \
"https://<host>/api/v1/partners/end_customer/direct_orders?partner=partner@shi.com&end_customer=it@acme.com&from=2026-01-01"
# Response
{
"ok": true,
"partner": {"organization": "SHI", "email": "partner@shi.com"},
"end_customer": "it@acme.com",
"total": 2,
"page": 1,
"per_page": 100,
"orders": [
{
"sales_order_number": "SO-99001",
"create_date": "2026-03-10",
"order_value": 2400.00,
"payment_status": "Fully Paid",
"payment_method": "Credit Card",
"product_name": "Xcitium Advanced Endpoint Protection",
"product_family": "AEP",
"term": "1 Year",
"endpoints": 100,
"subscription_expiration_date": "2027-03-10",
"global_order_state": "Active",
"is_refund": false
}
]
}
| Name | Prefix | Scopes | Created | Expires | Last used | Status |
|---|
No API keys yet.
NeXcitium API Keys
Credentials used for all CAM API calls (v1 and v2). Stored server-side; the secret is never sent back to the browser.
NeXcitium APIs
CAM v1 & v2 — shared credentials
New note
Expiry
Reminder
Add a task
Tasks
| # | Task | Status | Updated | Actions |
|---|
No tasks yet.