Skip to content

6.3. APIs

As briefly covered in Model Deployment, APIs (Application Programming Interfaces) provide a structured way for different parts of a pricing system to communicate. They act as a “contract” between systems: one system offers a service, and the other system consumes it. In insurance pricing, APIs are extremely useful for building modular components. Instead of embedding all logic into a monolithic system, each component can be maintained independently and communicate through a standard interface.

Pricing analysts may have interacted with APIs in various ways: for example, retrieving external data, sending model outputs to rating engines, or integrating with internal tools. Many will have seen APIs through software rather than writing them from scratch-but understanding them opens the door to automating workflows and building more flexible systems.

Typical use cases in insurance pricing include:

  • Model Serving – Serve model predictions to internal tools, rating engines, or dashboards.
  • Providing Data – Provide external data or lookups/groupings
  • Rating Engines – Allow downstream systems to request premium calculations without directly embedding complex logic.

RESTful APIs

Most modern APIs follow REST (Representational State Transfer) principles. RESTful APIs use HTTP methods to interact with resources in a predictable way:

  • GET – Retrieve information from the API.
  • POST – Send data to the API.
  • PUT – Update existing resources.
  • DELETE – Remove resources.

Endpoints are typically structured around resources, providing clear and consistent paths for interacting with specific parts of the system.


Request Structure

A well-designed API request typically includes:

  1. Endpoint URL – Where the request is sent.
  2. HTTP method – Defines the type of operation (GET, POST, PUT, DELETE).
  3. Headers – Include metadata such as content type and authentication tokens.
  4. Payload / Body – The data sent to the API.

Authentication and Secrets

APIs often require authentication to control access and prevent misuse. Common methods include:

  • Bearer tokens / API keys – Simple and widely supported.
  • OAuth – Supports token refresh and user-scoped access.
  • Basic Auth – Username/password access (less common in production).

Best practices:

  • Do not hard-code secrets in scripts; use environment variables or secret managers.
  • Rotate keys regularly.
  • Limit permissions to only what’s needed (principle of least privilege).

import os
import requests

# --- 1. Endpoint URL ---
API_URL = "https://api.example.com/v1/resource"

# --- 2. HTTP Method ---
# We'll demonstrate a POST request

# --- 3. Headers ---
# Use an environment variable for secrets (best practice)
API_TOKEN = os.getenv("API_TOKEN")  # e.g., export API_TOKEN="your-token" in shell

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {API_TOKEN}"  # Bearer token auth
}

# --- 4. Payload / Body ---
payload = {
    "name": "Sample Item",
    "description": "This is an example payload"
}

# Make the request
response = requests.post(API_URL, headers=headers, json=payload)

# Handle response
if response.status_code == 200:
    print("Request successful!")
    print(response.json())
else:
    print(f"Request failed: {response.status_code}")
    print(response.text)

Deployment

API deployment can vary depending on infrastructure:

  • Local / on-premises servers – Easy to control but harder to scale
  • Cloud services – Managed hosting with auto-scaling, monitoring, and security features
  • Containerisation – Ensures the API runs consistently across environments
  • Serverless functions – Lightweight, cost-effective endpoints for simple workloads

FastAPI Example

FastAPI is a modern, high-performance Python framework for building APIs. It is particularly well-suited for serving machine learning models because it is fast, easy to use, and comes with automatic validation and documentation.

Key Features of FastAPI

  • Automatic validation – Input data is validated automatically using Python type hints and Pydantic models, reducing errors in production
  • Interactive documentation – Built-in Swagger UI and ReDoc allow anyone to explore and test endpoints without writing code
  • High performance – Asynchronous support and optimized routing make FastAPI suitable for real-time scoring of large datasets
  • Ease of deployment – Can be deployed locally, in containers, or on cloud infrastructure with minimal setup
from fastapi import FastAPI
from pydantic import BaseModel
import requests
import json
import numpy as np

# ----- Define request schema -----
class DataFrameSplit(BaseModel):
    dataframe_split: dict
    model_version_uri: str
    databricks_token: str

# ----- Init FastAPI -----
app = FastAPI(title="Premium Calculation API")

@app.post("/calculate_premium")
def calculate_premiumpredict(payload: DataFrameSplit):

    # Call the deployed MLflow model
    response = requests.post(
        payload.model_version_uri,
        headers={"Content-Type": "application/json"},
        auth=("token", payload.databricks_token),
        data=json.dumps({"dataframe_split": payload.dataframe_split})
    )

    frequency_predictions = response.json().get("predictions")
    frequency_predictions = np.array(frequency_predictions)

    severity_prediction = 500
    burn_costs = frequency_predictions * severity_prediction
    premiums = burn_costs * 1.2

    return {"premium": premiums.tolist()}

This can then be initialised with

fastapi dev demo-code/fast_api.py

And queried with

import requests

payload = {
    'dataframe_split': {
        'index': [0],
        'columns': [
            'VehPower',
            'VehAge',
            'DrivAge',
            'BonusMalus',
            'VehBrand',
            'VehGas',
            'Area',
            'Density',
            'Region'
        ],
        'data': [[
            7.0,
            14.0,
            20.0,
            100.0,
            'B1',
            'Regular',
            'D',
            1329.0,
            'Ile-de-France'
        ]]
    },
    "model_version_uri": MODEL_VERSION_URI,
    "databricks_token": DATABRICKS_TOKEN
}

url = "http://127.0.0.1:8000/calculate_premium"

response = requests.post(url, json=payload)