POST /route
The same contract the in-browser engine answers at usesikka.com/routing. Card names are matched case-insensitively against the catalog; examples here use a generic wallet.
{
"cards": [
"option_a",
"option_b",
"option_c"
],
"merchant": "GROCERY MART DXB",
"amountAed": 400
}{
"bestCard": "option_a",
"bestRewardAed": 20.00,
"bestRatePct": 5,
"category": "groceries",
"categoryResolved": true,
"deltaVsRunnerUpAed": 14.00,
"reason": "5% on groceries, best of 3",
"perCard": [ … every card scored, best first … ],
"latencyMs": 0.25
}No PAN, no CVV, no credentials, no PII. The request carries card product names, a raw merchant descriptor, and an amount. Values in the example are illustrative; the live engine computes them from its verified rulebook.
Every field, defined.
| Field | Type | Meaning |
|---|---|---|
| bestCard | string | null | The winning card. null when no card earns a verified reward here: the engine abstains rather than guessing. |
| bestRewardAed | number | The AED reward the winning card earns on this transaction. |
| bestRatePct | number | The effective reward rate, as a percentage. |
| category | string | The resolved merchant category. Falls back to everyday. |
| categoryResolved | boolean | false when the descriptor could not be resolved. The transaction routes at base rates, flagged, never guessed. |
| deltaVsRunnerUpAed | number | Value at stake versus the next-best card. |
| reason | string | A human-readable explanation, ready for a nudge or a statement line. |
| perCard | object[] | Every card scored, best first: the full comparison behind the decision. |
| latencyMs | number | Compute time for this decision, measured live. |
FULL CONTRACT · PROPOSED
The production contract extends the live one with decision_id, reason_code (machine-stable, e.g. GROCERY_BONUS_5PCT), rulebook_version, confidence, and fallback. Proposed means exactly that: scoped and finalized in the pilot, not shipped today.
Same inputs, same decision. Every time.
The synchronous decision path is a versioned rules engine: no LLM calls, no sampling, no drift. Decisioning is stateless and side-effect-free, so retries are naturally safe: replaying a request returns the identical response.
PROPOSED Idempotency keys for billing-grade decision accounting (one billable decision per key, replays free) are part of the proposed production contract.
Three numbers. Three different claims.
| Number | What it is | What it is not |
|---|---|---|
| ~0.08ms p99 | Core decision compute on a local benchmark: the in-process engine, no network. | Not production latency. |
| <100ms | Typical round-trip on the live demo, measured in the browser. | Not an SLA. |
| Production SLA | A pilot gate: validated on your flows, in your deployment model, before production. | Not a marketing number. |
Execution never depends on us.
If a decision cannot be returned inside its budget, your stack proceeds exactly as it does today: the configured fallback applies and the payment executes unchanged. Low confidence returns an abstain, never a silent guess. A Sikka outage cannot block an authorization, by construction: Sikka sits before execution and holds no state your stack needs.
| Condition | Behaviour |
|---|---|
| Invalid context | 400 with a machine-readable error. Nothing is stored. |
| Unresolved merchant | 200 with categoryResolved: false: routed at base rates, flagged, never guessed. |
| No verified reward | 200 with bestCard: null: an explicit abstain. |
| Timeout / unavailable | Your configured fallback applies; execution proceeds unchanged. |
Four steps. Shadow first.
Send the wallet and the purchase
POST /route with the cards, the raw merchant descriptor, and amountAed. No PAN, no PII.
Get the decision back
Deterministic JSON: best card, reward, delta, reason, and the full perCard comparison.
Surface it on your rails
A "use this card" nudge, a reward attribution, a statement line, or an internal signal.
Host it in your perimeter
Stateless, no external calls at decision time. The rulebook ships versioned and freshness-checked.
The sandbox is already open.
The live engine runs in your browser at usesikka.com/routing: real decisions, real reason strings, no signup, nothing leaves the page. A dedicated pilot environment against representative flows is scoped in the pilot workshop.