agentsclimarketplace

Together webhooks events

Skill jeremylongshore/claude-code-plugins-plus-skills/plugins/saas-packs/together-pack/skills/together-webhooks-events

'Together AI webhooks events for inference, fine-tuning, and model deployment.From its SKILL.md

Install
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill together-webhooks-events

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

4.1 KB, 895 tokens by cl100k_base, as published. Nobody here has run it

Together AI Webhooks & Events

Overview

Together AI delivers webhook callbacks for asynchronous operations including fine-tuning jobs, batch inference, and model lifecycle events. Subscribe to events for fine-tune completion, job failures, model deprecation notices, and batch processing status to build automated ML pipelines without polling the jobs API.

Webhook Registration

const response = await fetch("https://api.together.xyz/v1/webhooks", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.TOGETHER_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://yourapp.com/webhooks/together",
    events: ["fine_tune.completed", "fine_tune.failed", "model.deprecated", "batch.done"],
    secret: process.env.TOGETHER_WEBHOOK_SECRET,
  }),
});

Signature Verification

import crypto from "crypto";
import { Request, Response, NextFunction } from "express";

function verifyTogetherSignature(req: Request, res: Response, next: NextFunction) {
  const signature = req.headers["x-together-signature"] as string;
  const expected = crypto.createHmac("sha256", process.env.TOGETHER_WEBHOOK_SECRET!)
    .update(req.body).digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).json({ error: "Invalid signature" });
  }
  next();
}

Event Handler

import express from "express";
const app = express();

app.post("/webhooks/together", express.raw({ type: "application/json" }), verifyTogetherSignature, (req, res) => {
  const event = JSON.parse(req.body.toString());
  res.status(200).json({ received: true });

  switch (event.type) {
    case "fine_tune.completed":
      deployModel(event.data.fine_tune_id, event.data.model_name); break;
    case "fine_tune.failed":
      alertTeam(event.data.fine_tune_id, event.data.error_message); break;
    case "model.deprecated":
      migratePipelines(event.data.model_id, event.data.replacement_model); break;
    case "batch.done":
      collectResults(event.data.batch_id, event.data.output_url); break;
  }
});

Event Types

EventPayload FieldsUse Case
fine_tune.completedfine_tune_id, model_name, eval_lossAuto-deploy fine-tuned model
fine_tune.failedfine_tune_id, error_message, stepAlert team and retry with adjusted params
model.deprecatedmodel_id, replacement_model, sunset_dateMigrate inference pipelines proactively
batch.donebatch_id, output_url, total_tokensDownload batch results and update billing
fine_tune.checkpointfine_tune_id, step, lossMonitor training progress in real time

Retry & Idempotency

const processed = new Set<string>();

async function handleIdempotent(event: { id: string; type: string; data: any }) {
  if (processed.has(event.id)) return;
  await routeEvent(event);
  processed.add(event.id);
  if (processed.size > 10_000) {
    const entries = Array.from(processed);
    entries.slice(0, entries.length - 10_000).forEach((id) => processed.delete(id));
  }
}

Error Handling

IssueCauseFix
401 UnauthorizedInvalid or expired API keyRotate key at api.together.xyz
Fine-tune stuckTraining data format issuesValidate JSONL before submission
Batch timeoutLarge batch exceeds time limitSplit into smaller batches
Model not foundDeprecated without migrationCheck model.deprecated events proactively

Resources

Next Steps

See together-security-basics.

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,144. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.