Hemmingway Pricing Log in API platform

API

API docs

How to call Hemmingway-1.5 and Hemmingway-1 from your own code: an OpenAI-compatible endpoint, keys, streaming, thinking, pictures, limits and what it costs. The API is OpenAI-compatible, so most code that already talks to a model needs two lines changed. Keys and billing live on the API platform.

Quick start

The API is OpenAI-compatible. Send requests to https://hemmingway.io/v1 with a key from API keys and the model hemmingway-1.5.

curl https://hemmingway.io/v1/chat/completions \
  -H "Authorization: Bearer $HEMMINGWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "hemmingway-1.5",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

The Python and JavaScript examples use OpenAI's SDKs: pip install openai or npm install openai.

Authentication

Send the key as a Bearer token in the Authorization header:

Header
Authorization: Bearer hemmingway_live_...
  • Keys start with hemmingway_live_. An account can have 10.
  • A key is shown once, when you make it. Hemmingway keeps only a hash of it.
  • A key spends the credit of the account that made it, or that account's plan — you choose which when you make the key, and it doesn't change. See Keys on your plan.
  • Keep keys out of web pages and apps you hand out.
  • Revoke a key on the API keys page. Requests with it stop working at once.

Models

There are two models. hemmingway-1.5 is Hemmingway-1.5, the default: a request that names no model gets it. hemmingway-1 is Hemmingway-1, our first model. The old id hemmingway-27b still works and means Hemmingway-1. GET /v1/models lists them.

Request
curl https://hemmingway.io/v1/models \
  -H "Authorization: Bearer $HEMMINGWAY_API_KEY"
Response
{"object": "list", "data": [
  {"id": "hemmingway-1.5", "object": "model", "owned_by": "hemmingway"},
  {"id": "hemmingway-1", "object": "model", "owned_by": "hemmingway"},
  {"id": "hemmingway-27b", "object": "model", "owned_by": "hemmingway"}
]}

Chat completions

POST /v1/chat/completions takes the body of OpenAI's Chat Completions. These fields reach the model. Any other field is dropped.

FieldWhat it does
messagesRequired. The conversation in OpenAI's message format, with at least one message. A message's content may be a string, or a list of text and picture parts. See Images.
modelhemmingway-1.5 or hemmingway-1. With no model you get hemmingway-1.5. hemmingway-27b still means Hemmingway-1. The reply names the model you asked for.
max_tokens, max_completion_tokensThe most tokens to write, thinking included. Capped at 32,768, which is also the default.
streamtrue or false. See Streaming.
stream_options{"include_usage": true} adds a last chunk with the token counts.
temperature, top_p, top_k, min_pSampling. Hemmingway-1.5 runs at temperature 1.0 when you send none, as it was tested. A lower temperature makes its writing easier to tell from a person’s.
presence_penalty, frequency_penalty, repetition_penaltyPenalties for repeating.
stopText that ends the reply.
seedA number for repeatable sampling.
response_formatOpenAI's response_format, passed to the model.
tools, tool_choice, parallel_tool_callsFunction calling, in OpenAI's format.
reasoning_effort, enable_thinking, chat_template_kwargsThinking. See Thinking.

The reply is OpenAI's chat completion object. usage has the token counts, and the x-request-id header names the request.

Response
{
  "id": "...",
  "object": "chat.completion",
  "model": "hemmingway-1.5",
  "choices": [
    {"index": 0, "message": {"role": "assistant", "content": "Hello. What do you need?"}, "finish_reason": "stop"}
  ],
  "usage": {"prompt_tokens": 9, "completion_tokens": 41, "total_tokens": 50}
}

Writing like the app

The app and the API reach the same model, sampled the same way. What the app puts around the request is a system message of its own, a note on each message, and, when something has to be looked up, a pass through web search and page reading first. The API is the model alone, so it writes from what you send it: the closer the messages are to the job, the closer the reply is to the app's.

For prose — a post, a letter, a message to send — keep hemmingway-1.5, leave the thinking at Extra high (that asks for the plain-writing line in Thinking), and say the job in a system message, with the text itself in the user message:

curl https://hemmingway.io/v1/chat/completions \
  -H "Authorization: Bearer $HEMMINGWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "hemmingway-1.5",
    "reasoning_effort": "xhigh",
    "messages": [
      {"role": "system", "content": "You are an editor. Rewrite the text I send so it reads as though the person wrote it, keeping the meaning, the facts and their voice. Return only the rewritten text."},
      {"role": "user", "content": "<the post>"}
    ]
  }'
  • Leave temperature out. Hemmingway-1.5 runs at the 1.0 it was tested at, and a lower temperature makes its writing easier to tell from a person's.
  • The app also searches the web, reads pages and remembers things, and writes a reply again when it comes back broken. The API is the model only: an answer that needs today's facts needs the app.

