Webhooks

Receive real-time notifications when events happen in your account. No polling required.

🤖

Event Occurs

📡

We Send POST

🖥️

Your Server

Process Event

Event Types

Subscribe to the events you care about:

batch.completed

Batch processing job finished. Access results and handle any errors.

batch.failed

Batch processing job failed. Review error details and retry if needed.

fine_tuning.job.created

New fine-tuning job started. Track progress and estimated completion.

fine_tuning.job.succeeded

Fine-tuning completed successfully. Your model is ready to use.

fine_tuning.job.failed

Fine-tuning failed. Check error logs and training data.

usage.threshold.reached

Usage threshold hit. Set up alerts to monitor costs.

Setting Up Webhooks

  1. 1

    Create an Endpoint

    Set up an HTTPS endpoint on your server to receive POST requests. Must return 2xx status within 30 seconds.

  2. 2

    Register the Webhook

    Go to Dashboard → Settings → Webhooks and add your endpoint URL. Select which events to receive.

  3. 3

    Verify Signatures

    Validate incoming webhooks using the signing secret to ensure they're from MythicDot.AI.

Payload Format

All webhook events follow the same structure:

Webhook Payload
{
  "id": "evt_abc123xyz789",
  "type": "batch.completed",
  "created": 1706140800,
  "data": {
    "object": {
      "id": "batch_abc123",
      "status": "completed",
      "request_counts": {
        "total": 1000,
        "completed": 998,
        "failed": 2
      },
      "output_file_id": "file_xyz789"
    }
  }
}

Handling Webhooks

Python (Flask)
from flask import Flask, request
import hmac
import hashlib

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_..."

@app.route("/webhook", methods=["POST"])
def webhook():
    # Verify signature
    signature = request.headers.get("X-MythicDot-Signature")
    payload = request.get_data()
    
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    if not hmac.compare_digest(signature, expected):
        return "Invalid signature", 401
    
    # Process the event
    event = request.json
    event_type = event["type"]
    
    if event_type == "batch.completed":
        batch_id = event["data"]["object"]["id"]
        print(f"Batch {batch_id} completed!")
        # Download and process results...
    
    elif event_type == "fine_tuning.job.succeeded":
        model_id = event["data"]["object"]["fine_tuned_model"]
        print(f"Model ready: {model_id}")
    
    return "OK", 200

Security Best Practices

🔒 Securing Your Webhooks
  • Always verify signatures — Use HMAC-SHA256 to validate all incoming requests.
  • Use HTTPS — Webhook endpoints must use TLS encryption.
  • Respond quickly — Return 2xx within 30 seconds. Process async if needed.
  • Handle duplicates — Use event IDs for idempotency. Same event may be sent twice.
  • Keep secrets secure — Never log or expose your webhook signing secret.

Retry Policy

If your endpoint doesn't respond with 2xx, we'll retry with exponential backoff:

Attempt Delay Time from Event
1 (initial) Immediate 0 min
2 5 minutes 5 min
3 30 minutes 35 min
4 2 hours 2.5 hours
5 (final) 8 hours ~10 hours

💡 Debugging Webhooks

Use the Dashboard → Webhooks → Logs to see delivery attempts, payloads, and response codes. You can also manually retry failed deliveries.