Download OpenAPI specification:
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.
All production auth tokens are delivered out-of-band via secure channel.
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.
| 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 |
| 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". |
{- "gateway_sms_id": 101,
- "port": 17,
- "sender": "612345678",
- "text": "ROKO U12345678",
- "timestamp": "2026-05-15T10:30:00Z",
- "source": "topaz"
}{- "status": "accepted",
- "sms_id": 0
}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: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.
| phone_number required | string Guinea MSISDN (9 digits, starts with 6). |
| 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"). |
{- "phone_number": "612345678",
- "text": "Merci pour votre participation ROKO.",
- "template_key": "VALID_FIRST"
}{- "sms_id": 0,
- "status": "SENT",
- "gateway_sms_id": 0,
- "reason": "string"
}