Images

Both models read pictures. Give a message a list of parts instead of a string: text parts and image_url parts, in the order you want the model to read them. It answers in text.

IMG="data:image/jpeg;base64,$(base64 < photo.jpg | tr -d '\n')"

curl https://hemmingway.io/v1/chat/completions \
  -H "Authorization: Bearer $HEMMINGWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"hemmingway-1.5\",
    \"messages\": [{\"role\": \"user\", \"content\": [
      {\"type\": \"image_url\", \"image_url\": {\"url\": \"$IMG\"}},
      {\"type\": \"text\", \"text\": \"What is in this picture?\"}
    ]}]
  }"
  • A picture comes as a data: URL, data:image/...;base64,.... A link is turned away with a 400: the model machine would fetch the address itself, so it is never given one.
  • PNG, JPEG, WebP and GIF are read.
  • Up to 4 pictures in one request. A fifth is refused.
  • A picture costs input tokens, about one for every 32×32 pixels: a 512×512 picture is 256 tokens. The most is 1,600 — a picture larger than about 1280×1280 is scaled down to fit — and the least is 64. usage.prompt_tokens_details.multimodal_tokens counts them.
  • Pictures are charged at the input price, like text.
  • A body is at most 4 MB and base64 makes a picture a third larger, so keep the pictures in one request under about 3 MB together.
  • A part that is neither text nor image_url is refused.

Thinking

Both models think before they answer, at their highest level unless you ask for less. Hemmingway-1.5 was tested at every thinking level (off, low, medium and extra high) and passes AI detectors 9 times in 10 at each; enable_thinking: false turns thinking off. The thinking comes in reasoning_content, apart from content: on the message, or on each streamed delta.

  • reasoning_effort: low, medium or xhigh, the default. high is read as xhigh and minimal as low. Any other value is refused. At Extra high, asked for or left out, a line telling the model to write like a person goes into the system prompt, the same line the app gets; at Low or Medium, and with thinking off, it does not.
  • enable_thinking: false turns thinking off, at the top level of the body or in chat_template_kwargs.
  • chat_template_kwargs passes only enable_thinking, reasoning_effort and preserve_thinking. Earlier assistant messages sent back with their reasoning_content keep it in the prompt. With preserve_thinking: false, the thinking of those before your last message is left out.
  • Thinking is billed as output tokens and counts toward max_tokens.
# less thinking
curl https://hemmingway.io/v1/chat/completions \
  -H "Authorization: Bearer $HEMMINGWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "hemmingway-1.5", "messages": [{"role": "user", "content": "Hello"}], "reasoning_effort": "low"}'

# no thinking
curl https://hemmingway.io/v1/chat/completions \
  -H "Authorization: Bearer $HEMMINGWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "hemmingway-1.5", "messages": [{"role": "user", "content": "Hello"}], "enable_thinking": false}'

Streaming

With "stream": true the reply comes as server-sent events: data: lines with chat completion chunks, then data: [DONE].

  • With "stream_options": {"include_usage": true}, a last chunk has usage and no choices.
  • While nothing else comes, a : keep-alive comment line comes every 15 seconds. OpenAI's SDKs skip it.
  • A stream that sends nothing for 5 minutes is cut.
curl -N https://hemmingway.io/v1/chat/completions \
  -H "Authorization: Bearer $HEMMINGWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "hemmingway-1.5",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": true,
    "stream_options": {"include_usage": true}
  }'
Events
data: {"id":"...","object":"chat.completion.chunk","model":"hemmingway-1.5","choices":[{"index":0,"delta":{"role":"assistant","content":"Hello"},"finish_reason":null}]}

data: {"id":"...","object":"chat.completion.chunk","model":"hemmingway-1.5","choices":[{"index":0,"delta":{"content":". What do you need?"},"finish_reason":"stop"}]}

data: {"id":"...","object":"chat.completion.chunk","model":"hemmingway-1.5","choices":[],"usage":{"prompt_tokens":9,"completion_tokens":41,"total_tokens":50}}

data: [DONE]

Errors

An error answers with its HTTP status and a body like this. The message is written for people.

