MyApp

<back to all web services

ChatCompletion

AI

Chat Completions API (OpenAI-Compatible)

The following routes are available for this service:
POST/v1/chat/completions
# frozen_string_literal: true
# encoding: utf-8


require 'json'
require 'servicestack'


module ResponseFormat
    TEXT = 'Text'
    JSON_OBJECT = 'JsonObject'
end

module ToolType
    FUNCTION = 'Function'
end

# @DataContract
class AiContent
    include ServiceStack::DTO

    # @DataMember(Name="type")
    # @return [String]
    attr_accessor :type

    def self.properties
        {
            type: { name: 'type' },
        }
    end

end

#
# Annotations for the message, when applicable, as when using the web search tool.
#
# @DataContract
class UrlCitation
    include ServiceStack::DTO

    # @DataMember(Name="end_index")
    # @return [Integer]
    attr_accessor :end_index

    # @DataMember(Name="start_index")
    # @return [Integer]
    attr_accessor :start_index

    # @DataMember(Name="title")
    # @return [String]
    attr_accessor :title

    # @DataMember(Name="url")
    # @return [String]
    attr_accessor :url

    def self.properties
        {
            end_index: { name: 'end_index' },
            start_index: { name: 'start_index' },
            title: { name: 'title' },
            url: { name: 'url' },
        }
    end

end

#
# Annotations for the message, when applicable, as when using the web search tool.
#
# @DataContract
class ChoiceAnnotation
    include ServiceStack::DTO

    # @DataMember(Name="type")
    # @return [String]
    attr_accessor :type

    # @DataMember(Name="url_citation")
    # @return [UrlCitation]
    attr_accessor :url_citation

    def self.properties
        {
            type: { name: 'type' },
            url_citation: { name: 'url_citation', type: UrlCitation },
        }
    end

end

#
# If the audio output modality is requested, this object contains data about the audio response from the model.
#
# @DataContract
class ChoiceAudio
    include ServiceStack::DTO

    # @DataMember(Name="data")
    # @return [String]
    attr_accessor :data

    # @DataMember(Name="expires_at")
    # @return [Integer]
    attr_accessor :expires_at

    # @DataMember(Name="id")
    # @return [String]
    attr_accessor :id

    # @DataMember(Name="transcript")
    # @return [String]
    attr_accessor :transcript

    def self.properties
        {
            data: { name: 'data' },
            expires_at: { name: 'expires_at' },
            id: { name: 'id' },
            transcript: { name: 'transcript' },
        }
    end

end

#
# The function that the model called.
#
# @DataContract
class ToolFunction
    include ServiceStack::DTO

    # @DataMember(Name="name")
    # @return [String]
    attr_accessor :name

    # @DataMember(Name="arguments")
    # @return [String]
    attr_accessor :arguments

    def self.properties
        {
            name: { name: 'name' },
            arguments: { name: 'arguments' },
        }
    end

end

#
# The tool calls generated by the model, such as function calls.
#
# @DataContract
class ToolCall
    include ServiceStack::DTO

    # @DataMember(Name="id")
    # @return [String]
    attr_accessor :id

    # @DataMember(Name="type")
    # @return [String]
    attr_accessor :type

    # @DataMember(Name="function")
    # @return [ToolFunction]
    attr_accessor :function

    def self.properties
        {
            id: { name: 'id' },
            type: { name: 'type' },
            function: { name: 'function', type: ToolFunction },
        }
    end

end

# @DataContract
class ChoiceMessage
    include ServiceStack::DTO

    # @DataMember(Name="content")
    # @return [String]
    attr_accessor :content

    # @DataMember(Name="refusal")
    # @return [String]
    attr_accessor :refusal

    # @DataMember(Name="reasoning")
    # @return [String]
    attr_accessor :reasoning

    # @DataMember(Name="reasoning_content")
    # @return [String]
    attr_accessor :reasoning_content

    # @DataMember(Name="thinking")
    # @return [String]
    attr_accessor :thinking

    # @DataMember(Name="role")
    # @return [String]
    attr_accessor :role

    # @DataMember(Name="timestamp")
    # @return [Integer]
    attr_accessor :timestamp

    # @DataMember(Name="tool_call_id")
    # @return [String]
    attr_accessor :tool_call_id

    # @DataMember(Name="images")
    # @return [List]
    attr_accessor :images

    # @DataMember(Name="audios")
    # @return [List]
    attr_accessor :audios

    # @DataMember(Name="files")
    # @return [List]
    attr_accessor :files

    # @DataMember(Name="annotations")
    # @return [List]
    attr_accessor :annotations

    # @DataMember(Name="audio")
    # @return [ChoiceAudio]
    attr_accessor :audio

    # @DataMember(Name="tool_calls")
    # @return [List]
    attr_accessor :tool_calls

    def self.properties
        {
            content: { name: 'content' },
            refusal: { name: 'refusal' },
            reasoning: { name: 'reasoning' },
            reasoning_content: { name: 'reasoning_content' },
            thinking: { name: 'thinking' },
            role: { name: 'role' },
            timestamp: { name: 'timestamp' },
            tool_call_id: { name: 'tool_call_id' },
            images: { name: 'images', type: [AiContent] },
            audios: { name: 'audios', type: [AiContent] },
            files: { name: 'files', type: [AiContent] },
            annotations: { name: 'annotations', type: [ChoiceAnnotation] },
            audio: { name: 'audio', type: ChoiceAudio },
            tool_calls: { name: 'tool_calls', type: [ToolCall] },
        }
    end

