curl --request POST \
--url https://api.trymorse.ai/v1/chat/completions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "kimi-k3",
"messages": [
{
"role": "system",
"content": "Answer in one sentence."
},
{
"role": "user",
"content": "What does a TEE attest?"
}
],
"max_completion_tokens": 200
}
'import requests
url = "https://api.trymorse.ai/v1/chat/completions"
payload = {
"model": "kimi-k3",
"messages": [
{
"role": "system",
"content": "Answer in one sentence."
},
{
"role": "user",
"content": "What does a TEE attest?"
}
],
"max_completion_tokens": 200
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'kimi-k3',
messages: [
{role: 'system', content: 'Answer in one sentence.'},
{role: 'user', content: 'What does a TEE attest?'}
],
max_completion_tokens: 200
})
};
fetch('https://api.trymorse.ai/v1/chat/completions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"id": "chatcmpl-YYOKD77FV2J75JOVRH6T77B4GZ",
"object": "chat.completion",
"created": 1792187800,
"model": "kimi-k3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "A TEE attests which code runs inside it, signed by keys the hardware vendor vouches for."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 19,
"total_tokens": 43
}
}{
"error": {
"message": "Media must be attached as inline data, not linked by URL.",
"type": "invalid_request_error",
"param": null,
"code": "remote_media"
}
}{
"error": {
"message": "Incorrect API key provided.",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}{
"error": {
"message": "The account balance does not cover the most this request could cost. Add credit, or set max_tokens or max_completion_tokens to lower the amount held.",
"type": "insufficient_balance",
"param": null,
"code": "insufficient_balance"
}
}{
"error": {
"message": "This account has been disabled. Contact support.",
"type": "invalid_request_error",
"param": null,
"code": "account_disabled"
}
}{
"error": {
"message": "The requested model does not exist.",
"type": "invalid_request_error",
"param": null,
"code": "model_not_found"
}
}{
"error": {
"message": "The request body did not arrive in time.",
"type": "invalid_request_error",
"param": null,
"code": "request_timeout"
}
}{
"error": {
"message": "Request body is too large.",
"type": "invalid_request_error",
"param": null,
"code": "request_too_large"
}
}{
"error": {
"message": "Rate limit reached for this account. Retry after the time in the Retry-After header.",
"type": "requests",
"param": null,
"code": "rate_limit_exceeded"
}
}{
"error": {
"message": "The upstream model server failed.",
"type": "upstream_error",
"param": null,
"code": "upstream_error"
}
}{
"error": {
"message": "The service is temporarily unable to authorize requests. Try again shortly.",
"type": "server_error",
"param": null,
"code": "service_unavailable"
}
}Create a chat completion
Sends a conversation to a model and returns the model’s reply, whole or as a stream. The request and the reply follow OpenAI’s chat completions format. Each field below notes where Morse differs.
Before the call, the account must hold enough credit for the most the request could cost, which is the prompt plus the output limit at the model’s prices. After the call, the account pays for the tokens the provider reports. If a stream stops early, the account pays for what the stream delivered. A retried request that reached the model costs again. Each reply’s X-Request-Id identifies the request.
curl --request POST \
--url https://api.trymorse.ai/v1/chat/completions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "kimi-k3",
"messages": [
{
"role": "system",
"content": "Answer in one sentence."
},
{
"role": "user",
"content": "What does a TEE attest?"
}
],
"max_completion_tokens": 200
}
'import requests
url = "https://api.trymorse.ai/v1/chat/completions"
payload = {
"model": "kimi-k3",
"messages": [
{
"role": "system",
"content": "Answer in one sentence."
},
{
"role": "user",
"content": "What does a TEE attest?"
}
],
"max_completion_tokens": 200
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: 'kimi-k3',
messages: [
{role: 'system', content: 'Answer in one sentence.'},
{role: 'user', content: 'What does a TEE attest?'}
],
max_completion_tokens: 200
})
};
fetch('https://api.trymorse.ai/v1/chat/completions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"id": "chatcmpl-YYOKD77FV2J75JOVRH6T77B4GZ",
"object": "chat.completion",
"created": 1792187800,
"model": "kimi-k3",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "A TEE attests which code runs inside it, signed by keys the hardware vendor vouches for."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 19,
"total_tokens": 43
}
}{
"error": {
"message": "Media must be attached as inline data, not linked by URL.",
"type": "invalid_request_error",
"param": null,
"code": "remote_media"
}
}{
"error": {
"message": "Incorrect API key provided.",
"type": "invalid_request_error",
"param": null,
"code": "invalid_api_key"
}
}{
"error": {
"message": "The account balance does not cover the most this request could cost. Add credit, or set max_tokens or max_completion_tokens to lower the amount held.",
"type": "insufficient_balance",
"param": null,
"code": "insufficient_balance"
}
}{
"error": {
"message": "This account has been disabled. Contact support.",
"type": "invalid_request_error",
"param": null,
"code": "account_disabled"
}
}{
"error": {
"message": "The requested model does not exist.",
"type": "invalid_request_error",
"param": null,
"code": "model_not_found"
}
}{
"error": {
"message": "The request body did not arrive in time.",
"type": "invalid_request_error",
"param": null,
"code": "request_timeout"
}
}{
"error": {
"message": "Request body is too large.",
"type": "invalid_request_error",
"param": null,
"code": "request_too_large"
}
}{
"error": {
"message": "Rate limit reached for this account. Retry after the time in the Retry-After header.",
"type": "requests",
"param": null,
"code": "rate_limit_exceeded"
}
}{
"error": {
"message": "The upstream model server failed.",
"type": "upstream_error",
"param": null,
"code": "upstream_error"
}
}{
"error": {
"message": "The service is temporarily unable to authorize requests. Try again shortly.",
"type": "server_error",
"param": null,
"code": "service_unavailable"
}
}Authorizations
An API key from the Morse app. It starts with sk_morse_.
Body
Only the fields below reach the model. Morse drops every other field without an error, such as temperature, top_p, n, stop, seed, response_format, logprobs, or user.
A chat model's id from GET /v1/models.
14096Show child attributes
Show child attributes
Send the reply as server-sent events.
Show child attributes
Show child attributes
The most output tokens the model may produce. Morse lowers a value above the model's max_output_tokens to max_output_tokens. When neither limit is set, the model's default applies. The account must hold credit for the most the request could cost, so a lower limit holds less credit.
x >= 1The same as max_completion_tokens. When both are set, max_completion_tokens wins.
x >= 1How much a reasoning model reasons, such as low, medium, or high. Anthropic, Gemini, and OpenAI models use the nearest effort they support. When reasoning_effort is absent, the model's default applies.
Show child attributes
Show child attributes
auto, none, required, or one named function.
auto, none, required Response
The reply. When stream is true, the body is server-sent events. Each data line is a ChatCompletionChunk, and the stream ends with data: [DONE]. If the provider fails after the first event, the stream ends with one error event in the Error shape and no [DONE]. Some reasoning models send a : keepalive comment every 25 seconds while they reason.
The reply. id is a new chatcmpl- id, and model is the id you sent. The exception is tee models, whose reply comes unchanged from the attested server.