Error
{"error": {"code": "bad_request", "message": "messages must be a list with at least one message."}}
StatusCodeWhen
400bad_requestThe body isn't a JSON object, messages is missing or empty, stream isn't true or false, a picture isn't a data: URL, or the model couldn't take the request.
401bad_keyThe key is unknown or revoked.
401signed_outNo key was sent, or it doesn't start with hemmingway_live_.
402out_of_creditThe account's credit is used up. Add credit on the Billing page.
402no_planThe key draws on a plan, and the account has none any more. Choose a plan, or use a key that draws on credit.
403not_in_apiA key was sent to /v1/tools/. Web search is part of the Hemmingway app.
404not_foundThere is nothing at that address.
413bad_requestThe body is over 4 MB.
429allowanceA key on a plan, and the plan's 5-hour or weekly allowance is used up. resets_at says when it starts again.
429busyThe account already has as many requests running as it may. 8 for a key on credit; the plan's number for a key on a plan.
500server_errorSomething went wrong on Hemmingway's server. The error's rid names the request.
502model_unreachable, model_errorThe model didn't answer, or answered with an error. Try again in a minute.

Limits

  • 8 requests at once per account, across all its keys on credit. A key on a plan uses the plan's number, shared with the app.
  • max_tokens up to 32,768.
  • A request body up to 4 MB.
  • Up to 4 pictures in a request. See Images.
  • A request runs for 13 minutes at most. A stream that sends nothing for 5 minutes is cut.
  • 10 keys per account.
  • The model only. Web search and page reading are part of the Hemmingway app.

Pricing

Prices are in dollars per million tokens.

TokensPrice
Input$0.72
Cached input$0.072
Output, thinking included$2.70
  • A request is charged when it ends, from the token counts the model reports. A reply cut off before its counts is counted at about 4 characters a token.
  • A request the model never got costs nothing.
  • Each request's charge is rounded up to the next millionth of a dollar.
  • Requests are let in while the credit is above zero, so requests running at once can take it a little below zero.

Keys on your plan

On Plus, Pro or Max you can make a key that draws on your plan instead of on credit. It spends the same allowance the Hemmingway app spends, and costs nothing.

  • Choose it when you make the key, on the API keys page. A key can't be changed from one to the other afterwards.
  • Its requests count against your 5-hour and weekly allowance, together with everything you do in the app.
  • When an allowance is used up the key answers 429 allowance, with resets_at. It never falls back to credit.
  • It shares your plan's number of requests at once with the app, and waits in the same place in the queue.
  • It shows on the Usage page with its tokens and requests, at no cost.
  • If the plan ends, the key answers 402 no_plan until you take a plan again.

Cached input

The model machine reuses the start of a prompt it has seen recently: the same system prompt, the same chat so far. Those tokens are charged at the cached input price.

  • There is nothing to switch on. It happens by itself.
  • usage.prompt_tokens_details.cached_tokens says how many of the prompt_tokens were cached. The rest are charged as input.
  • A reply can come without cached_tokens. Then the whole prompt was charged as input.
  • Only the start of a prompt can be reused. Keep what stays the same first and what changes last.
Usage
"usage": {
  "prompt_tokens": 1200,
  "completion_tokens": 41,
  "total_tokens": 1241,
  "prompt_tokens_details": {"cached_tokens": 1104}
}

Credit

  • A key on credit is paid from prepaid credit. Add it on the Billing page: $5, $20, $50, $100 or any amount from $5. Prices include tax.
  • Credit lasts 12 months from when you buy it. The oldest credit is used first, and what is left of a purchase after 12 months expires.
  • Credit isn't refunded, except where the law requires it. See the Terms.

Hemmingway Unlocked's API

Hemmingway Unlocked, the adults-only side of Hemmingway, has its own OpenAI-compatible address: https://wise.hemmingway.io/v1. It answers with Unlocked's uncensored model, and it is for adults, 18 or over.

Request
curl https://wise.hemmingway.io/v1/chat/completions \
  -H "Authorization: Bearer $UNLOCKED_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "hemmingway-1", "messages": [{"role": "user", "content": "Hello"}]}'
  • Make the key inside Unlocked, in its account menu under API keys. A key needs an Unlocked membership. Keys made on the API platform don't reach Unlocked, and Unlocked's keys aren't listed there.
  • Any model works: an Unlocked key always reaches Unlocked's model. Replies name the model hemmingway-27b.
  • The body, streaming and errors are as above. A key spends the membership's allowance, as a key on your plan does.
  • Each request is checked against Unlocked's rules before the model answers. One that breaks them gets 403 wise_refused, and if the check can't run, 503 wise_broke. An account without a membership gets 403 not_in_wise.
  • In SillyTavern: Chat Completion, then Custom (OpenAI-compatible), then the address and the key. The set-up, step by step.

Powered by Hemmingway

Built something on Hemmingway? Put this on your site.

Powered by HemmingwayPowered by Hemmingway

HTML
<a href="https://hemmingway.io/?utm_source=powered-by"><img src="https://hemmingway.io/media/powered-by-hemmingway-light.svg" alt="Powered by Hemmingway" width="212" height="44"></a>

On a dark page, use powered-by-hemmingway-dark.svg.