Skip to content
campaiDeveloper
campai.com

Before mapping a campai record into your database or displaying it on a website, check what each value means. 2799 can mean a monetary amount of 27.99, and a date ending in T00:00:00.000Z can mean a calendar day rather than an appointment at midnight.

This guide applies to external API integrations and developer apps. The examples below are JSON value excerpts, not complete create or update requests. Use the linked endpoint's request schema when sending a record.

What you’ll have at the end

A checked mapping for monetary amounts, calendar dates, timestamps, IDs, and absent values before you import or display campai data.

  1. Read the field contract
  2. Keep the source value
  3. Apply the correct unit or date rule
  4. Verify the displayed result
Before you start
  • An example response from the endpoint you plan to use
  • Its request and response schemas; no write access is needed for this guide
On this page

campai monetary amounts use integers scaled by 100. For a two-decimal currency, multiply the major-unit amount by 100 when preparing a request and divide by 100 when displaying it. Keep the integer in your database and calculations.

Meaning JSON value Display amount
Twenty-seven and 99 hundredths 2799 27.99
One currency unit 100 1.00
One hundredth 1 0.01
Zero, where the field permits it 0 0.00

For example, a receipt position's unitAmount: 2799 is a unit price of 27.99. 27.99, "2799", and "27,99 €" are not the same monetary value in the API: the field expects an integer number, without formatting or a currency symbol. See Get receipt for the complete response.

The amount alone does not identify its currency. Take the currency from the relevant record or organization configuration, and format it for the reader's locale. Dividing by 100 is a unit conversion, not a currency conversion. A receipt's isNet determines whether its position amounts are net or gross; the number alone does not tell you that either.

When accepting decimal text, validate the number of fraction digits and convert the whole and fractional parts into an integer. For example, "27.99" becomes 27 × 100 + 99. Do not rely on an unchecked floating-point multiplication: decimal fractions are not always represented exactly. Decide how your application handles extra decimal places before sending the request. Respect the field's minimum, maximum, and whether zero or negative amounts are allowed.

Do not apply the money conversion to every numeric field.

Field Example Meaning
Receipt discount with discountType: "%" 1250 12.50 percent
Receipt discount with discountType: "amount" 1250 12.50 currency units
Receipt position quantity 1.5 One and a half units; no ×100 conversion
Accounting tax rate 19 19 percent; no ×100 conversion
List offset 50 Skip 50 records

The receipt discount uses a scaled value even when it represents a percentage. Its discountType is essential. Tax rates use a different convention. Always read the exact field, unit, and discriminator together rather than guessing from the name or copying a conversion from a different endpoint.

A birthdate, membership entry date, or membership exit date is a date only. It does not have a time zone or time of day. campai represents these values at midnight UTC, with hours, minutes, seconds, and milliseconds all zero.

Example

{
  "birthdate": "1994-05-17T00:00:00.000Z",
  "member": {
    "entryAt": "2026-11-04T00:00:00.000Z",
    "exitAt": null
  }
}

This member joined on November 4, 2026, wherever the reader is. The UTC suffix is the storage representation of that calendar date. It is not an instruction to shift it into the reader's local time.

Operation Correct treatment
Send a date selected as 2026-11-04 Validate the calendar date and encode 2026-11-04T00:00:00.000Z.
Store it locally Use a date column or a validated YYYY-MM-DD value.
Display the returned value Preserve its UTC year, month, and day. If using a date formatter, set its time zone to UTC.
Calculate an anniversary or next day Use calendar arithmetic, retaining the date-only representation.

Creating midnight in a local time zone and then converting it to UTC is a common mistake. Midnight in Berlin on November 4 becomes 2026-11-03T23:00:00.000Z, which is not a valid midnight-UTC date-only value. Formatting the original value in Los Angeles can similarly show the previous day. Neither operation preserves the intended date.

