Skip to main content

Response format

Every successful response from leadx-api goes through one helper, so the envelope is the same everywhere.

Single resource​

GET /lead/:id, POST /contact, PUT /tag/:id — anything returning one document:

{
"ok": true,
"success": true,
"message": "Lead created successfully.",
"data": { "_id": "665f...", "stage": "New" }
}
FieldTypeMeaning
okbooleanAlways true on success.
successbooleanAlways true on success. Duplicate of ok; both are always sent.
messagestring | nullHuman-readable result. null when the endpoint declares no message.
dataobject | nullThe resource.

The HTTP status comes from the named response message — commonly 200, or 201 for creates.

Collection​

Every list endpoint returns the array in data alongside pagination metadata at the top level:

{
"ok": true,
"success": true,
"message": null,
"data": [ { "_id": "665f..." }, { "_id": "6660..." } ],
"totalCount": 1284,
"n": 25,
"p": 1,
"nextCursor": null,
"cursorPagination": false,
"sortBy": "createdAt",
"sortOrder": "desc"
}
FieldTypeMeaning
dataarrayThe page of documents.
totalCountnumberTotal matching the filter, ignoring pagination.
pnumber | nullPage echoed back. null when unpaginated.
nnumber | nullPage size echoed back.
nextCursorstring | nullOpaque cursor for the next page, when cursor pagination is on.
cursorPaginationbooleanWhether this response used cursor mode.
sortBy / sortOrderstringSort actually applied.

:::tip Read totalCount, not data.length data.length is the size of the page. totalCount is the size of the result set — use it to decide whether to keep paging. :::

Errors​

Errors do not use the ok/success: true envelope:

{
"status": "fail",
"success": false,
"message": "Lead not found.",
"warning": ""
}
FieldTypeMeaning
status"fail" | "error""fail" for 4xx, "error" for 5xx.
successbooleanAlways false.
messagestringWhat went wrong.
warningstringUsually empty; occasionally carries a non-fatal note.
stackstringDevelopment only — never present in production.

Detecting success reliably​

Branch on the HTTP status code, not on the body. Both shapes carry success, so body.success === true also works, but the status is what your HTTP client already gives you:

const res = await fetch(url, { headers: { apikey } });
const body = await res.json();
if (!res.ok) throw new Error(`${res.status} ${body.message}`);
return body.data;

A note on data for lists​

The single-resource and collection shapes both use data, but a collection sets it to an array and adds sibling metadata keys. Code that assumes data is an object will break on list endpoints, and vice versa. The rule is simple: GET on a collection path returns an array; everything else returns an object.

What is inside data​

The envelope is the same everywhere; the resource inside it is not. Each one is documented under Response schemas — every field, its type, whether it is required, what it defaults to, and which values an enumerated field accepts. Endpoint entries link to the schema for the resource they return.

Three things worth knowing before reading one:

  • Fields marked select: false are never in a response. They exist on the stored document and the schema page lists them, flagged, precisely so you do not go looking for them in a payload. password on a user is the obvious one.
  • A ObjectId -> Contact field is an id string, not the object — unless that endpoint populates it, in which case its entry says so and the whole nested object arrives in its place.
  • createdAt and updatedAt are present on any resource whose schema page says timestamps are maintained, even though they are not listed as fields.

An endpoint entry with no Response line is one whose payload is not a stored resource — a Facebook Graph passthrough, an aggregation, a computed report. Those are shaped by the endpoint rather than by a schema.