/v1/me— Check a keyReturns the workspace, the key's name and scopes, and the user it acts as.
Connect your ERP, website, BI tool or any other system to MetriCRM. Every endpoint below is generated from the same rules the app uses, so what you can do through the API always matches what the key's owner can do in MetriCRM.
Endpoint and field descriptions are in English.
Create a key in Settings → API keys and send it as a bearer token. Keys look like mck_your-workspace_…, act as the person who created them and only reach the resources in their scopes. Use api.metricrm.com/v1 or your workspace address followed by /api/v1.
curl https://api.metricrm.com/v1/me \
-H "Authorization: Bearer mck_your-workspace_…"Lists return up to 100 records per page with a nextCursor; pass it back as cursor to get the next page. Sort by createdAt or updatedAt in either order, and use updatedSince to sync only what changed.
curl "https://api.metricrm.com/v1/contacts?limit=50&updatedSince=2026-10-01T00:00:00Z&order=asc&sort=updatedAt"
# → { "data": [ … ], "nextCursor": "WyIyMDI2LTEwLTEz…" }
curl "https://api.metricrm.com/v1/contacts?limit=50&cursor=WyIyMDI2LTEwLTEz…"Errors use normal HTTP status codes and one JSON shape: a code you can program against, a readable message and, for invalid input, the fields to fix. 401 means the key is missing or no longer valid; 403 means its scopes, its owner's role or its IP allowlist do not allow the call; 404 also covers records the key cannot see.
HTTP/1.1 400 Bad Request
{ "error": { "code": "invalid_request",
"message": "Some fields are missing or invalid.",
"details": [ { "path": "email", "message": "Invalid email address" } ] } }Each key has its own limit per minute (600 by default, set when you create the key). Every response tells you where you stand; when you reach the limit, wait for the number of seconds in Retry-After.
HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 600
RateLimit-Remaining: 0
RateLimit-Reset: 42
Retry-After: 42Send an Idempotency-Key header with POST requests. If the network fails and you retry with the same key and body within 24 hours, you get the first response back instead of a duplicate record.
curl https://api.metricrm.com/v1/contacts \
-H "Authorization: Bearer $METRICRM_API_KEY" \
-H "Idempotency-Key: 6f1c2a9e-0b6d-4c1e-9a55-2f1d0e7b3c11" \
-H "Content-Type: application/json" \
-d '{"firstName":"Aisyah","lastName":"Rahman","email":"aisyah@sinar.my"}'Settings → Webhooks sends events (case.created, invoice.paid …) to your HTTPS endpoint as JSON. Each request is signed following Standard Webhooks: verify webhook-signature with your endpoint's whsec_ secret, reject old timestamps and use webhook-id to ignore repeats. Answer with any 2xx status; anything else is retried for about 3½ days.
// Node.js: verify a MetriCRM webhook (Standard Webhooks)
import { createHmac, timingSafeEqual } from "node:crypto";
function verify(secret, headers, rawBody) {
const id = headers["webhook-id"], ts = headers["webhook-timestamp"];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false; // too old
const key = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const expected = createHmac("sha256", key).update(`${id}.${ts}.${rawBody}`).digest();
return headers["webhook-signature"].split(" ").some((s) => {
const sig = Buffer.from(s.split(",")[1] ?? "", "base64");
return sig.length === expected.length && timingSafeEqual(sig, expected);
});
}
// Body: { "type": "case.created", "timestamp": "…",
// "data": { "id": "…", "entityType": "case", "object": { … }, "changes": { … } } }Check which key and workspace you are using.
curl "https://api.metricrm.com/v1/me?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/me— Check a keyReturns the workspace, the key's name and scopes, and the user it acts as.
Companies you do business with.
curl "https://api.metricrm.com/v1/accounts?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/accounts— List accountsCompanies you do business with. Requires the `accounts:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| ownerId | string (uuid) | Only accounts owned by this user. |
| teamId | string (uuid) | Only accounts of this team. |
| parentId | string (uuid) | Only child accounts of this account. |
| string | Exact email address (lower case). | |
| tier | string | Exact tier. |
/v1/accounts— Create an accountRequires the `accounts:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| namerequired | string | |
| legalName | string | null | |
| registrationNo | string | null | |
| industry | string | null | |
| website | string | null | |
| string (email) | null | "" | ||
| phone | string | null | |
| address | object | null | |
| tier | string | null | |
| parentId | string (uuid) | null | |
| ownerId | string (uuid) | null | |
| backupOwnerId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| tags | string[] | |
| custom | object |
/v1/accounts/{id}— Get one recordRequires the `accounts:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/accounts/{id}— Update an accountRequires the `accounts:write` scope.
| idrequired | string (uuid) | Record id. |
| name | string | |
| legalName | string | null | |
| registrationNo | string | null | |
| industry | string | null | |
| website | string | null | |
| string (email) | null | "" | ||
| phone | string | null | |
| address | object | null | |
| tier | string | null | |
| parentId | string (uuid) | null | |
| ownerId | string (uuid) | null | |
| backupOwnerId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| tags | string[] | |
| custom | object |
/v1/accounts/{id}— Move an account to the recycle binRequires the `accounts:write` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | null | |
| namerequired | string | |
| legalNamerequired | string | null | |
| registrationNorequired | string | null | |
| industryrequired | string | null | |
| websiterequired | string | null | |
| emailrequired | string | null | |
| phonerequired | string | null | |
| addressrequired | object | null | |
| tierrequired | string | null | |
| parentIdrequired | string (uuid) | null | |
| ownerIdrequired | string (uuid) | null | |
| teamIdrequired | string (uuid) | null | |
| tagsrequired | string[] | |
| customrequired | object | Custom field values by field key. |
| lastActivityAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
People at your customers.
curl "https://api.metricrm.com/v1/contacts?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/contacts— List contactsPeople at your customers. Requires the `contacts:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| accountId | string (uuid) | Only contacts whose primary account is this. |
| ownerId | string (uuid) | Only contacts owned by this user. |
| string | Exact email address (lower case). | |
| mobile | string | Exact mobile number in E.164 (+60…). |
/v1/contacts— Create a contactRequires the `contacts:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| firstName | string | null | |
| lastName | string | null | |
| fullName | string | null | |
| string (email) | null | "" | ||
| mobile | string | null | |
| office | string | null | |
| home | string | null | |
| title | string | null | |
| department | string | null | |
| locale | "en" | "ms" | "zh-CN" | null | |
| ownerId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| tags | string[] | |
| custom | object | |
| accountId | string (uuid) | null | |
| accountRole | string | null |
/v1/contacts/{id}— Get one recordRequires the `contacts:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/contacts/{id}— Update a contactRequires the `contacts:write` scope.
| idrequired | string (uuid) | Record id. |
| firstName | string | null | |
| lastName | string | null | |
| fullName | string | null | |
| string (email) | null | "" | ||
| mobile | string | null | |
| office | string | null | |
| home | string | null | |
| title | string | null | |
| department | string | null | |
| locale | "en" | "ms" | "zh-CN" | null | |
| ownerId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| tags | string[] | |
| custom | object |
/v1/contacts/{id}— Move a contact to the recycle binRequires the `contacts:write` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | null | |
| firstNamerequired | string | null | |
| lastNamerequired | string | null | |
| fullNamerequired | string | |
| emailrequired | string | null | |
| mobilerequired | string | null | |
| officerequired | string | null | |
| homerequired | string | null | |
| titlerequired | string | null | |
| departmentrequired | string | null | |
| localerequired | string | null | |
| primaryAccountIdrequired | string (uuid) | null | |
| ownerIdrequired | string (uuid) | null | |
| teamIdrequired | string (uuid) | null | |
| tagsrequired | string[] | |
| customrequired | object | Custom field values by field key. |
| lastActivityAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Customer service cases (MetriCare). New cases are routed like any other case.
curl "https://api.metricrm.com/v1/cases?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/cases— List casesCustomer service cases (MetriCare). New cases are routed like any other case. Requires the `cases:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | string | Exact status key. |
| priority | string | Exact priority key. |
| accountId | string (uuid) | Only cases of this account. |
| contactId | string (uuid) | Only cases of this contact. |
| assigneeId | string (uuid) | Only cases assigned to this user. |
| teamId | string (uuid) | Only cases of this team. |
/v1/cases— Create a caseRequires the `cases:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| subjectrequired | string | |
| description | string | |
| categoryId | string (uuid) | null | |
| subCategoryId | string (uuid) | null | |
| priority | string | null | |
| status | string | null | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| assigneeId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| tags | string[] | |
| custom | object |
/v1/cases/{id}— Get one recordRequires the `cases:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/cases/{id}— Update a caseRequires the `cases:write` scope.
| idrequired | string (uuid) | Record id. |
| subject | string | |
| description | string | |
| categoryId | string (uuid) | null | |
| subCategoryId | string (uuid) | null | |
| priority | string | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| tags | string[] | |
| custom | object | |
| resolution | string | null |
/v1/cases/{id}— Delete a caseRequires the `cases:write` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | |
| subjectrequired | string | |
| descriptionrequired | string | |
| channelrequired | string | |
| categoryIdrequired | string (uuid) | null | |
| subCategoryIdrequired | string (uuid) | null | |
| priorityrequired | string | |
| statusrequired | string | |
| statusCategoryrequired | string | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| assigneeIdrequired | string (uuid) | null | |
| teamIdrequired | string (uuid) | null | |
| tagsrequired | string[] | |
| customrequired | object | Custom field values by field key. |
| resolutionrequired | string | null | |
| languagerequired | string | null | |
| firstResponseDueAtrequired | string (date-time) | null | |
| resolutionDueAtrequired | string (date-time) | null | |
| firstRespondedAtrequired | string (date-time) | null | |
| slaStaterequired | string | |
| resolvedAtrequired | string (date-time) | null | |
| closedAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Replies and internal notes on cases. A public comment is emailed to the case contact.
curl "https://api.metricrm.com/v1/comments?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/comments— List case commentsReplies and internal notes on cases. A public comment is emailed to the case contact. Requires the `cases:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| caseId | string (uuid) | Only comments on this case. |
| kind | "public" | "internal" | Public replies or notes. |
/v1/comments— Add a reply or internal note to a caseRequires the `cases:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| caseIdrequired | string (uuid) | |
| kindrequired | "public" | "internal" | |
| htmlrequired | string | HTML body (sanitised). |
/v1/comments/{id}— Get one recordRequires the `cases:read` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| caseIdrequired | string (uuid) | |
| kindrequired | "public" | "internal" | |
| authorTyperequired | string | |
| authorIdrequired | string (uuid) | null | |
| authorNamerequired | string | null | |
| bodyrequired | string | Sanitised HTML. |
| viarequired | string | null | |
| createdAtrequired | string (date-time) |
Prospects to qualify (MetriSales). New leads are routed to a sales rep.
curl "https://api.metricrm.com/v1/leads?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/leads— List leadsProspects to qualify (MetriSales). New leads are routed to a sales rep. Requires the `leads:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | string | Exact status. |
| ownerId | string (uuid) | Only leads owned by this user. |
| string | Exact email address (lower case). |
/v1/leads— Create a leadRequires the `leads:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| fullNamerequired | string | |
| companyName | string | null | |
| string (email) | null | "" | ||
| phone | string | null | |
| source | "web_form" | "email" | "chat" | "social" | "import" | "api" | "manual" | |
| sourceDetail | string | null | |
| ownerId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| fields | object | |
| language | string | null |
/v1/leads/{id}— Get one recordRequires the `leads:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/leads/{id}— Update a leadRequires the `leads:write` scope.
| idrequired | string (uuid) | Record id. |
| fullName | string | |
| companyName | string | null | |
| string (email) | null | "" | ||
| phone | string | null | |
| status | "new" | "contacted" | "qualifying" | |
| fields | object |
/v1/leads/{id}— Delete a leadRequires the `leads:write` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | |
| fullNamerequired | string | |
| companyNamerequired | string | null | |
| emailrequired | string | null | |
| phonerequired | string | null | |
| sourcerequired | string | |
| sourceDetailrequired | string | null | |
| statusrequired | string | |
| ownerIdrequired | string (uuid) | null | |
| teamIdrequired | string (uuid) | null | |
| fieldsrequired | object | |
| scorerequired | integer | null | |
| languagerequired | string | null | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| dealIdrequired | string (uuid) | null | |
| convertedAtrequired | string (date-time) | null | |
| disqualifiedReasonrequired | string | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Deals in your sales pipelines.
curl "https://api.metricrm.com/v1/opportunities?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/opportunities— List opportunitiesDeals in your sales pipelines. Requires the `deals:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | "open" | "won" | "lost" | Open, won or lost. |
| pipelineId | string (uuid) | Only deals in this pipeline. |
| stageKey | string | Exact stage key. |
| accountId | string (uuid) | Only deals of this account. |
| ownerId | string (uuid) | Only deals owned by this user. |
/v1/opportunities— Create an opportunityRequires the `deals:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| namerequired | string | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| pipelineId | string (uuid) | null | |
| stageKey | string | null | |
| amountSen | integer | |
| currency | string | |
| expectedCloseDate | string (date) | null | |
| ownerId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| source | string | null | |
| competitors | string[] | |
| nextStep | string | null |
/v1/opportunities/{id}— Get one recordRequires the `deals:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/opportunities/{id}— Update an opportunityRequires the `deals:write` scope.
| idrequired | string (uuid) | Record id. |
| name | string | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| amountSen | integer | |
| expectedCloseDate | string (date) | null | |
| ownerId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| source | string | null | |
| competitors | string[] | |
| nextStep | string | null |
/v1/opportunities/{id}— Delete an opportunityRequires the `deals:write` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | |
| namerequired | string | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| pipelineIdrequired | string (uuid) | null | |
| stageKeyrequired | string | |
| probabilityrequired | integer | |
| amountSenrequired | integer | Deal value in the smallest currency unit (sen for MYR). |
| currencyrequired | string | |
| expectedCloseDaterequired | string (date) | null | |
| ownerIdrequired | string (uuid) | null | |
| teamIdrequired | string (uuid) | null | |
| sourcerequired | string | null | |
| leadIdrequired | string (uuid) | null | |
| competitorsrequired | string[] | |
| nextSteprequired | string | null | |
| statusrequired | "open" | "won" | "lost" | |
| wonAtrequired | string (date-time) | null | |
| lostAtrequired | string (date-time) | null | |
| lostReasonrequired | string | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Quotations with line items, discounts and SST. Approval rules still apply.
curl "https://api.metricrm.com/v1/quotations?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/quotations— List quotationsQuotations with line items, discounts and SST. Approval rules still apply. Requires the `quotations:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | string | Exact status. |
| dealId | string (uuid) | Only quotations for this opportunity. |
| accountId | string (uuid) | Only quotations for this account. |
/v1/quotations— Create a draft quotationRequires the `quotations:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| titlerequired | string | |
| dealId | string (uuid) | null | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| priceListId | string (uuid) | null | |
| tier | string | null | |
| language | "en" | "ms" | "zh-CN" | |
| validUntil | string | null | |
| paymentTermsDays | integer | null | |
| terms | string | null | |
| notes | string | null | |
| items | object[] |
/v1/quotations/{id}— Get one recordRequires the `quotations:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/quotations/{id}— Replace a draft quotation (send every field and all line items)Requires the `quotations:write` scope.
| idrequired | string (uuid) | Record id. |
| titlerequired | string | |
| dealId | string (uuid) | null | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| priceListId | string (uuid) | null | |
| tier | string | null | |
| language | "en" | "ms" | "zh-CN" | |
| validUntil | string | null | |
| paymentTermsDays | integer | null | |
| terms | string | null | |
| notes | string | null | |
| items | object[] |
/v1/quotations/{id}— Delete a draft quotationRequires the `quotations:write` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | |
| versionrequired | integer | |
| titlerequired | string | |
| dealIdrequired | string (uuid) | null | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| ownerIdrequired | string (uuid) | null | |
| statusrequired | string | |
| currencyrequired | string | |
| languagerequired | string | |
| validUntilrequired | string (date) | null | |
| paymentTermsDaysrequired | integer | null | |
| termsrequired | string | null | |
| grossSenrequired | integer | Before discount and tax in the smallest currency unit (sen for MYR). |
| discountSenrequired | integer | Discount in the smallest currency unit (sen for MYR). |
| taxSenrequired | integer | Tax in the smallest currency unit (sen for MYR). |
| totalSenrequired | integer | Total in the smallest currency unit (sen for MYR). |
| sentAtrequired | string (date-time) | null | |
| decidedAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Sales orders, created from accepted quotations.
curl "https://api.metricrm.com/v1/orders?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/orders— List ordersSales orders, created from accepted quotations. Requires the `orders:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | string | Exact status. |
| accountId | string (uuid) | Only orders of this account. |
| quoteId | string (uuid) | Only the order for this quotation. |
/v1/orders— Create the sales order for an accepted quotationRequires the `orders:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| quoteIdrequired | string (uuid) |
/v1/orders/{id}— Get one recordRequires the `orders:read` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | |
| quoteIdrequired | string (uuid) | null | |
| dealIdrequired | string (uuid) | null | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| ownerIdrequired | string (uuid) | null | |
| titlerequired | string | |
| statusrequired | string | |
| currencyrequired | string | |
| totalSenrequired | integer | Total in the smallest currency unit (sen for MYR). |
| taxSenrequired | integer | Tax in the smallest currency unit (sen for MYR). |
| fulfilledAtrequired | string (date-time) | null | |
| cancelledAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Invoices with SST and payment status.
curl "https://api.metricrm.com/v1/invoices?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/invoices— List invoicesInvoices with SST and payment status. Requires the `invoices:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | string | Exact status. |
| accountId | string (uuid) | Only invoices of this account. |
| orderId | string (uuid) | Only invoices for this order. |
/v1/invoices— Create a draft invoiceRequires the `invoices:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| titlerequired | string | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| language | "en" | "ms" | "zh-CN" | |
| issueDate | string | null | |
| paymentTermsDays | integer | null | |
| terms | string | null | |
| notes | string | null | |
| items | object[] |
/v1/invoices/{id}— Get one recordRequires the `invoices:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/invoices/{id}— Replace a draft invoice (send every field and all line items)Requires the `invoices:write` scope.
| idrequired | string (uuid) | Record id. |
| titlerequired | string | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| language | "en" | "ms" | "zh-CN" | |
| issueDate | string | null | |
| paymentTermsDays | integer | null | |
| terms | string | null | |
| notes | string | null | |
| items | object[] |
| idrequired | string (uuid) | |
| numberrequired | string | |
| orderIdrequired | string (uuid) | null | |
| dealIdrequired | string (uuid) | null | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| ownerIdrequired | string (uuid) | null | |
| titlerequired | string | |
| statusrequired | string | |
| currencyrequired | string | |
| languagerequired | string | |
| issueDaterequired | string (date) | |
| dueDaterequired | string (date) | |
| paymentTermsDaysrequired | integer | |
| totalSenrequired | integer | Total in the smallest currency unit (sen for MYR). |
| taxSenrequired | integer | Tax in the smallest currency unit (sen for MYR). |
| paidSenrequired | integer | Paid so far in the smallest currency unit (sen for MYR). |
| sentAtrequired | string (date-time) | null | |
| paidAtrequired | string (date-time) | null | |
| voidedAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Payments recorded against invoices (bank transfer, cash, cheque, card).
curl "https://api.metricrm.com/v1/payments?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/payments— List paymentsPayments recorded against invoices (bank transfer, cash, cheque, card). Requires the `invoices:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| invoiceId | string (uuid) | Only payments for this invoice. |
/v1/payments— Record a payment against an invoiceRequires the `invoices:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| amountSenrequired | integer | |
| methodrequired | "bank_transfer" | "cash" | "cheque" | "card" | "online" | "other" | |
| reference | string | null | |
| paidOnrequired | string | |
| note | string | null | |
| invoiceIdrequired | string (uuid) |
/v1/payments/{id}— Get one recordRequires the `invoices:read` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| invoiceIdrequired | string (uuid) | |
| numberrequired | string | |
| amountSenrequired | integer | Amount in the smallest currency unit (sen for MYR). |
| methodrequired | string | |
| referencerequired | string | null | |
| paidOnrequired | string (date) | |
| noterequired | string | null | |
| sourcerequired | string | |
| voidedAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) |
Your product and service catalogue.
curl "https://api.metricrm.com/v1/products?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/products— List productsYour product and service catalogue. Requires the `products:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | "active" | "archived" | Active or archived. |
| sku | string | Exact SKU (upper case). |
/v1/products— Create a productRequires the `products:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| skurequired | string | |
| namerequired | string | |
| description | string | null | |
| unit | string | |
| priceSenrequired | integer | |
| costSen | integer | null | |
| currency | string | |
| taxCategoryId | string (uuid) | null | |
| parentId | string (uuid) | null | |
| options | object | |
| status | "active" | "archived" |
/v1/products/{id}— Get one recordRequires the `products:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/products/{id}— Replace a product (send every field)Requires the `products:write` scope.
| idrequired | string (uuid) | Record id. |
| skurequired | string | |
| namerequired | string | |
| description | string | null | |
| unit | string | |
| priceSenrequired | integer | |
| costSen | integer | null | |
| currency | string | |
| taxCategoryId | string (uuid) | null | |
| parentId | string (uuid) | null | |
| options | object | |
| status | "active" | "archived" |
| idrequired | string (uuid) | |
| skurequired | string | |
| namerequired | string | |
| descriptionrequired | string | null | |
| unitrequired | string | |
| priceSenrequired | integer | List price in the smallest currency unit (sen for MYR). |
| costSenrequired | integer | null | |
| currencyrequired | string | |
| taxCategoryIdrequired | string (uuid) | null | |
| parentIdrequired | string (uuid) | null | |
| optionsrequired | object | |
| statusrequired | "active" | "archived" | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Follow-ups with due dates and reminders.
curl "https://api.metricrm.com/v1/tasks?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/tasks— List tasksFollow-ups with due dates and reminders. Requires the `tasks:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | "open" | "done" | "cancelled" | Open, done or cancelled. |
| assigneeId | string (uuid) | Only tasks assigned to this user. |
| accountId | string (uuid) | Only tasks about this account. |
| contactId | string (uuid) | Only tasks about this contact. |
/v1/tasks— Create a taskRequires the `tasks:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| titlerequired | string | |
| description | string | null | |
| priority | "low" | "medium" | "high" | "urgent" | |
| dueAt | string (date-time) | null | |
| remindAt | string (date-time) | null | |
| assigneeId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| entityType | string | null | |
| entityId | string (uuid) | null | |
| recurrence | object | null |
/v1/tasks/{id}— Get one recordRequires the `tasks:read` scope.
| idrequired | string (uuid) | Record id. |
/v1/tasks/{id}— Update a taskRequires the `tasks:write` scope.
| idrequired | string (uuid) | Record id. |
| title | string | |
| description | string | null | |
| priority | "low" | "medium" | "high" | "urgent" | |
| dueAt | string (date-time) | null | |
| remindAt | string (date-time) | null | |
| assigneeId | string (uuid) | null | |
| teamId | string (uuid) | null | |
| entityType | string | null | |
| entityId | string (uuid) | null | |
| recurrence | object | null |
/v1/tasks/{id}— Delete a taskRequires the `tasks:write` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | null | |
| titlerequired | string | |
| descriptionrequired | string | null | |
| statusrequired | "open" | "done" | "cancelled" | |
| priorityrequired | string | |
| dueAtrequired | string (date-time) | null | |
| remindAtrequired | string (date-time) | null | |
| assigneeIdrequired | string (uuid) | null | |
| teamIdrequired | string (uuid) | null | |
| entityTyperequired | string | null | |
| entityIdrequired | string (uuid) | null | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| completedAtrequired | string (date-time) | null | |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
The timeline on accounts and contacts: calls, emails, chats, notes and more.
curl "https://api.metricrm.com/v1/activities?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/activities— List activitiesThe timeline on accounts and contacts: calls, emails, chats, notes and more. Requires the `activities:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| accountId | string (uuid) | Only activities on this account. |
| contactId | string (uuid) | Only activities on this contact. |
| kind | string | Exact kind (call, email, note …). |
/v1/activities— Log an activity (a call, meeting note or email from another system)Requires the `activities:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| kindrequired | "call" | "email" | "chat" | "note" | |
| accountId | string (uuid) | null | |
| contactId | string (uuid) | null | |
| titlerequired | string | |
| body | string | null | |
| occurredAt | string (date-time) | null |
/v1/activities/{id}— Get one recordRequires the `activities:read` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| kindrequired | string | |
| subjectTyperequired | string | |
| subjectIdrequired | string (uuid) | |
| accountIdrequired | string (uuid) | null | |
| contactIdrequired | string (uuid) | null | |
| titlerequired | string | |
| bodyrequired | string | null | Short preview (up to 500 characters). |
| actorUserIdrequired | string (uuid) | null | |
| actorTyperequired | string | |
| occurredAtrequired | string (date-time) |
Knowledge base articles with their published translations.
curl "https://api.metricrm.com/v1/articles?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/articles— List knowledge baseKnowledge base articles with their published translations. Requires the `knowledge:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | string | Exact status (published, draft …). |
| visibility | "internal" | "public" | Internal or public. |
| categoryId | string (uuid) | Only articles in this category. |
/v1/articles/{id}— Get one recordRequires the `knowledge:read` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| numberrequired | string | null | |
| categoryIdrequired | string (uuid) | null | |
| slugrequired | string | |
| visibilityrequired | "internal" | "public" | |
| statusrequired | string | |
| tagsrequired | string[] | |
| versionrequired | integer | |
| publishedAtrequired | string (date-time) | null | |
| translationsrequired | object[] | Published content per language. |
| createdAtrequired | string (date-time) | |
| updatedAtrequired | string (date-time) |
Messages in MetriChat conversations (web chat, WhatsApp, SMS and more).
curl "https://api.metricrm.com/v1/messages?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/messages— List messagesMessages in MetriChat conversations (web chat, WhatsApp, SMS and more). Requires the `messages:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| conversationId | string (uuid) | Only messages in this conversation. |
| direction | "in" | "out" | "note" | "system" | Incoming, outgoing, internal note or system. |
/v1/messages— Reply in a conversation (through its channel)Requires the `messages:write` scope.
| Idempotency-Key (header) | string | Any unique value (a UUID works). A retry with the same key and body returns the first response instead of creating a duplicate. Kept for 24 hours. |
| conversationIdrequired | string (uuid) | |
| textrequired | string |
/v1/messages/{id}— Get one recordRequires the `messages:read` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| conversationIdrequired | string (uuid) | |
| directionrequired | "in" | "out" | "note" | "system" | |
| authorrequired | "customer" | "agent" | "bot" | "system" | |
| authorUserIdrequired | string (uuid) | null | |
| bodyrequired | string | |
| statusrequired | string | null | |
| createdAtrequired | string (date-time) |
People in this workspace (read only).
curl "https://api.metricrm.com/v1/users?limit=10" \
-H "Authorization: Bearer $METRICRM_API_KEY"/v1/users— List usersPeople in this workspace (read only). Requires the `users:read` scope.
| limit | integer | Page size, 1–100 (default 25). |
| cursor | string | The nextCursor of the previous page. |
| sort | "createdAt" | "updatedAt" | Sort field (default createdAt). |
| order | "asc" | "desc" | Sort order (default desc). |
| createdSince | string (date-time) | Only records created after this time (ISO 8601). |
| updatedSince | string (date-time) | Only records changed after this time — use for incremental sync. |
| status | string | Exact status (active, invited …). |
| string | Exact email address. |
/v1/users/{id}— Get one recordRequires the `users:read` scope.
| idrequired | string (uuid) | Record id. |
| idrequired | string (uuid) | |
| emailrequired | string | |
| displayNamerequired | string | |
| titlerequired | string | null | |
| localerequired | string | null | |
| timezonerequired | string | null | |
| statusrequired | string | |
| availabilityrequired | string | |
| createdAtrequired | string (date-time) |