Validate the calendar itself as well as the format: a date parser that silently normalizes February 30 does not make it a valid birthdate. null is not January 1, 1970. Use it only where the schema permits an absent date.

Creation times, update times, and timed event occurrences represent instants. Send ISO 8601 with an explicit time zone; a UTC Z suffix is an unambiguous choice.

Example

{
  "createdAt": "2026-11-04T14:30:00.000Z"
}

This example represents 2:30 PM UTC. It is 3:30 PM in Europe/Berlin and 9:30 AM in America/New_York on that date. Here, converting to the intended display time zone is correct. Keep the instant in storage and apply the display zone separately.

Avoid zone-free strings such as 2026-11-04 14:30, localized strings such as 04.11.2026, or a Unix timestamp unless the particular field explicitly requires one. The shared date-time validator normalizes milliseconds to zero; some fields deliberately preserve them. Do not rely on subsecond precision unless the endpoint's field supports it.

For event calendars, use each event's time zone and its occurrence boundaries. Daylight-saving transitions mean a local day is not always 24 hours. Check whether an endpoint's range includes or excludes its end; a date-only field and a timestamp filter are not interchangeable. Continue with Show events on your website for a complete renderer.

Value How to handle it
Organization, mandate, and record IDs Keep the full opaque ID string. ObjectIds normally have 24 hexadecimal characters; short organization URL codes are not substitutes.
File resource IDs Keep the returned string as-is. A file resource can use a different ID format; it is not the signed download URL.
Boolean Send true or false, without quotes.
Enum Send the exact schema value, including case, such as "member". Display labels are not API values.
Array Send the required array, such as ["member"], even when it contains one value.
User filter Where userFilter is a string, JSON-encode the filter object once inside that field.

See Organization and mandate IDs, Handling user filters, and Upload and attach files for those complete workflows.

External REST JSON represents dates and IDs as strings. Hosted developer-app helpers also support runtime Date and ObjectId values in their extended serialization. Do not add $date or $oid wrappers to an ordinary REST request just because you saw them in a runtime log. Use the built-in objects guide for the hosted runtime.

These values carry different information:

Example Interpretation
"exitAt": null The field is present and has no date.
No exitAt property The response did not supply that field. Do not assume the same meaning as null.
"exitAt": "" An empty string; not a valid date.
An empty returned list No accessible records matched that request, not proof that the organization has no records.

On writes, optional means a field may be omitted, and nullable means it may explicitly be null. A field can be required and nullable at the same time. Omission, clearing, and replacing an array depend on the particular operation; do not apply a universal “missing leaves unchanged” rule. Build the documented write payload rather than posting an entire GET response back.

On reads, preserve unknown or unavailable fields. A failed page, missing field, or permission-restricted response must not silently erase previously stored data. Check list envelopes, pagination, and permissions before treating a response as a complete snapshot.

Before processing real records, run these cases through your own input, storage, and display layers:

Fixture Expected result
Amount 2799 Remains integer 2799 in storage; displays 27.99 in the chosen currency.
Amount 1 Displays 0.01, not 1.00.
Date-only November 4 Displays November 4 in both Berlin and Los Angeles.
Timestamp 2026-11-04T14:30:00.000Z Displays 3:30 PM Berlin / 9:30 AM New York, with the zone identified.
exitAt: null versus omitted exitAt Your mapping distinguishes a known empty value from an unavailable field.
Receipt discount 1250 The meaning follows discountType; no universal percentage conversion is applied to unrelated fields.

Keep the original source values alongside any formatted display values while checking the mapping. Once these cases pass, use the same rules in your integration's import and export paths.

Check your result

Money round-trip
2799 stays integer 2799 and displays 27.99; 1 displays 0.01.
Date-only across time zones
November 4 remains November 4 in Berlin and Los Angeles.
Timestamp conversion
14:30 UTC becomes 15:30 Berlin / 09:30 New York on November 4, 2026.
Missing versus null
Unavailable data does not erase a previously known value.
Continue with Make your first API request