Keywords AI Logging API
Asynchronous request-logging endpoint for ingesting LLM call telemetry (model, prompt/completion messages, tokens, cost, latency, customer identifier, metadata) when calls are not routed through the gateway proxy.
Asynchronous request-logging endpoint for ingesting LLM call telemetry (model, prompt/completion messages, tokens, cost, latency, customer identifier, metadata) when calls are not routed through the gateway proxy.
openapi: 3.0.1
info:
title: Keywords AI API
description: >-
Keywords AI is an LLM observability and gateway platform. This specification
documents the publicly documented REST surface served from
https://api.keywordsai.co/api: the OpenAI-compatible chat completions proxy,
the asynchronous request-logging endpoint, prompt and prompt-version
management, threads, traces, evaluators, users (customers), datasets, and
experiments. All endpoints authenticate with a Bearer API key. (Keywords AI
is rebranding to Respan; the keywordsai.co host and API remain active.)
termsOfService: https://www.keywordsai.co/terms-of-service
contact:
name: Keywords AI Support
url: https://www.keywordsai.co
email: team@keywordsai.co
version: '1.0'
servers:
- url: https://api.keywordsai.co/api
description: Keywords AI production API base.
security:
- bearerAuth: []
tags:
- name: Gateway
description: OpenAI-compatible LLM proxy (chat completions).
- name: Logging
description: Asynchronous request / span logging.
- name: Prompts
description: Prompt and prompt-version management.
- name: Threads
description: Multi-turn conversation threads.
- name: Traces
description: OpenTelemetry-aligned distributed traces.
- name: Evaluators
description: Output-scoring evaluators.
- name: Users
description: End-user (customer) analytics.
- name: Datasets
description: Datasets and dataset logs.
- name: Experiments
description: Prompt / model experiments.
paths:
/chat/completions:
post:
operationId: createChatCompletion
tags:
- Gateway
summary: Create a chat completion
description: >-
OpenAI-compatible chat completions through the Keywords AI gateway.
Routes to 250+ models behind a single endpoint, with optional streaming
(Server-Sent Events when `stream` is true), tool calling, structured
outputs, fallbacks, load balancing, caching, and automatic logging.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ChatCompletionRequest'
example:
model: gpt-4o-mini
messages:
- role: user
content: Reply with exactly ok.
max_tokens: 16
temperature: 0
responses:
'200':
description: A chat completion (or, when stream=true, an SSE stream of chunks).
content:
application/json:
schema:
$ref: '#/components/schemas/ChatCompletionResponse'
text/event-stream:
schema:
type: string
description: 'data-only Server-Sent Events terminated by a [DONE] sentinel.'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
/request-logs/:
post:
operationId: createRequestLog
tags:
- Logging
summary: Create a request log (span)
description: >-
Asynchronously ingest telemetry for an LLM call that was not routed
through the gateway proxy. The legacy alias `/request-logs/create/`
remains supported.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RequestLog'
example:
model: gpt-4o
prompt_messages:
- role: user
content: Hello
completion_message:
role: assistant
content: Hi there!
prompt_tokens: 8
completion_tokens: 4
cost: 0.00012
latency: 0.42
customer_identifier: user_123
responses:
'200':
description: Log accepted.
content:
application/json:
schema:
$ref: '#/components/schemas/SimpleMessage'
'401':
$ref: '#/components/responses/Unauthorized'
/prompts/:
post:
operationId: createPrompt
tags:
- Prompts
summary: Create a prompt
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PromptCreate'
example:
name: customer_support
responses:
'201':
description: Prompt created.
content:
application/json:
schema:
$ref: '#/components/schemas/Prompt'
'401':
$ref: '#/components/responses/Unauthorized'
get:
operationId: listPrompts
tags:
- Prompts
summary: List prompts
responses:
'200':
description: A list of prompts.
content:
application/json:
schema:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/Prompt'
/prompts/{prompt_id}/:
parameters:
- $ref: '#/components/parameters/PromptId'
get:
operationId: retrievePrompt
tags:
- Prompts
summary: Retrieve a prompt
responses:
'200':
description: A prompt.
content:
application/json:
schema:
$ref: '#/components/schemas/Prompt'
'404':
$ref: '#/components/responses/NotFound'
patch:
operationId: updatePrompt
tags:
- Prompts
summary: Update a prompt
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PromptCreate'
responses:
'200':
description: Prompt updated.
content:
application/json:
schema:
$ref: '#/components/schemas/Prompt'
delete:
operationId: deletePrompt
tags:
- Prompts
summary: Delete a prompt
responses:
'204':
description: Prompt deleted.
/prompts/{prompt_id}/versions/:
parameters:
- $ref: '#/components/parameters/PromptId'
post:
operationId: createPromptVersion
tags:
- Prompts
summary: Create a prompt version
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PromptVersion'
example:
model: gpt-4o
messages:
- role: system
content: You are a helpful {{role}} assistant.
temperature: 0.7
responses:
'201':
description: Prompt version created.
content:
application/json:
schema:
$ref: '#/components/schemas/PromptVersion'
get:
operationId: listPromptVersions
tags:
- Prompts
summary: List prompt versions
responses:
'200':
description: A list of prompt versions.
content:
application/json:
schema:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/PromptVersion'
/log_threads/:
post:
operationId: listThreads
tags:
- Threads
summary: List threads
description: Retrieve conversation threads matching the supplied filters, with pagination.
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/ListFilter'
responses:
'200':
description: A paginated list of threads.
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedList'
/traces/list/:
post:
operationId: listTraces
tags:
- Traces
summary: List traces
description: Retrieve traces (OpenTelemetry-aligned span trees) with filtering and pagination.
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/ListFilter'
responses:
'200':
description: A paginated list of traces.
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedList'
/traces/{trace_id}/:
parameters:
- name: trace_id
in: path
required: true
schema:
type: string
get:
operationId: retrieveTrace
tags:
- Traces
summary: Retrieve a trace
responses:
'200':
description: A trace with its spans.
content:
application/json:
schema:
$ref: '#/components/schemas/Trace'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteTrace
tags:
- Traces
summary: Delete a trace
responses:
'204':
description: Trace deleted.
/evaluators/:
post:
operationId: createEvaluator
tags:
- Evaluators
summary: Create an evaluator
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Evaluator'
responses:
'201':
description: Evaluator created.
content:
application/json:
schema:
$ref: '#/components/schemas/Evaluator'
/evaluators/list/:
post:
operationId: listEvaluators
tags:
- Evaluators
summary: List evaluators
description: Retrieve evaluators matching the supplied filters.
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/ListFilter'
responses:
'200':
description: A paginated list of evaluators.
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedList'
/evaluators/{evaluator_id}/run/:
parameters:
- name: evaluator_id
in: path
required: true
schema:
type: string
post:
operationId: runEvaluator
tags:
- Evaluators
summary: Run an evaluator
description: Execute an evaluator against supplied inputs/logs and return scores.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
input:
type: string
output:
type: string
metadata:
type: object
additionalProperties: true
responses:
'200':
description: Evaluation result with score(s).
content:
application/json:
schema:
$ref: '#/components/schemas/EvaluationResult'
/users/list/:
post:
operationId: listUsers
tags:
- Users
summary: List users (customers)
description: >-
Retrieve end-user (customer) records in your organization with analytics
and budget fields. Supports filtering by customer_identifier, name,
email, number_of_requests, total_tokens, total_cost, and active_days.
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: page_size
in: query
schema:
type: integer
default: 50
maximum: 1000
- name: environment
in: query
schema:
type: string
enum:
- prod
- test
requestBody:
required: false
content:
application/json:
schema:
$ref: '#/components/schemas/ListFilter'
responses:
'200':
description: A paginated list of users (customers).
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedList'
/datasets/:
post:
operationId: createDataset
tags:
- Datasets
summary: Create a dataset
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Dataset'
responses:
'201':
description: Dataset created.
content:
application/json:
schema:
$ref: '#/components/schemas/Dataset'
get:
operationId: listDatasets
tags:
- Datasets
summary: List datasets
responses:
'200':
description: A list of datasets.
content:
application/json:
schema:
type: object
properties:
results:
type: array
items:
$ref: '#/components/schemas/Dataset'
/experiments/:
post:
operationId: createExperiment
tags:
- Experiments
summary: Create an experiment
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Experiment'
responses:
'201':
description: Experiment created.
content:
application/json:
schema:
$ref: '#/components/schemas/Experiment'
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'Keywords AI API key supplied as the Authorization Bearer header (Authorization: Bearer <KEYWORDSAI_API_KEY>).'
parameters:
PromptId:
name: prompt_id
in: path
required: true
schema:
type: string
description: The prompt identifier (id or slug).
responses:
Unauthorized:
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
RateLimited:
description: Too many requests.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
Message:
type: object
required:
- role
- content
properties:
role:
type: string
enum:
- system
- user
- assistant
- tool
content:
type: string
name:
type: string
tool_calls:
type: array
items:
type: object
additionalProperties: true
ChatCompletionRequest:
type: object
required:
- model
- messages
properties:
model:
type: string
description: Model identifier (any of the 250+ supported models).
messages:
type: array
items:
$ref: '#/components/schemas/Message'
stream:
type: boolean
description: Stream the response token-by-token via Server-Sent Events.
default: false
temperature:
type: number
minimum: 0
maximum: 2
max_tokens:
type: integer
top_p:
type: number
frequency_penalty:
type: number
presence_penalty:
type: number
tools:
type: array
items:
type: object
additionalProperties: true
response_format:
type: object
additionalProperties: true
customer_identifier:
type: string
description: End-user identifier for per-user analytics and logging.
fallback_models:
type: array
items:
type: string
metadata:
type: object
additionalProperties: true
ChatCompletionResponse:
type: object
properties:
id:
type: string
object:
type: string
example: chat.completion
created:
type: integer
model:
type: string
choices:
type: array
items:
type: object
properties:
index:
type: integer
message:
$ref: '#/components/schemas/Message'
finish_reason:
type: string
usage:
type: object
properties:
prompt_tokens:
type: integer
completion_tokens:
type: integer
total_tokens:
type: integer
RequestLog:
type: object
required:
- model
properties:
model:
type: string
prompt_messages:
type: array
items:
$ref: '#/components/schemas/Message'
completion_message:
$ref: '#/components/schemas/Message'
input:
description: Universal input (string, object, or array).
output:
description: Universal output (string, object, or array).
prompt_tokens:
type: integer
completion_tokens:
type: integer
cost:
type: number
description: Request cost in USD; auto-calculated if omitted.
latency:
type: number
description: Total request latency in seconds.
customer_identifier:
type: string
status:
type: string
enum:
- success
- error
timestamp:
type: string
format: date-time
metadata:
type: object
additionalProperties: true
PromptCreate:
type: object
required:
- name
properties:
name:
type: string
description:
type: string
Prompt:
type: object
properties:
id:
type: string
name:
type: string
slug:
type: string
description:
type: string
current_version:
type: integer
created_at:
type: string
format: date-time
updated_at:
type: string
format: date-time
PromptVersion:
type: object
required:
- model
- messages
properties:
model:
type: string
messages:
type: array
items:
$ref: '#/components/schemas/Message'
description:
type: string
temperature:
type: number
max_tokens:
type: integer
top_p:
type: number
frequency_penalty:
type: number
presence_penalty:
type: number
variables:
type: object
additionalProperties: true
fallback_models:
type: array
items:
type: string
load_balance_models:
type: array
items:
type: object
additionalProperties: true
tools:
type: array
items:
type: object
additionalProperties: true
response_format:
type: object
additionalProperties: true
deploy:
type: boolean
Trace:
type: object
properties:
trace_id:
type: string
name:
type: string
start_time:
type: string
format: date-time
end_time:
type: string
format: date-time
spans:
type: array
items:
type: object
additionalProperties: true
Evaluator:
type: object
required:
- name
properties:
id:
type: string
name:
type: string
type:
type: string
description: Evaluator type (e.g. llm, code, human).
description:
type: string
definition:
type: object
additionalProperties: true
EvaluationResult:
type: object
properties:
evaluator_id:
type: string
score:
type: number
passed:
type: boolean
reason:
type: string
Dataset:
type: object
required:
- name
properties:
id:
type: string
name:
type: string
description:
type: string
created_at:
type: string
format: date-time
Experiment:
type: object
required:
- name
properties:
id:
type: string
name:
type: string
description:
type: string
columns:
type: array
items:
type: object
additionalProperties: true
ListFilter:
type: object
properties:
filters:
type: object
additionalProperties: true
page:
type: integer
default: 1
page_size:
type: integer
default: 50
sort_by:
type: string
PaginatedList:
type: object
properties:
count:
type: integer
next:
type: string
nullable: true
previous:
type: string
nullable: true
results:
type: array
items:
type: object
additionalProperties: true
SimpleMessage:
type: object
properties:
message:
type: string
Error:
type: object
properties:
error:
type: object
properties:
message:
type: string
type:
type: string
code:
type: string