end

#
# A list of message content tokens with log probability information.
#
# @DataContract
class LogprobItem
    include ServiceStack::DTO

    # @DataMember(Name="token")
    # @return [String]
    attr_accessor :token

    # @DataMember(Name="logprob")
    # @return [Float]
    attr_accessor :logprob

    # @DataMember(Name="bytes")
    # @return [String]
    attr_accessor :bytes

    # @DataMember(Name="top_logprobs")
    # @return [List]
    attr_accessor :top_logprobs

    def self.properties
        {
            token: { name: 'token' },
            logprob: { name: 'logprob' },
            bytes: { name: 'bytes' },
            top_logprobs: { name: 'top_logprobs', type: [LogprobItem] },
        }
    end

end

#
# Log probability information for the choice.
#
# @DataContract
class Logprobs
    include ServiceStack::DTO

    # @DataMember(Name="content")
    # @return [List]
    attr_accessor :content

    def self.properties
        {
            content: { name: 'content', type: [LogprobItem] },
        }
    end

end

# @DataContract
class Choice
    include ServiceStack::DTO

    # @DataMember(Name="finish_reason")
    # @return [String]
    attr_accessor :finish_reason

    # @DataMember(Name="index")
    # @return [Integer]
    attr_accessor :index

    # @DataMember(Name="message")
    # @return [ChoiceMessage]
    attr_accessor :message

    # @DataMember(Name="logprobs")
    # @return [Logprobs]
    attr_accessor :logprobs

    def self.properties
        {
            finish_reason: { name: 'finish_reason' },
            index: { name: 'index' },
            message: { name: 'message', type: ChoiceMessage },
            logprobs: { name: 'logprobs', type: Logprobs },
        }
    end

end

#
# Usage statistics for the completion request.
#
# @DataContract
class AiCompletionUsage
    include ServiceStack::DTO

    # @DataMember(Name="accepted_prediction_tokens")
    # @return [Integer]
    attr_accessor :accepted_prediction_tokens

    # @DataMember(Name="audio_tokens")
    # @return [Integer]
    attr_accessor :audio_tokens

    # @DataMember(Name="reasoning_tokens")
    # @return [Integer]
    attr_accessor :reasoning_tokens

    # @DataMember(Name="rejected_prediction_tokens")
    # @return [Integer]
    attr_accessor :rejected_prediction_tokens

    def self.properties
        {
            accepted_prediction_tokens: { name: 'accepted_prediction_tokens' },
            audio_tokens: { name: 'audio_tokens' },
            reasoning_tokens: { name: 'reasoning_tokens' },
            rejected_prediction_tokens: { name: 'rejected_prediction_tokens' },
        }
    end

end

#
# Breakdown of tokens used in the prompt.
#
# @DataContract
class AiPromptUsage
    include ServiceStack::DTO

    # @DataMember(Name="accepted_prediction_tokens")
    # @return [Integer]
    attr_accessor :accepted_prediction_tokens

    # @DataMember(Name="audio_tokens")
    # @return [Integer]
    attr_accessor :audio_tokens

    # @DataMember(Name="cached_tokens")
    # @return [Integer]
    attr_accessor :cached_tokens

    def self.properties
        {
            accepted_prediction_tokens: { name: 'accepted_prediction_tokens' },
            audio_tokens: { name: 'audio_tokens' },
            cached_tokens: { name: 'cached_tokens' },
        }
    end

end

