SMOC Public Contacts API — Integration Guide
Guide to the SMOC Public Contacts API — a read-only REST endpoint for listing contacts and aggregate counts for your company. Use it from custom integrations, sync jobs, or alongside the Zapier app.
Overview
The SMOC Public API lets third-party systems read contacts for a single company. It is hosted on Cloudflare Workers and scoped automatically to the company tied to your API key.
What it does today:
- List contacts for your company (up to 500 per request)
- Return aggregate counts of leads and customers
- Scope data automatically to the company tied to your API key
What it does not do:
- Create, update, or delete contacts
- Paginate with cursors or offsets (only a
limitcap) - Query across multiple companies with one key
The sole contacts endpoint is:
GET /api/company/mongocontact
Get your API key
All SMOC data integrations use the same Console token pattern as Zapier and MCP:
- Log in to SMOC Console.
- Go to Settings → Integrations → API (use Integrations → Zapier for Zapier-specific setup).
- Click Generate new API key.
- Copy the key immediately — it is shown once and cannot be retrieved later.
Generating a new key does not revoke existing keys. Revoke old keys from Console when you need to rotate credentials.
Each key is bound to one company. The key carries an operatorId claim equal to that company's ID. The API uses this to scope all contact data — you cannot pass a different company ID in the request.
Base URLs
| Environment | Base URL |
|---|---|
| Production | https://v2.api.smoc.ai |
| Production (alternate) | https://v2-production.api.smoc.ai |
| Staging | https://v2-staging.api.smoc.ai |
Full endpoint example:
GET https://v2.api.smoc.ai/api/company/mongocontact
Authentication
Send your API key in a custom HTTP header named token:
GET /api/company/mongocontact HTTP/1.1
Host: v2.api.smoc.ai
token: <your-api-key>
Content-Type: application/json
The API verifies the key and reads the operatorId claim to determine which company's contacts to return. You do not send a company ID in the URL or query string.
Do not use:
Authorization: Bearer …— this header is not accepted by this endpoint (despite what the Console "API Access" page may currently show). Use thetokenheader in integrations until product support for Bearer is added.- Clerk secret keys (
sk_…) or publishable keys (pk_…) — these are rejected with401 Invalid token type.
Request
Method: GET only. Other methods (e.g. POST) return 404 Not Found.
Query parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit |
integer | No | 100 |
Max contacts to return. Must be 1–500. |
sortByField |
string | No | (none) | Sort contacts descending by this field. |
Allowed sortByField values:
| Value | Sorts by |
|---|---|
createdAt |
Contact creation date |
updatedAt |
Last update date |
lastConversationDate |
Last conversation date |
companyUsers.lastConversationDate |
Legacy alias for lastConversationDate (Zapier compatibility) |
Sort is always descending (newest/highest first). If omitted, MongoDB's natural order is used.
Response
Success (200 OK)
{
"data": [ /* array of contact objects */ ],
"leadsCount": 42,
"customerCount": 18
}
| Field | Type | Description |
|---|---|---|
data |
array | Contact records for your company |
leadsCount |
number | Contacts with status "1" or null |
customerCount |
number | Contacts with status "2" |
leadsCount and customerCount reflect all contacts for the company, not just the current page.
Contact object fields
Each item in data includes only the fields below (sensitive/internal fields are excluded):
| Field | Description |
|---|---|
id |
Unique contact record ID (MongoDB _id, exposed as id for Zapier compatibility) |
userId |
User identifier |
email |
Email address |
firstName |
First name |
lastName |
Last name |
msisdn |
Phone number |
company |
Company name (contact's employer, if captured) |
city, state, street, zip |
Address fields |
status |
Contact lifecycle status (see below) |
brandId |
Brand identifier |
operatorId |
Company/operator identifier |
createdAt |
ISO-8601 creation timestamp |
updatedAt |
ISO-8601 last update timestamp |
lastConversationDate |
ISO-8601 date of last conversation |
acceptedCommunication |
Whether the contact accepted communication |
acceptedPrivacy |
Whether the contact accepted privacy terms |
inviterUser |
Who referred this contact (object) |
rewardFlows |
Flows where rewards were earned |
promosPresented |
Promotions shown to the contact |
promosRedeemed |
Promotions redeemed |
answeredSurveyQuestions |
Survey responses |
usersReferred |
Users this contact referred |
referralLinks |
Referral link details |
visitList |
Visit/session history (device, UTM, geo, etc.) |
textFields |
Custom text fields captured in flows |
Fields may be null or absent if not collected for that contact.
Contact status values
| Status | Meaning |
|---|---|
"1" |
Lead |
"2" |
Customer |
"3" |
Lost |
"4" |
Converted |
null |
Treated as Lead in counts |
Nested object shapes
inviterUser
{
"id": 123,
"firstName": "Jane",
"lastName": "Doe",
"email": "[email protected]"
}
rewardFlows / promos
{ "id": "...", "title": "Summer promo" }
referralLinks
{
"key": "...",
"campaignId": 1,
"campaignName": "...",
"flowVariantId": 1,
"url": "https://...",
"share": true
}
visitList — includes browser, os, deviceType, country, region, city, UTM fields (utmSource, utmMedium, utmCampaign, etc.), referrer, landingPage, userAgent, ip.
answeredSurveyQuestions — includes question/answer text, translations, reward info, and timestamps.
textFields — custom flow fields: flowId, flowName, variantId, variantName, key, value.
Error responses
All errors return JSON with an error field. Some include a hint.
| HTTP status | Condition | Example body |
|---|---|---|
401 |
Missing token header |
{ "error": "Missing token header" } |
401 |
Invalid/revoked key, or sk_/pk_ key used |
{ "error": "Invalid or revoked token", "hint": "You can create a valid token from the Integration Dashboard." } |
403 |
Valid key but no operatorId claim |
{ "error": "Unauthorized" } |
422 |
limit > 500 |
{ "error": "limit must not exceed 500" } |
422 |
Invalid sortByField |
{ "error": "Invalid sortByField value" } |
404 |
Wrong path or method | Not Found (plain text) |
Example requests
Basic — fetch up to 100 contacts:
curl -s \
-H "token: YOUR_API_KEY" \
"https://v2.api.smoc.ai/api/company/mongocontact"
Fetch 25 contacts, sorted by last conversation:
curl -s \
-H "token: YOUR_API_KEY" \
"https://v2.api.smoc.ai/api/company/mongocontact?limit=25&sortByField=lastConversationDate"
Example truncated response:
{
"data": [
{
"id": "665a1b2c3d4e5f6789012345",
"email": "[email protected]",
"firstName": "Alex",
"lastName": "Smith",
"msisdn": "+4712345678",
"status": "2",
"operatorId": "10",
"createdAt": "2025-03-15T10:22:00.000Z",
"lastConversationDate": "2025-06-01T14:30:00.000Z",
"visitList": [
{
"deviceType": "mobile",
"browser": "Chrome",
"country": "NO",
"utmSource": "google"
}
]
}
],
"leadsCount": 120,
"customerCount": 45
}
Zapier integration
SMOC provides a Zapier app that uses this same endpoint. Typical flow:
- Get access via the Zapier invite link (linked from Console → Settings → Integrations → Zapier).
- Generate an API key in Console.
- In Zapier: My Apps → Custom Integrations → Add Connection and paste the key when prompted for a token.
- Create a Zap with trigger SMOC → New Contact.
The Zapier trigger polls this endpoint and treats returned contacts as new when they appear. See the Zapier eGuide for step-by-step setup.
Limitations and design notes
- Read-only — no write endpoints on the public API today.
- No offset/cursor pagination — use
limit(max 500). To sync all contacts, sort consistently and track seen IDs client-side, or use Zapier's polling model. - Automatic scoping — the API key determines the company; there is no multi-tenant override parameter.
- Projection-limited fields — only the fields listed above are returned; internal database fields are stripped.
- Legacy compatibility — the endpoint path and
companyUsers.lastConversationDatesort alias exist for backward compatibility with the original API and Zapier app.
Related: MCP (AI clients)
The same API worker also exposes an MCP endpoint at https://v2.api.smoc.ai/mcp with richer contact tools (contacts_search, contacts_get, contacts_get_stats, etc.) for AI agents — not typical REST integrations. It uses Bearer token auth and the MCP protocol. See the MCP eGuide.
For a product overview of all integration paths, see smoc.ai/integrations.
Quick reference
| Item | Value |
|---|---|
| Endpoint | GET /api/company/mongocontact |
| Auth header | token: <api-key> |
| Content type | application/json |
| Max page size | 500 |
| Default page size | 100 |
| Company scope | From API key (operatorId claim) |
| Key creation | Console → Settings → Integrations → API |
Stay close to the shift in AI sales
Get product updates and perspective on proactive AI agents, multichannel orchestration, and conversion—without the noise.


