Roko Lucky Drawer — SMS Platform API (0.1.0)

Download OpenAPI specification:

Roko Platform Team: eric@delaguayaba.com

Inbound webhook + outbound send endpoints for the ROKO Nano Fertilizer Lucky Draw Campaign (Guinea, 2026).

This spec is the canonical contract between the Roko AWS backend and the Topaz SMS gateway integration.

  • Section 1 — Inbound webhook: the payload Topaz MUST POST to us when a farmer sends an SMS. We define this; Topaz implements.
  • Section 2 — Outbound send: the internal API our frontend / workers call to send a single-segment SMS. Under the hood this Lambda calls the Topaz outbound endpoint described in Section 3.
  • Section 3 — Topaz outbound contract (reference): the request shape the Roko Lambda will POST to Topaz when sending SMS. Topaz MUST implement an endpoint matching this.

All production auth tokens are delivered out-of-band via secure channel.

webhook

Inbound SMS from the Topaz gateway.

Receive an inbound SMS from Topaz

Topaz calls this endpoint for every SMS received on our SIM (612 990 119 for stage, 612 987 722 for prod). The request must carry the shared token in X-Roko-Webhook-Token; Roko persists the SMS and returns the internal sms_id.

Idempotency: requests with the same (gateway_sms_id, port) tuple are safe to retry; we upsert on that key.

Auth: constant-time compare against the token stored in /roko/{stage|prod}/webhook-inbound-token SSM parameter.

Authorizations:
webhookToken
Request Body schema: application/json
required
gateway_sms_id
required
integer >= 0

Stable ID assigned by the Topaz gateway for this SMS.

port
required
integer [ 0 .. 31 ]

SIM slot port on the gateway (0–31). Port identifies the environment.

sender
required
string^[0-9+]{6,20}$

Farmer MSISDN. Preferred: 9-digit Guinea local format, no + prefix.

text
required
string [ 1 .. 1600 ] characters

Raw SMS content as received by Topaz. No transformation.

timestamp
required
string <date-time>

ISO-8601 UTC timestamp of when Topaz received the SMS.

source
string <= 30 characters

Vendor identifier. Defaults to "topaz".

Responses

Request samples

Content type
application/json
{
  • "gateway_sms_id": 101,
  • "port": 17,
  • "sender": "612345678",
  • "text": "ROKO U12345678",
  • "timestamp": "2026-05-15T10:30:00Z",
  • "source": "topaz"
}

Response samples

Content type
application/json
{
  • "status": "accepted",
  • "sms_id": 0
}

send

Outbound SMS originated by Roko.

Send a single-segment SMS via Topaz

Internal endpoint called by the Roko ops dashboard / worker jobs to send an SMS to a farmer.

Strict validations:

  • phone_number must be a Guinea MSISDN (9 digits starting with 6). Country code 224 prefix is stripped if present.
  • text must fit in exactly one SMS segment:
    • 160 chars if all characters are in the GSM-7 alphabet
    • 70 chars otherwise (Unicode/UCS-2)
  • Requests exceeding the single-segment limit return 400 with the detected encoding and the applicable limit.

Auth: API key via x-api-key header. Key issued per caller by the operator; stored in AWS API Gateway usage plans.

Authorizations:
apiKey
Request Body schema: application/json
required
phone_number
required
string

Guinea MSISDN (9 digits, starts with 6). +224 / 224 prefix accepted and stripped.

text
required
string non-empty

SMS body. Must fit in one segment (160 GSM-7 or 70 Unicode).

template_key
string <= 30 characters

Optional tag used for analytics (e.g., "VALID_FIRST").

Responses

Request samples

Content type
application/json
{
  • "phone_number": "612345678",
  • "text": "Merci pour votre participation ROKO.",
  • "template_key": "VALID_FIRST"
}

Response samples

Content type
application/json
{
  • "sms_id": 0,
  • "status": "SENT",
  • "gateway_sms_id": 0,
  • "reason": "string"
}

topaz-outbound

Reference contract for the Topaz-side outbound endpoint.