#
# Usage statistics for the completion request.
#
# @DataContract
class AiUsage
    include ServiceStack::DTO

    # @DataMember(Name="completion_tokens")
    # @return [Integer]
    attr_accessor :completion_tokens

    # @DataMember(Name="prompt_tokens")
    # @return [Integer]
    attr_accessor :prompt_tokens

    # @DataMember(Name="total_tokens")
    # @return [Integer]
    attr_accessor :total_tokens

    # @DataMember(Name="completion_tokens_details")
    # @return [AiCompletionUsage]
    attr_accessor :completion_tokens_details

    # @DataMember(Name="prompt_tokens_details")
    # @return [AiPromptUsage]
    attr_accessor :prompt_tokens_details

    # @DataMember(Name="duration")
    # @return [Integer]
    attr_accessor :duration

    def self.properties
        {
            completion_tokens: { name: 'completion_tokens' },
            prompt_tokens: { name: 'prompt_tokens' },
            total_tokens: { name: 'total_tokens' },
            completion_tokens_details: { name: 'completion_tokens_details', type: AiCompletionUsage },
            prompt_tokens_details: { name: 'prompt_tokens_details', type: AiPromptUsage },
            duration: { name: 'duration' },
        }
    end

end

# @DataContract
class ChatResponse
    include ServiceStack::DTO

    # @DataMember(Name="id")
    # @return [String]
    attr_accessor :id

    # @DataMember(Name="choices")
    # @return [List]
    attr_accessor :choices

    # @DataMember(Name="created")
    # @return [Integer]
    attr_accessor :created

    # @DataMember(Name="model")
    # @return [String]
    attr_accessor :model

    # @DataMember(Name="system_fingerprint")
    # @return [String]
    attr_accessor :system_fingerprint

    # @DataMember(Name="object")
    # @return [String]
    attr_accessor :object

    # @DataMember(Name="service_tier")
    # @return [String]
    attr_accessor :service_tier

    # @DataMember(Name="usage")
    # @return [AiUsage]
    attr_accessor :usage

    # @DataMember(Name="provider")
    # @return [String]
    attr_accessor :provider

    # @DataMember(Name="cost")
    # @return [Float]
    attr_accessor :cost

    # @DataMember(Name="tool_history")
    # @return [List]
    attr_accessor :tool_history

    # @DataMember(Name="metadata")
    # @return [Dictionary]
    attr_accessor :metadata

    # @DataMember(Name="responseStatus")
    # @return [ServiceStack::ResponseStatus]
    attr_accessor :response_status

    def self.properties
        {
            id: { name: 'id' },
            choices: { name: 'choices', type: [Choice] },
            created: { name: 'created' },
            model: { name: 'model' },
            system_fingerprint: { name: 'system_fingerprint' },
            object: { name: 'object' },
            service_tier: { name: 'service_tier' },
            usage: { name: 'usage', type: AiUsage },
            provider: { name: 'provider' },
            cost: { name: 'cost' },
            tool_history: { name: 'tool_history', type: [ChoiceMessage] },
            metadata: { name: 'metadata' },
            response_status: { name: 'responseStatus', type: ServiceStack::ResponseStatus },
        }
    end

end

#
# A list of messages comprising the conversation so far.
#
# @DataContract
class AiMessage
    include ServiceStack::DTO

    # @DataMember(Name="content")
    # @return [List]
    attr_accessor :content

    # @DataMember(Name="role")
    # @return [String]
    attr_accessor :role

    # @DataMember(Name="name")
    # @return [String]
    attr_accessor :name

    # @DataMember(Name="tool_calls")
    # @return [List]
    attr_accessor :tool_calls

    # @DataMember(Name="tool_call_id")
    # @return [String]
    attr_accessor :tool_call_id

    # @DataMember(Name="reasoning")
    # @return [String]
    attr_accessor :reasoning

    # @DataMember(Name="reasoning_content")
    # @return [String]
    attr_accessor :reasoning_content

    # @DataMember(Name="timestamp")
    # @return [Integer]
    attr_accessor :timestamp

    # @DataMember(Name="images")
    # @return [List]
    attr_accessor :images

    def self.properties
        {
            content: { name: 'content', type: [AiContent] },
            role: { name: 'role' },
            name: { name: 'name' },
            tool_calls: { name: 'tool_calls', type: [ToolCall] },
            tool_call_id: { name: 'tool_call_id' },
            reasoning: { name: 'reasoning' },
            reasoning_content: { name: 'reasoning_content' },
            timestamp: { name: 'timestamp' },
            images: { name: 'images', type: [AiContent] },
        }
    end

end

