Back to Home

Public API Documentation

Build with MSG4wrd.io API v5

Use the v5 API for authentication, SMS, calls, playable voice messages, private Hub synchronization, contacts, keyword webhooks, GSM modem devices, SMS campaigns, monitoring, top-ups, account limits, billing, and token QR codes.

All authenticated portal features are available to every account by default. Wallet credits and account limits govern usage.

Base URL
https://api.msg4wrd.io

Authentication

Call /api/login, then send protected requests with a Bearer token.

Message Status

0pending
1sending
2success
3failed

Response Format

Responses are JSON except authenticated audio downloads, which return audio bytes with byte-range support. Validation failures include a message and may include an errors map.

Calls and Voice Messages

  1. The Webapp is public and the Hub may stay on a private home network. The Hub initiates authenticated connections, uploads activity and polls for work; the public server does not need a Hub URL.
  2. On the Hub, enable Cloud activity and calls, bind the SIM/channel, and choose the incoming/outgoing SMS, call and voice switches. Call detection must be enabled. Incoming playable voice requires a saved voicemail/recording and a modem that supports recording.
  3. Cloud activity OFF keeps the existing SMS connection active but disables call/voice capture and remote call acceptance. Saving with it enabled, or Sync now, recovers missed call states and saved voicemail from bound channels since the worker was created; already captured events are not duplicated.
  4. Outbound SMS polling follows the Devices sender assignment. An enabled Both device owns the PH and US queues before country-specific devices. A sender_not_assigned response is a routing warning, even when HTTP is 200 and the legacy body status is 404; an empty queue has no routing warning.
  5. Conversation recording: hold the mic, speak, then release to preview. Slide left or press Escape to cancel; discard or explicitly Send the draft. HTTPS, browser microphone permission and MediaRecorder support are required. Recording stops before two minutes and is capped at 8 MiB.
  6. Send voice uploads audio to POST /api/v5/call/media, then queues POST /api/v5/call with one audio part. The Hub calls the recipient and plays the recording. POST /api/v5/inbound/reply continues to send text SMS.
  7. A queued single-audio call is immediately playable in its conversation from the uploaded source, even while the Hub is offline. The exact prepared audio replaces that source in the same entry after the Hub uploads it. Mixed text/audio calls become playable after preparation.
  8. Use preview_only:true to prepare text, audio or ordered mixed parts without dialing. Calls also provides mic recording and file upload. Review an unknown call result before creating a new request with a new idempotency key.
  9. Enable remote call acceptance for queued calls. Offline or paused workers retain captured events. Delivery retries are bounded; failed jobs are visible in the worker and can be retried. Activity uploads and audio retries do not redial a call.

Text + recording preview · POST /api/v5/call

{
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "idempotency_key": "voice-preview-001",
  "preview_only": true,
  "parts": [
    {
      "type": "text",
      "text": "Hello. Here is your recorded message."
    },
    {
      "type": "audio",
      "media_id": "22222222-2222-4222-8222-222222222222"
    }
  ]
}

POST /api/v5/send

Send SMS Status Flow

Send requests are documented separately because the API queues an outbound message first, then the sender workflow moves it through status codes.

Queue a message
curl -X POST "https://api.msg4wrd.io/api/v5/send?mobile=09171234567&message=Hello%20from%20MSG4wrd&local=0&priority=0" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"

Save the returned sent.id. That ID is the same value used for resend when the outbound message later fails.

Resend failed message
curl -X POST "https://api.msg4wrd.io/api/v5/inbound/message/125/resend" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json"
  1. 1Read messages from GET /api/v5/inbound or GET /api/v5/inbound/thread/{mobile}.
  2. 2Find a stored SMS with a positive id, type = sms, is_inbound = 0 and status = 3.
  3. 3Call POST /api/v5/inbound/message/{id}/resend using that message ID.
  4. 4A successful resend resets the same message to status 0 pending and returns the updated sent object.
0Pending

The API accepted the request, charged the wallet, created the outbound SMS row, and returned the message ID in sent.id.

Store sent.id. The gateway/device worker picks up pending outbound messages for delivery.

1Sending

The message is actively being processed by the sender workflow.

Do not resend yet. Continue reading the thread or inbound list until the status moves to success or failed.

2Success

The outbound SMS was marked as delivered/sent by the processing workflow.

No resend action is needed.

3Failed

The outbound SMS failed and is eligible for API resend if it belongs to the authenticated account.

Call POST /api/v5/inbound/message/{id}/resend with the failed outbound message ID.

Endpoint Catalog

API v5 Routes

Open portal docs

Base

Authentication bootstrap and session/token management.

4 endpoints
POST/api/login

Authenticate with email/password and receive a bearer token.

Public
Parameteremail
Typestring
Requiredrequired
DescriptionRegistered email address.
Parameterpassword
Typestring
Requiredrequired
DescriptionAccount password.

JSON Response Example

{
  "token": "1|abc123...",
  "user": {
    "id": 1,
    "firstname": "Juan",
    "lastname": "Dela Cruz",
    "email": "[email protected]"
  }
}
POST/api/v5/logout

End the current session without revoking the persisted API token.

Auth

JSON Response Example

204 No Content
POST/api/v5/tokens/create

Regenerate the account API token and invalidate previous tokens.

Auth

JSON Response Example

