Portal
API Conventions

Idempotency

Duplicate request and retry guidance.

Network timeouts, client retries, and asynchronous workers are normal in messaging integrations. Idempotency keeps one business action from becoming multiple orders, charges, or delivery attempts.

Merchant request key

Single SMS send supports client_order_id as the merchant-side request reference.

Send request reference
{
  "phone_number": "+639171234567",
  "template_id": "TPL1001",
  "sender_id": "SND1001",
  "var": "FutureSMS",
  "client_order_id": "client-ord-20260325-0001"
}
FieldRule
client_order_idOptional merchant-side order reference.
Length12-128 characters after trimming.
ScopeUnique for the merchant.
PurposeLets your system correlate a FutureSMS order with your own business action.

When client_order_id is omitted, FutureSMS can still create the order, but your retry and reconciliation logic has less information to work with.

Duplicate handling

If the same merchant sends a new order with a client_order_id that already exists, the API returns a conflict response.

Duplicate client order
{
  "error_code": "CONFLICT",
  "reason": null,
  "message": "Conflict",
  "details": "client_order_id already exists for this merchant",
  "path": "/api/v1/sms/sends",
  "timestamp": "2026-03-25T10:30:05Z",
  "request_id": "req_20260325_demo_0002"
}

Treat this as a signal to reconcile, not as permission to generate a new identifier and send the same business action again.

Timeout recovery

If a write request times out after your client submitted it, do not immediately send a second business request.

Store client_order_id before sending the request. It gives your integration a stable value to reconcile after network timeouts.

Persist the reference before sending

Store your local business id and client_order_id before calling the API.

Submit the request

Send the request once. Store the returned order_id if the API responds.

Reconcile before retrying

If the client sees a timeout or connection failure, query by the identifiers available to you, such as the returned order_id or your client_order_id on a list/search endpoint.

Retry only after a decision

Retry only when your integration has confirmed that the first request was not accepted, or when your operational process intentionally creates a new business action.

Safe retry pattern

Local retry state
{
  "local_message_id": "msg_20260325_0001",
  "client_order_id": "client-ord-20260325-0001",
  "last_request_status": "timeout",
  "next_action": "query_before_retry"
}

Your system should store enough state to answer these questions:

QuestionWhy it matters
Did we already submit this business action?Prevents accidental duplicate orders.
Did FutureSMS return an order_id?Lets you query the exact platform order.
Did we receive a conflict for the same client_order_id?Usually means the first accepted request already owns that merchant reference.
Is this retry a transport retry or a new business action?Keeps operational retries separate from intentional resends.

Internal retries

FutureSMS may perform internal asynchronous retries for delivery, callback, replay, or recovery flows. Those retries are driven by durable platform state and do not require the merchant to submit the original request again.

Merchant clients should retry at the API boundary only for transport uncertainty, and should always reconcile using stored identifiers before creating a second business request.