Parameters $ai | Medplum

On this page

The $ai operation provides an interface for calling AI language models (like OpenAI's GPT) through Medplum. This operation supports both standard request/response and streaming modes.

Use Cases

Prerequisites

The AI feature must be enabled for your project. Contact your Medplum administrator or ensure ai is included in your project's features list.

By default the operation calls OpenAI at https://api.openai.com/v1. To route requests through a LiteLLM proxy or other OpenAI-compatible endpoint, set the optional project secret LLM_BASE_URL (e.g. https://litellm.example.com/v1); the OPENAI_API_KEY secret is then used as the proxy's bearer token. See $ai Operation for details.

Invoke the $ai operation

[base]/Parameters/$ai

For example:

curl -X POST 'https://api.medplum.com/fhir/R4/Parameters/$ai' \
  -H "Content-Type: application/fhir+json" \
  -H "Authorization: Bearer MY_ACCESS_TOKEN" \
  -d '{
    "resourceType": "Parameters",
    "parameter": [
      {
        "name": "messages",
        "valueString": "[{\"role\": \"user\", \"content\": \"What is FHIR?\"}]"
      },
      {
        "name": "apiKey",
        "valueString": "sk-your-openai-api-key"
      },
      {
        "name": "model",
        "valueString": "gpt-4"
      }
    ]
  }'

Parameters

Name Type Description Required
messages string JSON string containing the conversation messages array Yes
apiKey string OpenAI API key Yes
model string OpenAI model to use (e.g., gpt-4, gpt-3.5-turbo) Yes
tools string JSON string containing the tools array for function calling No

Messages Format

The messages parameter should be a JSON-encoded array of message objects following the OpenAI chat format:

[
  {"role": "system", "content": "You are a helpful healthcare assistant."},
  {"role": "user", "content": "What is the normal range for blood pressure?"}
]

Tools Format (Function Calling)

The tools parameter enables function calling capabilities:

[
  {
    "type": "function",
    "function": {
      "name": "get_patient_vitals",
      "description": "Retrieve patient vital signs",
      "parameters": {
        "type": "object",
        "properties": {
          "patient_id": {
            "type": "string",
            "description": "The patient's ID"
          }
        },
        "required": ["patient_id"]
      }
    }
  }
]

Output

Name Type Description
content string The AI response content
tool_calls string JSON string containing tool calls array

Example Response

{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "content",
      "valueString": "FHIR (Fast Healthcare Interoperability Resources) is a standard for exchanging healthcare information electronically..."
    }
  ]
}

Response with Tool Calls

{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "tool_calls",
      "valueString": "[{\"id\": \"call_abc123\", \"type\": \"function\", \"function\": {\"name\": \"get_patient_vitals\", \"arguments\": {\"patient_id\": \"patient-123\"}}}]"
    }
  ]
}

Streaming Mode

The operation supports Server-Sent Events (SSE) streaming for real-time responses. To enable streaming, set the Accept header to text/event-stream:

curl -X POST 'https://api.medplum.com/fhir/R4/Parameters/$ai' \
  -H "Content-Type: application/fhir+json" \
  -H "Accept: text/event-stream" \
  -H "Authorization: Bearer MY_ACCESS_TOKEN" \
  -d '...'

Streaming responses arrive as SSE events:

data: {"content": "FHIR "}

data: {"content": "(Fast "}

data: {"content": "Healthcare "}

data: {"content": "Interoperability "}

data: {"content": "Resources) "}

data: [DONE]

note Tool calls are not supported in streaming mode.

Error Responses

Feature Not Enabled

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "forbidden",
      "details": {
        "text": "Forbidden"
      }
    }
  ]
}

Invalid Messages Format

{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "invalid",
      "details": {
        "text": "Messages must be an array"
      }
    }
  ]
}

Security Considerations

Related Documentation