{
  "token": "2|xyz789..."
}
GET/api/v5/tokens/qr-code

Return a QR code data URI for the active API token.

Auth

JSON Response Example

{
  "qr_code": "data:image/svg+xml;base64,PHN2Zy...",
  "mime_type": "image/svg+xml"
}

Account

Account wallet, usage, and device and outbound SMS limit metadata.

1 endpoints
GET/api/v5/account

Retrieve wallet, account limits and usage, keyword usage, and active API token details.

Auth

JSON Response Example

{
  "wallets": {
    "balance": 150.00
  },
  "limits": {
    "device_limit": 1,
    "devices_used": 0,
    "devices_remaining": 1,
    "sms_daily_limit": 200,
    "sms_sent_today": 0,
    "sms_remaining_today": 200,
    "sms_monthly_limit": 3000,
    "sms_sent_this_month": 0,
    "sms_remaining_this_month": 3000
  },
  "total_keyword_used": 3,
  "authToken": "1|abc123...",
  "realtime_channel": "account-realtime-channel"
}

Send SMS

Outbound SMS queueing, status tracking, and failed-message resend behavior.

1 endpoints
POST/api/v5/send

Queue an outbound SMS message using query parameters.

Auth
Parametermobile
Typestring
Requiredrequired
DescriptionRecipient mobile number query parameter.
Parametermessage
Typestring
Requiredrequired
DescriptionSMS body query parameter, maximum 160 characters.
Parameterlocal
Typeinteger
Requiredoptional
DescriptionCountry routing flag query parameter. Use 0 for PH (default) or 1 for US.
Parametersendername
Typestring
Requiredoptional
DescriptionSender name query parameter. Defaults to default; custom sender names follow the same queue behavior as /api/v2/sms.
Parameterpriority
Typeinteger
Requiredoptional
DescriptionPriority query parameter. Use 0 for normal priority (default) or 1 for high priority.

JSON Response Example

{
  "message": "Message queued successfully.",
  "charged": 1,
  "sent": {
    "id": 124,
    "mobile": "09171234567",
    "normalized_mobile": "+639171234567",
    "content": "Hello",
    "sender": "default",
    "is_inbound": 0,
    "local": 0,
    "priority": 0,
    "status": 0,
    "created_at": "2026-05-09T10:01:00.000000Z"
  }
}

Calls and Voice

Public call queue, private Hub execution, text-to-speech, audio uploads and authenticated playback.

12 endpoints
POST/api/v5/call

Queue a call on your Hub. The Hub converts text to speech and combines ordered text/audio parts into one message. It uploads prepared audio before dialing. Keep the same idempotency key and request body when retrying: new jobs return 202, identical requests 200, and a changed request with the same key 409. preview_only prepares audio without dialing.

Auth
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionEnabled registered Hub owned by the authenticated account; maximum 100 characters.
Parameteridempotency_key
Typestring
Requiredrequired
DescriptionUnique account-scoped request key, maximum 200 characters. Use a new key for a deliberate new call.
Parametermobile
Typestring
Requiredoptional
DescriptionPH or US number covered by the selected Hub; required unless preview_only is true.
Parameterparts
Typearray
Requiredrequired
Description1–8 ordered parts. Text: {type: "text", text: "message"}, nonblank and up to 300 characters each. Audio: {type: "audio", media_id: "owned upload UUID"}. Complete rendered audio must fit the modem and be at most 120 seconds.
Parametervoice
Typestring
Requiredoptional
DescriptionOptional configured Hub TTS voice ID, maximum 100 characters.
Parameterpreview_only
Typeboolean
Requiredoptional
DescriptionDefault false. True prepares a playable preview and allows mobile to be omitted.
Parameterscheduled_at
Typetimestamp
Requiredoptional
DescriptionInclude a timezone offset. Default: now.
Parameterexpires_at
Typetimestamp
Requiredoptional
DescriptionMust be after scheduled_at. Default: 24 hours after the scheduled time.

Request Example

{
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "idempotency_key": "voice-reply-001",
  "mobile": "+639171234567",
  "parts": [
    {
      "type": "audio",
      "media_id": "22222222-2222-4222-8222-222222222222"
    }
  ]
}

JSON Response Example

{
  "id": "11111111-1111-4111-8111-111111111111",
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "mobile": "+639171234567",
  "idempotency_key": "voice-reply-001",
  "parts": [
    {
      "type": "audio",
      "media_id": "22222222-2222-4222-8222-222222222222"
    }
  ],
  "status": "queued",
  "direction": "out",
  "type": "call",
  "preview_only": false,
  "cancel_requested": false,
  "audio_url": null,
  "seconds": 0,
  "scheduled_at": "2026-10-04T01:00:00.000000Z",
  "expires_at": "2026-10-05T01:00:00.000000Z"
}
GET/api/v5/call

Paginated incoming and outgoing calls, newest first, with owned Hub presence. Preview-only jobs are omitted from this list; read them by ID. Unknown callers remain in Calls rather than being merged into a phone conversation. Read call details for any associated incoming voicemail.

