Intake API.
Send a contact, company, or deal from your own form or system to Mosaik with one POST request.
Intake creates one record for each request. Use it when a form, landing page, or other system needs to add a lead to Mosaik. The Intake endpoint does not change existing records. It creates new ones.
For the setup steps in Mosaik, see Connections.
Send a request
POST https://<your-portal>.example.com/rest/intakeSend the x-api-key header and a JSON body. The body holds one record object:
curl https://<your-portal>.example.com/rest/intake \
-H "x-api-key: <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"record": {
"requestId": "3f1c9a52-7d2e-4b8a-9c41-0e6f2b7d8a10",
"kind": "contact",
"firstName": "Ada",
"email": "ada@acme.example"
}
}'const response = await fetch("https://<your-portal>.example.com/rest/intake", {
method: "POST",
headers: {
"x-api-key": "<your-api-key>",
"Content-Type": "application/json",
},
body: JSON.stringify({
record: {
requestId: crypto.randomUUID(),
kind: "contact",
firstName: "Ada",
email: "ada@acme.example",
},
}),
});
const receipt = await response.json();import uuid
import requests
response = requests.post(
"https://<your-portal>.example.com/rest/intake",
headers={"x-api-key": "<your-api-key>"},
json={
"record": {
"requestId": str(uuid.uuid4()),
"kind": "contact",
"firstName": "Ada",
"email": "ada@acme.example",
}
},
)
response.raise_for_status()
receipt = response.json()Each request needs a requestId in UUID format. Use a new UUID for each submission.
Sending the same request again returns the original receipt. It does not create a second record. Reusing a requestId with different data returns an error.
Record kinds
Each record has a kind of contact, company, or deal.
| Kind | Required fields | Optional fields |
|---|---|---|
contact |
firstName, email |
lastName, title, phone, companyId |
company |
name, domain |
None |
deal |
name, companyId |
amountCents, currency, paymentType, stage, expectedCloseDate |
Notes on the fields:
emailis stored in lower case.domainkeeps only the host name. The API removes the protocol, any path, and a leadingwww.. A value without a valid host name is refused.amountCentsis an integer amount in the smallest currency unit, such as cents. It must be zero or more.currencyuses a three-letter currency code that Mosaik supports.stageaccepts an open deal stage:DEMO_BOOKED,QUALIFIED_TO_BUY,DECISION_MAKER_BOUGHT_IN, orCONTRACT_SENT.expectedCloseDateusesYYYY-MM-DD.
The API rejects any field that the table does not list. Send only the fields in the table.
Responses
A successful request returns the receipt for the record:
{
"requestId": "3f1c9a52-7d2e-4b8a-9c41-0e6f2b7d8a10",
"kind": "contact",
"recordId": "<new-record-id>",
"receivedAt": "2027-03-01T09:30:00.000Z"
}Use recordId to link to the new record. Store the requestId in your own system so you can match a receipt to a submission.
Duplicates and errors
Intake never changes an existing record. If a contact email or a company domain already belongs to an active record, the request returns an error and creates nothing. Search for the existing record first, then create a deal for it with companyId.
Limits
Each account can send 60 requests per minute. Above that limit, the API returns 429. Send submissions one at a time, or queue them, when a form can produce bursts of traffic.