Server API

Sessions, client tokens, status, results, deletion and webhooks. Called from your backend with your API key.

All requests go to KITA_BASE_URL with your key in X-API-Key. Responses are JSON. Errors have the shape {"error": {"code": "...", "request_id": "req_..."}}; quote the request_id when you contact Kita.

Authentication

Send your key in the X-API-Key header on every request. Keys are per organization and per environment: risk_test_… for test, risk_live_… for production. Nothing in the API is readable without one, and the key is checked before the request body is.

curl "$KITA_BASE_URL/v1/risk/sessions" -H "X-API-Key: $KITA_API_KEY"
StatusCodeMeaning
401missing_api_keyNo X-API-Key header.
401invalid_api_keyThe key matches no organization. Check for a truncated or rotated key.
401wrong_environmentA test key sent to production, or a live key sent to test.

Keep the key on your server. The browser and the mobile app only ever receive a client_token, which is limited to one session and one origin and expires after 30 minutes.

Python client

kita_risk.py is a single file with no dependencies. Copy it into your project.

from kita_risk import KitaRisk, KitaRiskError
 
kita = KitaRisk(api_key=os.environ["KITA_API_KEY"], base_url=os.environ["KITA_BASE_URL"])
 
session = kita.create_session(reference_id="LOAN-2026-001", origin="https://app.example.com")
token   = kita.client_token(session["session_id"])       # when the borrower returns
status  = kita.status(session["session_id"])
kita.delete(session["session_id"])                       # files, results and stored copies
 
KitaRisk.verify_webhook(secret, request.headers["Kita-Signature"], raw_body)  # -> bool

Getting the file

Download kita_risk.py. It wraps exactly the endpoints below, so any language with an HTTP client works the same way.

Create a session

POST /v1/risk/sessions

FieldTypeRequiredDescription
reference_idstring, 1–128yesYour applicant or loan ID. Stored with everything Kita keeps for the session.
originstringyesThe exact web origin that embeds the SDK. Must be registered with Kita. For Android, the origin you load the host page under.
display_namestring, 1–60noYour name as shown to the borrower. Default "Your lender".
countryMX or PHnoDefault MX. Must match the model profile enabled for you.
locationoptional or disablednoWhether the flow may ask for browser location. Default optional. Location is never a model input.

Send an Idempotency-Key header (up to 128 characters) derived from the applicant. A repeat with the same key and body returns the same session with a new client token; the old token stops working. A repeat with a different body returns 409 idempotency_conflict.

Returns 201 with session_id, client_token, expires_at, sdk_url, connect_url and environment.

New client token

POST /v1/risk/sessions/{session_id}/client-token

Issues a fresh 30-minute token and invalidates the previous one.

Session status

GET /v1/risk/sessions/{session_id} · GET /v1/risk/sessions?offset=0 (40 per page, newest first)

{
  "session_id": "rs_3f9a1c2e7b8d4a60915e2c7d4b8a6f01",
  "reference_id": "LOAN-2026-001",
  "status": "completed",
  "consented": true,
  "documents": [
    { "id": "doc_a4e4…", "name": "statement-august.pdf", "size": 398000, "status": "completed", "reason": null }
  ],
  "completed_documents": 1,
  "results_available": true,
  "archive_status": "stored",
  "created_at": "2026-09-18T19:02:11Z",
  "retain_until": "2026-09-19T19:02:11Z"
}
statusMeaning
collectingThe borrower has not shared yet. Files can still be added or removed.
queued, processingShared. Kita is reading the files.
completedEvery file was read.
partialSome files were read; the rest have a reason.
failedNo file could be read.

Results

GET /v1/risk/sessions/{session_id}/results returns 409 results_not_ready until the session is completed, partial or failed.

For live scoring the response lists each score with status, value, percentile and the document it came from; see the scores. Scores that do not apply to the uploaded document types are null, never zero.

For a backtest every score is returned as unavailable with reason withheld_for_backtest. The response still tells you which files were read and their detected types.

Delete a session

DELETE /v1/risk/sessions/{session_id} returns 204. It removes the session, its files and results, and the copy in Kita's archive. If the archive cannot be reached the call returns 503 archive_unavailable and nothing is removed, so you can retry. Use this to honor a borrower's deletion request.

Webhooks

When a session finishes, Kita posts to the HTTPS URL you registered:

{ "id": "evt_9c1f…", "type": "risk.session.completed", "session_id": "rs_3f9a…", "created_at": 1789754531.2, "schema_version": "risk.v1" }

type is risk.session.completed, .partial or .failed. The body never contains scores or borrower data; fetch what you need with your API key.

Verify every delivery. The Kita-Signature header is t=<unix seconds>,v1=<hex> where v1 is HMAC-SHA256 of t + "." + raw_body under your webhook secret. Reject timestamps older than five minutes and deduplicate on id. Return any 2xx once you have stored the event. Failed deliveries retry with backoff, six attempts in all.

Limits

Write requests120 per minute per organization, in bursts of up to 30. 429 carries Retry-After.
File size100 MB per file
Files per session12
PDF pages150 per file
Client token lifetime30 minutes
Session retention24 hours unless agreed otherwise

On this page