Auth
Parameterdirection
Typestring
Requiredoptional
Descriptionin or out.
Parameterstatus
Typestring
Requiredoptional
DescriptionExact call status, for example queued, answered, completed, missed or unknown.
Parameterdevice_uid
Typestring
Requiredoptional
DescriptionFilter by registered Hub.
Parametersearch
Typestring
Requiredoptional
DescriptionSearch by phone number.
Parameterfrom
Typedate
Requiredoptional
DescriptionInclude calls from the start of this date.
Parameterto
Typedate
Requiredoptional
DescriptionInclude calls through the end of this date.
Parameterpage
Typeinteger
Requiredoptional
DescriptionDefault 1; 20 calls per page.

JSON Response Example

{
  "data": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "device_uid": "YOUR_HUB_DEVICE_UID",
      "mobile": "+639171234567",
      "idempotency_key": "voice-reply-001",
      "parts": [
        {
          "type": "audio",
          "media_id": "22222222-2222-4222-8222-222222222222"
        }
      ],
      "status": "queued",
      "direction": "out",
      "type": "call",
      "preview_only": false,
      "cancel_requested": false,
      "audio_url": null,
      "seconds": 0,
      "scheduled_at": "2026-10-04T01:00:00.000000Z",
      "expires_at": "2026-10-05T01:00:00.000000Z"
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 20,
  "total": 1,
  "hubs": [
    {
      "device_uid": "YOUR_HUB_DEVICE_UID",
      "name": "Home Hub",
      "sender_country": "ph",
      "online": true,
      "last_seen_at": "2026-10-04T01:00:00.000000Z",
      "capabilities": {
        "accept_calls": true
      }
    }
  ]
}
GET/api/v5/call/{id}

Owned job or incoming call details, parts, timestamps, current state and authenticated audio_url. Jobs use UUIDs; local call log entries use activity-N. An incoming call has playable audio only when a saved recording exists. Prepared audio becomes available after the Hub uploads it.

Auth
Parameterid
Typestring
Requiredrequired
DescriptionJob UUID or activity-N in the URL path.

JSON Response Example

{
  "id": "11111111-1111-4111-8111-111111111111",
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "mobile": "+639171234567",
  "idempotency_key": "voice-reply-001",
  "parts": [
    {
      "type": "audio",
      "media_id": "22222222-2222-4222-8222-222222222222"
    }
  ],
  "status": "ready",
  "direction": "out",
  "type": "call",
  "preview_only": false,
  "cancel_requested": false,
  "audio_url": "/api/v5/call/media/22222222-2222-4222-8222-222222222222/audio",
  "seconds": 12,
  "scheduled_at": "2026-10-04T01:00:00.000000Z",
  "expires_at": "2026-10-05T01:00:00.000000Z"
}
POST/api/v5/call/{id}/cancel

Cancel a queued job immediately or request cancellation during preparation/calling. The Hub retrieves cancellation through heartbeat. A terminal job returns 409. Incoming activity-N entries are log records and cannot be cancelled through this route.

Auth
Parameterid
TypeUUID
Requiredrequired
DescriptionOwned call job UUID in the URL path.

JSON Response Example

{
  "id": "11111111-1111-4111-8111-111111111111",
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "mobile": "+639171234567",
  "idempotency_key": "voice-reply-001",
  "parts": [
    {
      "type": "audio",
      "media_id": "22222222-2222-4222-8222-222222222222"
    }
  ],
  "status": "cancelled",
  "direction": "out",
  "type": "call",
  "preview_only": false,
  "cancel_requested": true,
  "audio_url": null,
  "seconds": 0,
  "scheduled_at": "2026-10-04T01:00:00.000000Z",
  "expires_at": "2026-10-05T01:00:00.000000Z"
}
POST/api/v5/call/media

Upload a browser recording or audio file using multipart/form-data. Returns a private media UUID and owner-only audio_url (201). Reference the UUID in an audio part. Non-PCM formats require FFmpeg on the Hub.

Auth
Parameteraudio
Typefile
Requiredrequired
DescriptionMultipart audio file, up to 8 MiB. WAV, MP3, M4A, Ogg, WebM, AAC or AMR. Let the client set the multipart boundary.
Parameterseconds
Typenumber
Requiredoptional
DescriptionRecording duration, 0–120 seconds. The Hub validates the actual rendered duration before dialing.

Request Example

curl -X POST "https://api.msg4wrd.io/api/v5/call/media" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json" \
  -F "[email protected]" \
  -F "seconds=12"

JSON Response Example

{
  "id": "22222222-2222-4222-8222-222222222222",
  "audio_url": "/api/v5/call/media/22222222-2222-4222-8222-222222222222/audio"
}
GET/api/v5/call/media/{id}/audio

Authenticated audio bytes, with byte-range support for playback and seeking (200 or 206). This response is binary audio. Use a Range header such as bytes=0-1023 for partial playback. The portal streams through its authenticated session; never place a bearer token in a public audio URL.

Auth
Parameterid
TypeUUID
Requiredrequired
DescriptionOwned private media UUID in the URL path.
POST/api/v5/call/queue/claim

Hub protocol: claim one due job. Returns job:null if nothing is available, otherwise a preparing job, claim_token and audio-part download URLs. The lease lasts 10 minutes and heartbeat renews it. Started calls are never automatically reassigned or redialed.

Auth
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionEnabled registered Hub owned by the authenticated account; maximum 100 characters.
Parametercountries
Typearray
Requiredrequired
Description1–2 country flags covered by this Hub: 0=PH, 1=US.

Request Example

{
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "countries": [
    0,
    1
  ]
}

