Together AI Free code examples in Python and JavaScript
Hosted open models with fine-tuning and dedicated endpoints.
WHAT THIS PAGE COVERS
Fine-tuning an open model on your own data end to end.
meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo
together
Model ids change. If a sample returns a 404 on the model, that is the first thing to check against the official docs.
The client reads TOGETHER_API_KEY on construction. The same package covers inference and the fine-tuning API.
pip install together
export TOGETHER_API_KEY="your-key" # macOS / Linux
setx TOGETHER_API_KEY "your-key" # Windows, then open a new shell
Model ids are the full Hugging Face path. The response shape is OpenAI's, so an existing client works too — point it at https://api.together.ai/v1.
import os
from together import Together
client = Together(api_key=os.environ["TOGETHER_API_KEY"])
completion = client.chat.completions.create(
model="meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
messages=[{"role": "user", "content": "Explain a database index."}],
)
print(completion.choices[0].message.content)
JSONL, one conversation per line. THE FORMAT IS THE WORK: a few hundred genuinely representative examples beat tens of thousands of scraped ones, and every example should look exactly like what you will send at inference time.
import json
# Each line is one complete conversation. Include the system message
# if you will send one at inference — the model learns the shape it
# is trained on, and a mismatch at run time undoes the training.
examples = [
{
"messages": [
{"role": "system", "content": "You triage pump faults."},
{"role": "user", "content": "Pump stalled, code E-4471."},
{"role": "assistant", "content": "SEVERITY: high\nCAUSE: impeller jam"},
]
},
]
with open("train.jsonl", "w", encoding="utf-8") as handle:
for example in examples:
handle.write(json.dumps(example) + "\n")
# Check it before spending anything on a job.
uploaded = client.files.upload(file="train.jsonl", check=True)
print(uploaded.id)
LoRA by default: an adapter, not a new copy of the model. Cheaper, faster, and it cannot damage the base model — which matters the first few times when the data is not as clean as you think.
job = client.fine_tuning.create(
training_file=uploaded.id,
model="meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
lora=True, # adapter, not a full fine-tune
n_epochs=3, # more than ~4 usually overfits
learning_rate=1e-5,
suffix="pump-triage", # becomes part of the model id
)
print(job.id, job.status)
The finished job carries a model id you call exactly like any other. Nothing else about the request changes — which is what makes a fine-tune easy to A/B against the base model.
import time
while True:
status = client.fine_tuning.retrieve(job.id)
print(status.status)
if status.status in {"completed", "error", "cancelled"}:
break
time.sleep(30)
if status.status != "completed":
raise RuntimeError(f"fine-tune {status.status}")
# Same call, different model id. Run the old one alongside it before
# replacing anything.
completion = client.chat.completions.create(
model=status.output_name,
messages=[{"role": "user", "content": "Pump stalled, code E-4471."}],
)
print(completion.choices[0].message.content)
THE PACKAGE IS together-ai, with the suffix. The bare `together` name on npm is an unrelated project.
npm install together-ai
export TOGETHER_API_KEY="your-key"
The response is OpenAI-shaped. Streaming is server-sent events — pass stream: true and iterate.
import Together from "together-ai";
const client = new Together({ apiKey: process.env.TOGETHER_API_KEY });
const completion = await client.chat.completions.create({
model: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
messages: [{ role: "user", content: "Explain a database index." }],
});
console.log(completion.choices[0].message.content);
JSONL, one conversation per line, matching what you will send at inference. A few hundred representative examples beat a large scraped set — and the mismatch between training shape and request shape is the usual reason a fine-tune underperforms.
import { writeFile } from "node:fs/promises";
const examples = [
{
messages: [
{ role: "system", content: "You triage pump faults." },
{ role: "user", content: "Pump stalled, code E-4471." },
{ role: "assistant", content: "SEVERITY: high\nCAUSE: impeller jam" },
],
},
];
await writeFile(
"train.jsonl",
examples.map((example) => JSON.stringify(example)).join("\n") + "\n",
);
const uploaded = await client.files.upload({
file: "train.jsonl",
purpose: "fine-tune",
});
LoRA first, always. And BEFORE running a job at all: if a better prompt or a retrieval step gets you there, that is cheaper, reversible and does not go stale.
const job = await client.fineTune.create({
training_file: uploaded.id,
model: "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
lora: true,
n_epochs: 3,
suffix: "pump-triage",
});
// Worth fine-tuning for:
// a fixed output shape the model keeps drifting from
// a house style or tone that a prompt cannot hold across turns
// domain vocabulary the base model mangles
//
// NOT worth fine-tuning for:
// facts that change -> retrieval
// a one-off instruction -> the prompt
// "it is not smart enough" -> a bigger base model
console.log(job.id, job.status);
The finished job's output name is a model id like any other. Keep the base model's call alongside it for a while — a fine-tune that is better on your examples and worse in general is a common and quiet outcome.
let status;
do {
await new Promise((resolve) => setTimeout(resolve, 30_000));
status = await client.fineTune.retrieve(job.id);
console.log(status.status);
} while (!["completed", "error", "cancelled"].includes(status.status));
if (status.status !== "completed") {
throw new Error(`fine-tune ${status.status}`);
}
// Run both and compare on held-out examples before switching.
for (const model of [
"meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo",
status.output_name,
]) {
const completion = await client.chat.completions.create({
model,
messages: [{ role: "user", content: "Pump stalled, code E-4471." }],
});
console.log(model, "->", completion.choices[0].message.content);
}
QUESTIONS
Which languages are the Together AI examples in?
Python and JavaScript. Every sample runs as pasted and reads its credentials from an environment variable — no key is ever written into the code.
Which package do I install for Together AI?
The samples use together. The install step on each language tab gives the exact command.
Which Together AI model do these examples use?
meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo, checked against the official documentation on 26 September 2026. Model ids change often; if a call returns a model-not-found error, check the current list in the official docs.
Where is the official Together AI documentation?
https://docs.together.ai/ — it is linked at the bottom of this page, and it is the authority whenever it disagrees with a sample here.
ALSO IN HOSTING, GATEWAYS & LOCAL
The authority
Official Together AI documentation
Model names, pricing and rate limits change faster than any page here can. When this page and the official docs disagree, the official docs are right.
https://docs.together.ai/