Envelope structure
- When
successistrue,datacontains the endpoint-specific response payload anderrorisnull. - When
successisfalse,dataisnullanderrorcontains a machine-readablecodeand a human-readablemessage.
boolean
required
Whether the request was processed successfully. Use this as your primary branch condition — check
success before reading data or error.object | null
The response payload when
success is true. The shape of this object varies by endpoint. It is always null when success is false.object | null
The error details when
success is false. Always null when success is true.Success response
A successful response setssuccess: true, populates data with the endpoint result, and sets error to null.
data fields shown above are typical of a POST /v3/request or POST /v3/send response. Each endpoint documents its own data shape in the API Reference.
Error response
A failed response setssuccess: false, sets data to null, and populates error with a code and message.
Error response with details
A small number of error codes include anerror.details object with additional structured data. Currently, only DUPLICATE_EXTERNAL_ID returns details.
DUPLICATE_EXTERNAL_ID, read error.details.existing_otp_id and call GET /v3/otp/{otp_id} with that value to retrieve the status of the original transaction. See the Idempotency guide for the full retry pattern.
Parsing the envelope
Structure your response-handling code around thesuccess flag first, then delegate to error-specific logic based on error.code.
Special cases
Wrong OTP code is not an error
When a user submits an incorrect OTP code toPOST /v3/verify, the API does not return an error response. Instead, it returns HTTP 200 with success: true and data.verified: false. Check data.verified to determine whether verification passed.
Verify success response
A successful verification returnsdata.verified: true along with a verified_at timestamp.
Data formats
Timestamps
All timestamp fields (expires_at, verified_at) use the format YYYY-MM-DD HH:MM:SS in WIB (Western Indonesian Time, UTC+7). When storing or comparing timestamps in your own system, convert to UTC or your local timezone as needed.
WIB is UTC+7. To convert a WIB timestamp to UTC, subtract 7 hours.
OTP ID format
Every OTP transaction is assigned a uniqueotp_id with the following structure:
OTP20260807ABCD000001
OTP— fixed prefix20260807— date the OTP was created (YYYYMMDD)ABCD— 4 random uppercase letters000001— zero-padded daily counter, resets each day
otp_id string. Use it as the path parameter for GET /v3/otp/{otp_id} and as the body parameter for POST /v3/verify.