JSON Response Example

{
  "job": null
}
POST/api/v5/call/heartbeat

Hub protocol: report presence/capabilities, renew active owned claims and retrieve cancellation IDs. Stale started calls become unknown. Review an unknown outcome before creating a deliberate new call.

Auth
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionEnabled registered Hub owned by the authenticated account; maximum 100 characters.
Parametercapabilities
Typeobject
Requiredoptional
DescriptionHub capability snapshot, including accept_calls.
Parameteractive
Typearray
Requiredoptional
DescriptionUp to 50 {id: job UUID, claim_token: current token} records.

Request Example

{
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "capabilities": {
    "accept_calls": true
  },
  "active": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "claim_token": "CURRENT_CLAIM_TOKEN"
    }
  ]
}

JSON Response Example

{
  "cancelled": [
    "11111111-1111-4111-8111-111111111111"
  ]
}
POST/api/v5/call/events

Hub protocol: post incoming/outgoing call snapshots or fenced job progress. Older versions cannot overwrite newer snapshots. Before dialing a job, upload its prepared audio, report ready, then report dialing and require an explicit authorized:true response. A successful HTTP response alone does not authorize dialing. Completion of a call requires answer confirmation.

Auth
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionEnabled registered Hub owned by the authenticated account; maximum 100 characters.
Parameterlocal_id
Typestring
Requiredrequired
DescriptionStable Hub-local call/automation ID, maximum 100 characters.
Parametermobile
Typestring
Requiredoptional
DescriptionCaller/recipient. Omit for a private or unknown caller.
Parameterdirection
Typestring
Requiredrequired
Descriptionin or out.
Parameterstatus
Typestring
Requiredrequired
Descriptionqueued, preparing, ready, dialing, ringing, answered, playing, completed, busy, no_answer, declined, failed, unknown, cancelled or expired. Local snapshots also accept ended, missed and rejected.
Parameterversion
Typeinteger
Requiredrequired
DescriptionPositive, increasing snapshot version; retries retain the same version and payload.
Parameteroccurred_at
Typetimestamp
Requiredrequired
DescriptionOriginal event time with timezone offset.
Parametercall_job_id
TypeUUID
Requiredoptional
DescriptionPublic job UUID for progress reports; omit for a local call snapshot.
Parameterclaim_token
Typestring
Requiredoptional
DescriptionRequired for call_job_id progress; use the current owned claim token.
Parameterseconds
Typenumber
Requiredoptional
DescriptionCall duration, 0–86400 seconds; default 0.
Parameterbody
Typestring
Requiredoptional
DescriptionCall detail, maximum 4000 characters.
Parameterchannel_name
Typestring
Requiredoptional
DescriptionHub channel label, maximum 100 characters.
Parametersim_number
Typestring
Requiredoptional
DescriptionSIM phone number, maximum 64 characters.
Parameterstarted_at
Typetimestamp
Requiredoptional
DescriptionOriginal call start time; nullable.
Parameteranswered_at
Typetimestamp
Requiredoptional
DescriptionOriginal answer time; nullable.
Parameterended_at
Typetimestamp
Requiredoptional
DescriptionOriginal call end time; nullable.

Request Example

{
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "local_id": "hub-call-001",
  "mobile": "+639171234567",
  "direction": "in",
  "status": "ended",
  "version": 3,
  "occurred_at": "2026-10-04T01:01:00Z",
  "started_at": "2026-10-04T01:00:30Z",
  "answered_at": "2026-10-04T01:00:42Z",
  "ended_at": "2026-10-04T01:01:00Z",
  "seconds": 18,
  "channel_name": "Home SIM"
}

JSON Response Example

{
  "accepted": true,
  "authorized": false,
  "cancel_requested": false
}
POST/api/v5/call/{id}/voice

Hub protocol: upload the exact prepared audio for a currently claimed job using multipart/form-data, before ready/dialing. Returns its private media ID (201; 200 for identical audio). Changing saved audio or using a stale claim returns 409.

Auth
Parameterid
TypeUUID
Requiredrequired
DescriptionClaimed public job UUID in the URL path.
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionEnabled registered Hub owned by the authenticated account; maximum 100 characters.
Parameterclaim_token
Typestring
Requiredrequired
DescriptionCurrent claim token returned to this Hub; stale or foreign claims return 409.
Parameteraudio
Typefile
Requiredrequired
DescriptionMultipart audio file, up to 8 MiB. WAV, MP3, M4A, Ogg, WebM, AAC or AMR. Let the client set the multipart boundary.
Parameterseconds
Typenumber
Requiredoptional
DescriptionRecording duration, 0–120 seconds. The Hub validates the actual rendered duration before dialing.

Request Example

curl -X POST "https://api.msg4wrd.io/api/v5/call/11111111-1111-4111-8111-111111111111/voice" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json" \
  -F "device_uid=YOUR_HUB_DEVICE_UID" \
  -F "claim_token=CURRENT_CLAIM_TOKEN" \
  -F "seconds=12" \
  -F "[email protected]"

JSON Response Example

{
  "id": "22222222-2222-4222-8222-222222222222"
}
POST/api/v5/call/voice

Hub protocol: upload a saved incoming voicemail/recording or local outgoing voice snapshot using multipart/form-data. Creates a voice_message conversation entry with playable private audio. Identity (account, Hub, local_id) is deduplicated: identical audio returns the existing ID; changed audio returns 409. Unknown callers are not merged into a phone thread.

