KODA
Developers

Three endpoints. One coffee.

Connect your systems to KODA. Create intents, verify codes, receive signed webhooks — over a simple, key-authenticated REST API. Calls are metered against your plan; verifications draw down prepaid ACU.

1 · Get a key

Sign in → Developers → Create API key. The secret is shown once.

2 · Authenticate

Send Authorization: Bearer sk_… (or X-API-Key) on every request.

3 · Call the engine

Hit the endpoints below. Watch usage and ACU in your dashboard.

Base URL & authentication

Base URL   https://kodajnn.com/v1
Sandbox    https://kodajnn.com/v1
Auth       Authorization: Bearer sk_live_xxx    (or)  X-API-Key: sk_live_xxx

curl -H "Authorization: Bearer sk_test_..." https://kodajnn.com/v1/ping

Endpoints

MethodPathDescription
GET/pingVerify a key and see the merchant it unlocks.
POST/intentsCreate a payment intent (amount, currency, operators, expiry).
GET/intents/{id}Poll intent status.
POST/intents/{id}/verifySubmit the customer's reference code or screenshot.
POST/intents/{id}/cancelCancel an awaiting intent.
GET/checkout/{id}?cs=Customer-facing intent read, authorised by the intent's own client_secret — no API key. Powers the hosted page & widget.
POST/checkout/{id}/verifyThe customer submits their SMS code; on success returns the redirect so the order moves forward automatically.
GET/receiptsFilterable ledger of verified payments with audit traces.
POST/sandbox/smsInject an operator-formatted SMS and watch KODA structure it.
GET/billing/balancePrepaid ACU balance. (read:usage)
GET/agentsList the AI agents you can run and their ACU cost. (read:agents)
POST/agents/{type}/runRun a KODA agent — reconciliation report, trust lookup, dispute evidence, or screenshot extraction. Consumes prepaid ACU. (run:agents)
GET/usageYour monthly quota, usage and ACU balance. (read:usage)

Scopes

ScopeGrants
read:receiptsRead the verified-payments ledger
read:agentsList the AI agent catalogue
run:agentsRun AI agents (consumes ACU)
read:usageRead API usage & ACU balance
write:intentsCreate payment intents. Publishable pk_ keys get only this scope — safe to ship in the browser: they can start a payment, never read your data.
*Full account scope (sk_ keys). Restricted rk_live_ keys default to read-only — e.g. a read-only reconciliation key for your accountant.

Drop-in checkout — pay by mobile money, automatically

Add "Pay by mobile money" to any website or marketplace. The customer picks their operator, pays, pastes the SMS code they received into a KODA panel, and KODA verifies it — then the order moves forward on its own. Two integration paths:

1 · Hosted checkout (recommended)

Your server creates the intent with your secret key and gets back a checkout_url + client_secret. Send the customer to the URL, or open it in the widget overlay:

amount is an integer in the currency's minor unit — the same convention as Stripe. 589 USD means $5.89. Zero-decimal currencies have no fractional part, so the amount is the whole number: 25000 CDF is 25 000 FC. KODA shows the customer the natural amount and matches it against the operator SMS.

// your server (secret key) — never exposes anything to the browser
POST /v1/intents  { "amount": 25000, "currency": "CDF",   // 25 000 FC
  "operators": ["orange_cd","mpesa_cd"],
  "metadata": { "order_id": "CMD-1042" },
  "success_url": "https://shop.example.com/order/success" }
→ { "intent_id": "int_…", "client_secret": "cs_…",
    "checkout_url": "https://kodajnn.com/pay/int_…?cs=cs_…" }
// USD example: { "amount": 589, "currency": "USD" }  → the customer pays $5.89
<script src="https://kodajnn.com/js/koda.js"></script>
<script>
  Koda.checkout({
    checkoutUrl: '<checkout_url from your server>',
    onVerified: function (r) { window.location = '/order/success'; }
  });
</script>

2 · Publishable key (front-end only)

No backend call needed — a pk_ key can only create intents, so it is safe in the page. The widget creates the intent and opens the overlay for you:

<script src="https://kodajnn.com/js/koda.js"></script>
<button
  data-koda-key="pk_live_…"
  data-koda-amount="25000"
  data-koda-currency="CDF"
  data-koda-operators="orange_cd,mpesa_cd"
  data-koda-order="CMD-1042"
  data-koda-success-url="https://shop.example.com/order/success">
  Payer par mobile money
</button>
// or call it directly
Koda.pay({ key: 'pk_live_…', amount: 25000, currency: 'CDF',
  operators: ['orange_cd','mpesa_cd'], orderId: 'CMD-1042',
  successUrl: 'https://shop.example.com/order/success',
  onVerified: function (r) { /* r.receipt_id, r.amount — advance the order */ } });

Behind the scenes the money path is unchanged: the code is matched against the Sentinel SIM ledger, scored by the fraud engine, checked for replay, and a signed payment.verified webhook fires to your server — the browser hand-off is a convenience on top, never the source of truth.

Limits & pricing

Sandbox magic references

TEST-OK-25000   → instant payment.verified
TEST-LATE-90    → verifies after 90 s (payment.verified.late)
TEST-REPLAY     → code_already_used
TEST-SUFFIX     → msisdn_suffix_mismatch → challenge flow

Human-readable API reference → · machine-readable contract: /v1/openapi.json (import into Postman or generate an SDK). North-star: first verified payment < 10 minutes from signup.

Use it from any stack

Door 3 is plain HTTPS — it works in any website or app. Ready-made drop-ins and snippets:

Create your sandbox account →