AI reads the company
Every agent
AI crawls the site and writes the offer, the audience, the voice, and the brand. Website chat, card flows, and LinkedIn start from that.
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.
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:
What it does not do:
limit cap)This Zapier/compat contract is staying. The sole contacts endpoint for that contract is:
GET /api/company/mongocontact
Richer contact search is additive: POST /api/v2/contacts_search. Do not migrate Zapier off mongocontact.
For Console setup, authentication, and a function overview, start with the REST API connection guide.
All SMOC data integrations use the same Console token pattern as Zapier and MCP:
Generating a new key does not revoke existing keys. Issued keys are listed on the same page — revoke unused keys there 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.
| Environment | Base URL |
|---|---|
| Production | https://api.smoc.ai |
Full endpoint example:
GET https://api.smoc.ai/api/company/mongocontact
Send your API key in a custom HTTP header named token:
GET /api/company/mongocontact HTTP/1.1
Host: 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 the token header in integrations until product support for Bearer is added.sk_…) or publishable keys (pk_…) — these are rejected with 401 Invalid token type.Method: GET only. Other methods (e.g. POST) return 404 Not Found.
| 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. |
status |
string | No | (none) | Filter by contact status. status=1 is the standard lead poll, including positive message-flow smart leads. |
Allowed sortByField values:
| Value | Sorts by |
|---|---|
createdAt |
Contact creation date. When this sort is requested (and status is omitted or 1), recent late smart leads from the last 14 days are merged in and the page is re-sorted by max(createdAt, leadCapturedAt) so they appear without displacing newer web contacts. |
updatedAt |
Last update date |
lastConversationDate |
Last conversation date |
leadCapturedAt |
When the contact became a smart lead (falls back to updatedAt for historical rows) |
companyUsers.lastConversationDate |
Legacy alias for lastConversationDate (Zapier compatibility) |
Sort is always descending (newest/highest first). If omitted, MongoDB's natural order is used.
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.
Each item in data includes only the fields below (sensitive/internal fields are excluded):
| Field | Description |
|---|---|
id |
Zapier poll identity. Usually the Mongo _id. Late-converting smart leads (leadCapturedAt at least 1 hour after createdAt, and on or after 2026-09-11) use {mongoId}__sl so New Contact can fire. Use contactId for the stable Mongo id. |
contactId |
Stable Mongo _id. Does not change when id is rewritten for a late smart lead. |
linkedinUrl |
LinkedIn profile URL when present (top-level linkedinUrl or the first linkedinProfiles[].url). |
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). Positive message-flow smart leads use "1" like web-form leads. |
leadSentiment |
"positive" or "negative" when a message-flow reply was classified; omitted otherwise |
leadCapturedAt |
ISO-8601 time the contact became a positive smart lead (falls back to updatedAt when missing) |
tags |
Resolved contact tags { id, name, systemKind? }[] (includes Auto: Positive Lead / Auto: Negative Lead) |
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.
| Status | Meaning |
|---|---|
"1" |
Lead (includes positive message-flow smart leads) |
"2" |
Customer |
"3" |
Lost |
"4" |
Converted |
null |
Treated as Lead in counts |
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.
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" } |
422 |
Invalid status |
{ "error": "Invalid status value" } |
404 |
Wrong path or method | Not Found (plain text) |
Basic — fetch up to 100 contacts:
curl -s \
-H "token: YOUR_API_KEY" \
"https://api.smoc.ai/api/company/mongocontact"
Fetch 25 contacts, sorted by last conversation:
curl -s \
-H "token: YOUR_API_KEY" \
"https://api.smoc.ai/api/company/mongocontact?limit=25&sortByField=lastConversationDate"
Fetch standard leads (web-form and positive message-flow smart leads):
curl -s \
-H "token: YOUR_API_KEY" \
"https://api.smoc.ai/api/company/mongocontact?status=1&sortByField=leadCapturedAt"
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
}
SMOC provides a Zapier app that uses this same endpoint. Typical flow:
The Zapier trigger polls this endpoint and treats returned contacts as new when they appear. New Contact keys on id. Late-converting smart leads (imported prospects that later get leadCapturedAt) now receive a stable {contactId}__sl id so the existing New Contact Zap can fire once. contactId remains the Mongo id for CRM mapping. This applies to every company; only captures on or after 2026-09-11 are rewritten (temporary until a dedicated New Smart Lead trigger exists). Prefer HubSpot Create or Update Contact on email to avoid duplicates if the prospect was already synced. See the Zapier eGuide for step-by-step setup.
limit (max 500). To sync all contacts, sort consistently and track seen IDs client-side, or use Zapier's polling model.companyUsers.lastConversationDate sort alias exist for backward compatibility with the original API and Zapier app.The same API worker also exposes MCP at https://api.smoc.ai/mcp and REST v2 at POST /api/v2/{toolName} with richer contact tools (contacts_search, contacts_get, contacts_get_stats, etc.). See the MCP eGuide and the REST v2 reference.
For a product overview of all integration paths, see smoc.ai/integrations.
| 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 |
POST /api/v2/{toolName} callWhere AI runs
Website chat, card flows, and LinkedIn share one system. AI does each job below. The line under the title says where that job runs.
Every agent
AI crawls the site and writes the offer, the audience, the voice, and the brand. Website chat, card flows, and LinkedIn start from that.
Dashboard · Lead Strategy
Set your lead goal. AI simulates thousands of channel mixes, ranks them by efficiency, and shows the most cost-effective plan. Your data and constraints shape the math.
Every agent · theme on web · list on LinkedIn
AI writes the flow. Theme runs on website chat and cards. Translation runs on every agent. AI finds the prospect list on LinkedIn.
Path on every flow · web and LinkedIn split
Reinforcement learning on the flow path runs on every agent. Recommendations run on web. Right timing and reply reading run on LinkedIn.
Every agent
AI proposes a variant, uses your review on the next draft, and starts from an example that already works. You apply the change.
Get product updates and perspective on proactive AI agents, multichannel orchestration, and conversion—without the noise.
Enter your email below to get started with SMOC.AI