Auth
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionEnabled registered Hub owned by the authenticated account; maximum 100 characters.
Parameterlocal_id
Typestring
Requiredrequired
DescriptionStable local call/automation ID, maximum 100 characters.
Parametermobile
Typestring
Requiredoptional
DescriptionCaller/recipient; omit for a private or unknown caller.
Parameterdirection
Typestring
Requiredrequired
Descriptionin or out.
Parameterversion
Typeinteger
Requiredrequired
DescriptionPositive source snapshot version; retain it on retries.
Parameteroccurred_at
Typetimestamp
Requiredrequired
DescriptionOriginal recording/call time with timezone offset.
Parameterseconds
Typenumber
Requiredrequired
DescriptionRecording duration, 0–120 seconds. The Hub validates the actual rendered duration before dialing.
Parameteraudio
Typefile
Requiredrequired
DescriptionMultipart audio file, up to 8 MiB. WAV, MP3, M4A, Ogg, WebM, AAC or AMR. Let the client set the multipart boundary.

Request Example

curl -X POST "https://api.msg4wrd.io/api/v5/call/voice" \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Accept: application/json" \
  -F "device_uid=YOUR_HUB_DEVICE_UID" \
  -F "local_id=hub-call-001" \
  -F "mobile=+639171234567" \
  -F "direction=in" \
  -F "version=4" \
  -F "occurred_at=2026-10-04T01:01:00Z" \
  -F "seconds=12" \
  -F "[email protected]"

JSON Response Example

{
  "id": "22222222-2222-4222-8222-222222222222"
}
POST/api/v5/sms/events

Hub protocol: import local outbound SMS snapshots into conversations without sending or charging the SMS again. Increasing versions update the same activity; retries retain their original version and timestamp.

Auth
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionEnabled registered Hub owned by the authenticated account; maximum 100 characters.
Parameterlocal_id
Typestring
Requiredrequired
DescriptionStable Hub-local SMS ID, maximum 100 characters.
Parametermobile
Typestring
Requiredrequired
DescriptionRecipient phone number, maximum 64 characters.
Parameterstatus
Typestring
Requiredrequired
Descriptionqueued, sending, submitted, delivered, failed or unknown.
Parameterbody
Typestring
Requiredrequired
DescriptionSMS content, maximum 4000 characters.
Parameterversion
Typeinteger
Requiredrequired
DescriptionPositive, increasing snapshot version.
Parameteroccurred_at
Typetimestamp
Requiredrequired
DescriptionOriginal event time with timezone offset.
Parameterchannel_name
Typestring
Requiredoptional
DescriptionChannel label, maximum 100 characters.
Parametersim_number
Typestring
Requiredoptional
DescriptionSIM phone number, maximum 64 characters.

Request Example

{
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "local_id": "hub-sms-002",
  "mobile": "+639171234567",
  "body": "Your request is ready.",
  "status": "submitted",
  "version": 2,
  "occurred_at": "2026-10-04T01:00:00Z",
  "channel_name": "Home SIM"
}

JSON Response Example

{
  "accepted": true
}

Inbound

SMS, calls and voice messages share a normalized mobile thread. Use entry_key as the unique UI identity and type (sms, call or voice_message) to choose its presentation. Keep positive SMS IDs for SMS actions. call_status carries the detailed call state; audio_url and seconds describe owner-only playback. Numeric status remains 0=pending, 1=sending, 2=success, 3=failed. Only stored outgoing SMS entries can use SMS resend.

5 endpoints
GET/api/v5/inbound

List SMS, call and voice conversations, with the latest entry per normalized mobile and saved contact details.

Auth
Parametersearch
Typestring
Requiredoptional
DescriptionSearch by mobile number, message content, or sender.
Parameterpage
Typeinteger
Requiredoptional
DescriptionPage number. Defaults to 1.

JSON Response Example

{
  "data": [
    {
      "id": -8,
      "entry_key": "activity:8",
      "type": "voice_message",
      "mobile": "+639171234567",
      "normalized_mobile": "+639171234567",
      "content": "Voice message",
      "sender": "",
      "is_inbound": 1,
      "status": 2,
      "call_status": null,
      "call_id": null,
      "audio_url": "/api/v5/call/media/22222222-2222-4222-8222-222222222222/audio",
      "seconds": 12,
      "created_at": "2026-10-04T01:02:00.000000Z",
      "from_mobile": "+639171234567",
      "received_at": "2026-10-04T01:02:00.000000Z",
      "contact_name": "Juan Dela Cruz",
      "contact_mobile": "09171234567"
    }
  ],
  "current_page": 1,
  "last_page": 1,
  "per_page": 15,
  "total": 1,
  "realtime_channel": "account-realtime-channel"
}
GET/api/v5/inbound/thread/{mobile}

Retrieve the latest 500 SMS, call and voice entries for one mobile, oldest first. entry_key is the unique UI identity; audio_url is authenticated playback, seconds is the recording duration, and call_status is the detailed call state.

Auth
Parametermobile
Typestring
Requiredrequired
DescriptionMobile number in the URL path.

JSON Response Example