#
# Parameters for audio output. Required when audio output is requested with modalities: [audio]
#
# @DataContract
class AiChatAudio
    include ServiceStack::DTO

    # @DataMember(Name="format")
    # @return [String]
    attr_accessor :format

    # @DataMember(Name="voice")
    # @return [String]
    attr_accessor :voice

    def self.properties
        {
            format: { name: 'format' },
            voice: { name: 'voice' },
        }
    end

end

# @DataContract
class AiResponseFormat
    include ServiceStack::DTO

    # @DataMember(Name="type")
    # @return [ResponseFormat]
    attr_accessor :type

    def self.properties
        {
            type: { name: 'type' },
        }
    end

end

# @DataContract
class AiToolFunction
    include ServiceStack::DTO

    # @DataMember(Name="name")
    # @return [String]
    attr_accessor :name

    # @DataMember(Name="description")
    # @return [String]
    attr_accessor :description

    # @DataMember(Name="parameters")
    # @return [Dictionary]
    attr_accessor :parameters

    def self.properties
        {
            name: { name: 'name' },
            description: { name: 'description' },
            parameters: { name: 'parameters' },
        }
    end

end

# @DataContract
class Tool
    include ServiceStack::DTO

    # @DataMember(Name="type")
    # @return [ToolType]
    attr_accessor :type

    # @DataMember(Name="function")
    # @return [AiToolFunction]
    attr_accessor :function

    def self.properties
        {
            type: { name: 'type' },
            function: { name: 'function', type: AiToolFunction },
        }
    end

end

#
# Chat Completions API (OpenAI-Compatible)
#
# @DataContract
class ChatCompletion
    include ServiceStack::DTO

    # @DataMember(Name="messages")
    # @return [List]
    attr_accessor :messages

    # @DataMember(Name="model")
    # @return [String]
    attr_accessor :model

    # @DataMember(Name="audio")
    # @return [AiChatAudio]
    attr_accessor :audio

    # @DataMember(Name="logit_bias")
    # @return [Dictionary]
    attr_accessor :logit_bias

    # @DataMember(Name="metadata")
    # @return [Dictionary]
    attr_accessor :metadata

    # @DataMember(Name="reasoning_effort")
    # @return [String]
    attr_accessor :reasoning_effort

    # @DataMember(Name="response_format")
    # @return [AiResponseFormat]
    attr_accessor :response_format

    # @DataMember(Name="service_tier")
    # @return [String]
    attr_accessor :service_tier

    # @DataMember(Name="safety_identifier")
    # @return [String]
    attr_accessor :safety_identifier

    # @DataMember(Name="stop")
    # @return [List]
    attr_accessor :stop

    # @DataMember(Name="modalities")
    # @return [List]
    attr_accessor :modalities

    # @DataMember(Name="prompt_cache_key")
    # @return [String]
    attr_accessor :prompt_cache_key

    # @DataMember(Name="tools")
    # @return [List]
    attr_accessor :tools

    # @DataMember(Name="verbosity")
    # @return [String]
    attr_accessor :verbosity

    # @DataMember(Name="temperature")
    # @return [Float]
    attr_accessor :temperature

    # @DataMember(Name="max_completion_tokens")
    # @return [Integer]
    attr_accessor :max_completion_tokens

    # @DataMember(Name="top_logprobs")
    # @return [Integer]
    attr_accessor :top_logprobs

    # @DataMember(Name="top_p")
    # @return [Float]
    attr_accessor :top_p

    # @DataMember(Name="frequency_penalty")
    # @return [Float]
    attr_accessor :frequency_penalty

    # @DataMember(Name="presence_penalty")
    # @return [Float]
    attr_accessor :presence_penalty

    # @DataMember(Name="seed")
    # @return [Integer]
    attr_accessor :seed

    # @DataMember(Name="n")
    # @return [Integer]
    attr_accessor :n

    # @DataMember(Name="store")
    # @return [TrueClass]
    attr_accessor :store

    # @DataMember(Name="logprobs")
    # @return [TrueClass]
    attr_accessor :logprobs

    # @DataMember(Name="parallel_tool_calls")
    # @return [TrueClass]
    attr_accessor :parallel_tool_calls

    # @DataMember(Name="enable_thinking")
    # @return [TrueClass]
    attr_accessor :enable_thinking

    # @DataMember(Name="stream")
    # @return [TrueClass]
    attr_accessor :stream

    def self.properties
        {
            messages: { name: 'messages', type: [AiMessage] },
            model: { name: 'model' },
            audio: { name: 'audio', type: AiChatAudio },
            logit_bias: { name: 'logit_bias' },
            metadata: { name: 'metadata' },
            reasoning_effort: { name: 'reasoning_effort' },
            response_format: { name: 'response_format', type: AiResponseFormat },
            service_tier: { name: 'service_tier' },
            safety_identifier: { name: 'safety_identifier' },
            stop: { name: 'stop' },
            modalities: { name: 'modalities' },
            prompt_cache_key: { name: 'prompt_cache_key' },
            tools: { name: 'tools', type: [Tool] },
            verbosity: { name: 'verbosity' },
            temperature: { name: 'temperature' },
            max_completion_tokens: { name: 'max_completion_tokens' },
            top_logprobs: { name: 'top_logprobs' },
            top_p: { name: 'top_p' },
            frequency_penalty: { name: 'frequency_penalty' },
            presence_penalty: { name: 'presence_penalty' },
            seed: { name: 'seed' },
            n: { name: 'n' },
            store: { name: 'store' },
            logprobs: { name: 'logprobs' },
            parallel_tool_calls: { name: 'parallel_tool_calls' },
            enable_thinking: { name: 'enable_thinking' },
            stream: { name: 'stream' },
        }
    end

    def response_type() = ChatResponse
    def get_type_name() = 'ChatCompletion'
