Developer documentation

API Documentation

Reference material and integration guides for the Relational Manager API.

Kotlin (Ktor Client) Integration

Example POST /v1/score using Ktor Client.

Prereqs

  • RI_API_KEY (string)
  • BASE_URL (string), default https://www.relationalmanager.com/api
  • Ktor client and JSON serialization
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.header
import io.ktor.client.request.post
import io.ktor.client.statement.bodyAsText
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.contentType
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive

suspend fun main() {
    val baseUrl = System.getenv("BASE_URL") ?: "https://www.relationalmanager.com/api"
    val apiKey = System.getenv("RI_API_KEY") ?: ""

    val payload = JsonObject(mapOf(
        "lenses" to JsonArray(listOf(JsonPrimitive(1), JsonPrimitive(4))),
        "persist" to JsonPrimitive(false),
        "message" to JsonObject(mapOf(
            "message_id" to JsonPrimitive("m2"),
            "conversation_id" to JsonPrimitive("c1"),
            "text" to JsonPrimitive("I'm not sure this will work."),
            "channel_type" to JsonPrimitive("chat"),
            "channel_id" to JsonPrimitive("support"),
            "sender_id" to JsonPrimitive("u2"),
            "sender_type" to JsonPrimitive("user"),
            "lang" to JsonPrimitive("en"),
            "timestamp" to JsonPrimitive("1716561012")
        )),
        "previous_message" to JsonObject(mapOf(
            "message_id" to JsonPrimitive("m1"),
            "conversation_id" to JsonPrimitive("c1"),
            "text" to JsonPrimitive("We can try a few options."),
            "channel_type" to JsonPrimitive("chat"),
            "channel_id" to JsonPrimitive("support"),
            "sender_id" to JsonPrimitive("u1"),
            "sender_type" to JsonPrimitive("agent"),
            "lang" to JsonPrimitive("en"),
            "timestamp" to JsonPrimitive("1716560950")
        ))
    ))

    val client = HttpClient(CIO) {
        install(ContentNegotiation) {
            json(Json)
        }
    }

    val response = client.post("$baseUrl/v1/score") {
        header(HttpHeaders.Authorization, "Bearer $apiKey")
        contentType(ContentType.Application.Json)
        setBody(payload)
    }

    println(response.status.value)
    println(response.headers["X-Request-Id"])
    println(response.bodyAsText())

    client.close()
}

Lens Aggregates, Indicators and Traffic Lights

The lens JSON includes weighted score, scoring_coverage, and traffic_light; questions include question and scoring_status.

Use each question's indicator_name, score, scoring_status, and traffic_light for UI dials. The signal uses the parent lens ranges, while internal metric details remain private.

The lens prescriptions array contains prioritized guidance for yellow/red signals and is empty for green.

client.put("$baseUrl/v1/lenses/1/traffic-light-ranges") {
    header(HttpHeaders.Authorization, "Bearer $apiKey")
    contentType(ContentType.Application.Json)
    setBody("""{"traffic_light_ranges":{"red":{"min":-1.0,"max":-0.2},"yellow":{"min":-0.2,"max":0.4},"green":{"min":0.4,"max":1.0}}}""")
}

The update key requires org:write; inspect scoring_status for zero-valued questions.