{
  "mobile": "+639171234567",
  "variants": [
    "09171234567",
    "+639171234567"
  ],
  "messages": [
    {
      "id": 123,
      "entry_key": "sms:123",
      "type": "sms",
      "mobile": "09171234567",
      "normalized_mobile": "+639171234567",
      "content": "Hello",
      "sender": "default",
      "is_inbound": 0,
      "local": 0,
      "priority": 0,
      "status": 2,
      "created_at": "2026-10-04T01:00:00.000000Z"
    },
    {
      "id": -7,
      "entry_key": "activity:7",
      "type": "call",
      "mobile": "+639171234567",
      "normalized_mobile": "+639171234567",
      "content": "Incoming call ended",
      "sender": "Home SIM",
      "is_inbound": 1,
      "status": 2,
      "call_status": "ended",
      "call_id": "activity-7",
      "audio_url": null,
      "seconds": 18,
      "created_at": "2026-10-04T01:01:00.000000Z"
    },
    {
      "id": -8,
      "entry_key": "activity:8",
      "type": "voice_message",
      "mobile": "+639171234567",
      "normalized_mobile": "+639171234567",
      "content": "Voice message",
      "sender": "",
      "is_inbound": 1,
      "status": 2,
      "call_status": null,
      "call_id": null,
      "audio_url": "/api/v5/call/media/22222222-2222-4222-8222-222222222222/audio",
      "seconds": 12,
      "created_at": "2026-10-04T01:02:00.000000Z"
    },
    {
      "id": 0,
      "entry_key": "call:11111111-1111-4111-8111-111111111111",
      "type": "voice_message",
      "call_id": "11111111-1111-4111-8111-111111111111",
      "mobile": "+639171234567",
      "normalized_mobile": "+639171234567",
      "content": "Voice message",
      "sender": "",
      "is_inbound": 0,
      "status": 0,
      "call_status": "queued",
      "audio_url": "/api/v5/call/media/22222222-2222-4222-8222-222222222222/audio",
      "seconds": 12,
      "created_at": "2026-10-04T01:03:00.000000Z"
    }
  ]
}
POST/api/v5/inbound/reply

Send a manual reply to an inbound thread target.

Auth
Parametermobile
Typestring
Requiredrequired
DescriptionRecipient mobile number or normalized thread mobile.
Parametermessage
Typestring
Requiredrequired
DescriptionSMS body, maximum 160 characters.

JSON Response Example

{
  "message": "Reply sent successfully.",
  "sent": {
    "id": 125,
    "mobile": "09171234567",
    "normalized_mobile": "+639171234567",
    "content": "Reply text",
    "sender": "default",
    "is_inbound": 0,
    "status": 0,
    "created_at": "2026-05-09T10:02:00.000000Z"
  }
}
POST/api/v5/inbound/message/{id}/resend

Reset a failed outbound SMS message back to pending.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionFailed outbound SMS message ID in the URL path.

JSON Response Example

{
  "message": "Message queued for resend.",
  "sent": {
    "id": 125,
    "mobile": "09171234567",
    "normalized_mobile": "+639171234567",
    "content": "Reply text",
    "sender": "default",
    "is_inbound": 0,
    "status": 0,
    "created_at": "2026-05-09T10:02:00.000000Z"
  }
}
POST/api/v5/inbound

Store an inbound SMS from a registered device and run configured automations. Hub retries retain source_id and occurred_at to deduplicate ingestion and preserve its original time.

Auth
Parameterdevice_uid
Typestring
Requiredrequired
DescriptionRegistered active device identifier.
Parametermobile
Typestring
Requiredrequired
DescriptionSender mobile number.
Parametermessage
Typestring
Requiredrequired
DescriptionInbound SMS body.
Parameterlocal
Typeinteger
Requiredoptional
DescriptionCountry routing flag. Use 0 for PH (default) or 1 for US.
Parametersource_id
Typestring
Requiredoptional
DescriptionStable Hub-local incoming SMS ID, up to 100 characters. Reuse it on retries to deduplicate ingestion and automations per account/device.
Parameteroccurred_at
Typetimestamp
Requiredoptional
DescriptionOriginal SMS time with timezone offset. Defaults to now.

Request Example

{
  "device_uid": "YOUR_HUB_DEVICE_UID",
  "source_id": "hub-sms-001",
  "mobile": "+639171234567",
  "message": "Hello from the Hub",
  "local": 0,
  "occurred_at": "2026-10-04T01:00:00Z"
}

JSON Response Example

{
  "status": 200,
  "message": "success"
}

Contacts

Saved SMS contacts used by inbound lists and manual sends.

4 endpoints
GET/api/v5/contacts

List saved SMS contacts.

Auth

JSON Response Example

{
  "data": [
    {
      "id": 1,
      "name": "Juan Dela Cruz",
      "mobile": "09171234567",
      "created_at": "2026-05-09T10:00:00.000000Z",
      "updated_at": "2026-05-09T10:00:00.000000Z"
    }
  ]
}
POST/api/v5/contacts

Create a saved SMS contact.

Auth
Parametername
Typestring
Requiredrequired
DescriptionContact display name, maximum 100 characters.
Parametermobile
Typestring
Requiredrequired
DescriptionContact mobile number, maximum 30 characters and unique per user.

JSON Response Example

