Monochrome API Response Standard


id as its identifier. We never expose database-specific names like _id or objectId to clients. This keeps the API database-agnostic and avoids leaking implementation details. If a relationship must be expressed, it should be done using a clear name such as userId, driverId, or orderId. We never mix user_id and userId, and we never shorten IDs into unclear forms like uid.userId inside every address unless the response genuinely supports multiple users in one call.createdAt, last modification time is always updatedAt, and scheduled or future times should be explicit, such as startsAt, endsAt, or expiresAt. We never use vague names like date, time, or timestamp without context.durationMinutes, offlineMinutes, or remainingSeconds, so the unit is obvious without reading documentation.is, has, can, or should. Examples include isDefault, hasUnreadMessages, canCancel, or shouldRetry. We never use ambiguous booleans like default, active, or enabled without a prefix, because they become unclear in conditionals and logs.0 or 1, and not strings like "true".latitude and longitude. We never shorten them to lat or long, because long is ambiguous and inconsistent across platforms. A readable address should be named formattedAddress or displayAddress, not just address, unless the meaning is unambiguous.pickupLocation, dropoffLocation, or homeLocation, each containing its own latitude and longitude.title, short UI strings are named label, longer descriptions are named description, and system-generated messages should be named message. We avoid overloading one field to serve multiple purposes.addresses, drivers, items, routes, or notifications. We never use vague names like list, results, or dataList unless there is no better alternative.null. This prevents defensive coding on the client and keeps behavior consistent.count, totalCount, unreadCount, or completedTripsCount. If a number represents money, the currency should be implied by the product context or made explicit using a paired field like amount and currency.null instead of guessing or defaulting to zero.status for high-level state and represent it as a string enum, such as pending, active, completed, or cancelled. We do not mix numeric and string statuses across endpoints.status.success and is a boolean. The message is always named message and written in a friendly, human tone. The payload lives in data. Optional metadata such as pagination or totals lives in meta. Errors live in error and never share space with data._id. Booleans must read clearly (is, has, can), timestamps must be ISO strings with consistent naming, and locations must always use latitude and longitude.null, optional fields should be intentional, and defaults must not mislead.error.code for logic and a friendly message for humans. No raw errors or stack traces should ever reach the client.