end

Ruby ChatCompletion DTOs

To override the Content-type in your clients, use the HTTP Accept Header, append the .csv suffix or ?format=csv

HTTP + CSV

The following are sample HTTP requests and responses. The placeholders shown need to be replaced with actual values.

POST /v1/chat/completions HTTP/1.1 
Host: blazor-vue.web-templates.io 
Accept: text/csv
Content-Type: text/csv
Content-Length: length

{"messages":[{"content":[{}],"role":"String","name":"String","tool_calls":[{"id":"String","type":"String","function":{"name":"String","arguments":"String"}}],"tool_call_id":"String","reasoning":"String","reasoning_content":"String","timestamp":0,"images":[{}]}],"model":"String","audio":{"format":"String","voice":"String"},"logit_bias":{"0":0},"metadata":{"String":"String"},"reasoning_effort":"String","response_format":{"type":"text"},"service_tier":"String","safety_identifier":"String","stop":["String"],"modalities":["String"],"prompt_cache_key":"String","tools":[{"type":"function","function":{"name":"String","description":"String","parameters":{"String":{}}}}],"verbosity":"String","temperature":0,"max_completion_tokens":0,"top_logprobs":0,"top_p":0,"frequency_penalty":0,"presence_penalty":0,"seed":0,"n":0,"store":false,"logprobs":false,"parallel_tool_calls":false,"enable_thinking":false,"stream":false}
HTTP/1.1 200 OK
Content-Type: text/csv
Content-Length: length

{"id":"String","choices":[{"finish_reason":"String","index":0,"message":{"content":"String","refusal":"String","reasoning":"String","reasoning_content":"String","thinking":"String","role":"String","timestamp":0,"tool_call_id":"String","images":[{}],"audios":[{}],"files":[{}],"annotations":[{"type":"String","url_citation":{"end_index":0,"start_index":0,"title":"String","url":"String"}}],"audio":{"data":"String","expires_at":0,"id":"String","transcript":"String"},"tool_calls":[{"id":"String","type":"String","function":{"name":"String","arguments":"String"}}]},"logprobs":{"content":[{"token":"String","logprob":0,"bytes":"AA==","top_logprobs":[{"token":"String","logprob":0,"bytes":"AA==","top_logprobs":[{"token":"String","logprob":0,"bytes":"AA=="}]}]}]}}],"created":0,"model":"String","system_fingerprint":"String","object":"String","service_tier":"String","usage":{"completion_tokens":0,"prompt_tokens":0,"total_tokens":0,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"cached_tokens":0},"duration":0},"provider":"String","cost":0,"tool_history":[{"content":"String","refusal":"String","reasoning":"String","reasoning_content":"String","thinking":"String","role":"String","timestamp":0,"tool_call_id":"String","images":[{}],"audios":[{}],"files":[{}],"annotations":[{"type":"String","url_citation":{"end_index":0,"start_index":0,"title":"String","url":"String"}}],"audio":{"data":"String","expires_at":0,"id":"String","transcript":"String"},"tool_calls":[{"id":"String","type":"String","function":{"name":"String","arguments":"String"}}]}],"metadata":{"String":"String"},"responseStatus":{"errorCode":"String","message":"String","stackTrace":"String","errors":[{"errorCode":"String","fieldName":"String","message":"String","meta":{"String":"String"}}],"meta":{"String":"String"}}}