{
  "message": "Contact added successfully.",
  "contact": {
    "id": 1,
    "name": "Juan Dela Cruz",
    "mobile": "09171234567",
    "created_at": "2026-05-09T10:00:00.000000Z",
    "updated_at": "2026-05-09T10:00:00.000000Z"
  }
}
PUT/api/v5/contacts/{id}

Update a saved SMS contact.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionContact record ID in the URL path.
Parametername
Typestring
Requiredrequired
DescriptionContact display name, maximum 100 characters.
Parametermobile
Typestring
Requiredrequired
DescriptionContact mobile number, unique per user.

JSON Response Example

{
  "message": "Contact updated successfully.",
  "contact": {
    "id": 1,
    "name": "Juan Dela Cruz",
    "mobile": "09171234567",
    "created_at": "2026-05-09T10:00:00.000000Z",
    "updated_at": "2026-05-09T10:05:00.000000Z"
  }
}
DELETE/api/v5/contacts/{id}

Delete a saved SMS contact.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionContact record ID in the URL path.

JSON Response Example

204 No Content

SMS Campaigns

Recipient-file parsing, sample templates, draft creation, delivery reporting, reuse, and queued sending.

7 endpoints
POST/api/v5/campaigns/parse

Parse an XLSX, CSV, or TXT recipient file into a validation preview.

Auth
Parameterfile
Typefile
Requiredrequired
DescriptionRecipient file up to 10 MB.
GET/api/v5/campaigns/template/{type}

Download a basic, company, or unique-message sample template.

Auth
Parametertype
Typestring
Requiredrequired
DescriptionLayout: basic, company, or unique.
Parameterformat
Typestring
Requiredoptional
DescriptionQuery value: xlsx, csv, or txt.
GET/api/v5/campaigns

List campaigns plus aggregate recipient and delivery totals.

Auth
Parameterpage
Typeinteger
Requiredoptional
DescriptionPage number.
POST/api/v5/campaigns

Save a campaign draft without spending credits or sending messages.

Auth
Parametername
Typestring
Requiredrequired
DescriptionCampaign name.
Parametermessages
Typestring[]
Requiredrequired
DescriptionOne to 10 messages, each up to 160 characters.
Parameterrecipients
Typeobject[]
Requiredrequired
DescriptionParsed recipients with mobile and optional variables.
Parametersource_filename
Typestring
Requiredoptional
DescriptionOriginal recipient filename.
GET/api/v5/campaigns/{id}

Retrieve campaign totals, cost estimate, wallet balance, and recipient delivery statuses.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionCampaign ID.
Parameterpage
Typeinteger
Requiredoptional
DescriptionRecipient page number.
Parameterstatus
Typestring
Requiredoptional
DescriptionOptional recipient status filter.
GET/api/v5/campaigns/{id}/duplicate

Load a previous campaign into the Copy and Use composer workflow.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionCampaign ID.
POST/api/v5/campaigns/{id}/send

Queue a draft after checking wallet credits and daily/monthly outbound limits.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionDraft campaign ID.

Keywords

Keyword routing, webhook assignment, devices, and linked mobile numbers.

4 endpoints
GET/api/v5/keywords-devices

Retrieve keywords, mobile devices, and linked mobile numbers.

Auth

JSON Response Example

{
  "keywords": [
    {
      "id": 1,
      "keyword": "PAYMENT",
      "webhook": "https://example.com/webhook",
      "status": true
    }
  ],
  "devices": [
    {
      "id": 1,
      "name": "Main GSM Modem",
      "device_id": "DEVICE-001",
      "mobile": "09171234567",
      "status": true
    }
  ]
}
POST/api/v5/keyword/create

Create a keyword and webhook configuration.

Auth
Parameterkeyword
Typestring
Requiredrequired
DescriptionUnique keyword. Letters, numbers, underscores, and dashes are accepted.
Parameterwebhook
Typeurl
Requiredrequired
DescriptionHTTPS endpoint that receives transaction payloads.
Parameterdevice_id
Typeinteger
Requiredoptional
DescriptionEnabled mobile device record ID to tag.
Parameterewallet_channel
Typeinteger
Requiredoptional
Description1 for SMS Command Only, 2 for all commands.
Parameteris_default_webhook
Typeboolean
Requiredoptional
DescriptionUse as fallback for unmatched transactions.
Parameterdefault_webhook
Typeboolean
Requiredoptional
DescriptionLegacy alias for is_default_webhook.
Parameterstatus
Typeboolean
Requiredoptional
DescriptionEnable or disable this keyword.
Parametermobile_app
Typeboolean
Requiredoptional
DescriptionLegacy alias used to enable the keyword when status is omitted.

JSON Response Example

{
  "success": true,
  "message": "Keyword created"
}
PUT/api/v5/keyword/{id}

Update an existing keyword.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionKeyword record ID in the URL path.
Parameterkeyword
Typestring
Requiredrequired
DescriptionUnique keyword. Letters, numbers, underscores, and dashes are accepted.
Parameterwebhook
Typeurl
Requiredrequired
DescriptionHTTPS endpoint that receives transaction payloads.
Parameterdevice_id
Typeinteger
Requiredoptional
DescriptionEnabled mobile device record ID to tag.
Parameterewallet_channel
Typeinteger
Requiredoptional
Description1 for SMS Command Only, 2 for all commands.
Parameteris_default_webhook
Typeboolean
Requiredoptional
DescriptionUse as fallback for unmatched transactions.
Parameterdefault_webhook
Typeboolean
Requiredoptional
DescriptionLegacy alias for is_default_webhook.
Parameterstatus
Typeboolean
Requiredoptional
DescriptionEnable or disable this keyword.
Parametermobile_app
Typeboolean
Requiredoptional
DescriptionLegacy alias used to enable the keyword when status is omitted.

JSON Response Example

{
  "success": true,
  "message": "Keyword updated."
}
DELETE/api/v5/keyword/{id}

Delete an existing keyword.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionKeyword record ID in the URL path.

JSON Response Example

{
  "success": true,
  "message": "Keyword deleted."
}

Devices

GSM modem device registration and management.

3 endpoints
POST/api/v5/device/create

Register a new GSM modem device.

Auth
Parameterid
Typeinteger
Requiredoptional
DescriptionExisting device ID. Include to update through create endpoint.
Parameteris_update
Typeboolean
Requiredoptional
DescriptionLegacy update flag.
Parametername
Typestring
Requiredrequired
DescriptionDisplay name for the device.
Parameterdevice_id
Typestring
Requiredrequired
DescriptionUnique hardware identifier.
Parametermobile
Typestring
Requiredrequired
DescriptionSIM card mobile number installed in the device.
Parameteris_autoreply_to_sender
Typeboolean
Requiredoptional
DescriptionAutomatically reply to inbound SMS senders.
Parameteris_msg4wrd
Typeboolean
Requiredoptional
DescriptionUse MSG4wrd as the outbound sender.
Parameterstatus
Typeboolean
Requiredoptional
DescriptionEnable or disable this device. Defaults to enabled.

JSON Response Example

{
  "success": true,
  "message": "Device registered"
}
PUT/api/v5/device/{id}

Update a registered GSM modem device.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionDevice record ID in the URL path.
Parametername
Typestring
Requiredrequired
DescriptionDisplay name for the device.
Parameterdevice_id
Typestring
Requiredrequired
DescriptionUnique hardware identifier.
Parametermobile
Typestring
Requiredrequired
DescriptionSIM card mobile number installed in the device.
Parameteris_autoreply_to_sender
Typeboolean
Requiredoptional
DescriptionAutomatically reply to inbound SMS senders.
Parameteris_msg4wrd
Typeboolean
Requiredoptional
DescriptionUse MSG4wrd as the outbound sender.
Parameterstatus
Typeboolean
Requiredoptional
DescriptionEnable or disable this device.

JSON Response Example

{
  "success": true,
  "message": "Device updated."
}
DELETE/api/v5/device/{id}

Delete a registered GSM modem device.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionDevice record ID in the URL path.

JSON Response Example

{
  "success": true,
  "message": "Device deleted."
}

Sender Numbers

Blocked sender-number management for Philippine and US numbers.

2 endpoints
POST/api/v5/sender-number/create

Add a number to the account’s blocked-sender list.

Auth
Parametermobile
Typestring
Requiredrequired
DescriptionInternational PH or US mobile number.
DELETE/api/v5/sender-number/{id}

Delete a blocked sender number owned by the account.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionSender-number record ID.

Billing

Top-up offers, promos, limit add-ons, one-time checkout, payment history, and invoices.

9 endpoints
GET/api/v5/credit-packages

List active credit top-ups, promos, and account-limit add-ons.

Public
GET/api/v5/payments

List one-time purchase and legacy payment history.

Auth
Parameterpage
Typeinteger
Requiredoptional
DescriptionPage number.
GET/api/v5/payments/{id}/proof

Download the authenticated account’s own manual payment proof image.

Auth
Parameterid
Typeinteger
Requiredrequired
DescriptionPayment transaction ID.
GET/api/v5/payments/gateway-settings

Read enabled payment gateways and public checkout configuration.

Public
GET/api/v5/payments/gateway-settings/{gateway}/qr

Download the configured public QR image for GCash or Maya.

Public
Parametergateway
Typestring
Requiredrequired
Descriptiongcash or maya.
POST/api/v5/checkout/paypal/order

Create a PayPal order for an active offer.

Auth
Parametercredit_package_id
Typeinteger
Requiredrequired
DescriptionActive offer ID.
POST/api/v5/checkout/paypal/order/{txn}/capture

Capture a PayPal order and fulfill credits and limit increments once.

Auth
Parametertxn
Typeinteger
Requiredrequired
DescriptionPayment transaction ID.
POST/api/v5/checkout/manual

Submit GCash or Maya payment details and proof for verification.

Auth
Parametercredit_package_id
Typeinteger
Requiredrequired
DescriptionActive offer ID.
Parametergateway
Typestring
Requiredrequired
Descriptiongcash or maya.
Parameterreference_number
Typestring
Requiredrequired
DescriptionPayment reference number.
Parameterproof
Typefile
Requiredrequired
DescriptionPayment proof image.
GET/api/v5/billing

List billing invoices and payment history.

Auth
Parameterpage
Typeinteger
Requiredoptional
DescriptionPage number. Defaults to 1.

JSON Response Example

{
  "data": [
    {
      "id": 1,
      "description": "Credit top-up",
      "amount": 999.00,
      "status": "paid",
      "paid_at": "2026-05-09T10:00:00.000000Z"
    }
  ],
  "current_page": 1,
  "last_page": 2
}