← back to slashed.pro /SLASHEDDOCS Get key →
// Docs · Migrate · qua- → sl-

qua- → sl-.

If you are already calling Quatarly through the OpenAI SDK, this is a four-minute migration. The body shape, the SDK, the exception surface — all unchanged. Three things change: base URL, key prefix, error envelope.

// What you are not doing You are not rewriting prompts. You are not changing model IDs (most map 1:1). You are not changing your retry logic. You are not switching SDKs.

01The three changes, side-by-side

WhatQuatarlySLASHED
Base URL https://api.quatarly.ai/v1 https://api.slashed.pro/v1
Auth header X-Quatarly-Token: qua-... Authorization: Bearer sl-...
Key prefix qua-... sl-...
Error envelope {"err_code", "err_msg"} {"error":{"message","type","code","param"}}
SDK Official OpenAI SDK Official OpenAI SDK (unchanged)
Request body OpenAI v1 spec OpenAI v1 spec (unchanged)
Response body OpenAI v1 spec OpenAI v1 spec (unchanged)

02The five-step migration

Step 01

Get a SLASHED key.

Sign in at dashboard.slashed.pro. Create a key under Keys → New. Copy the sl-... secret once — it is shown a single time. Optional but recommended: name it migration-from-quatarly and scope it to the model IDs you intend to use.

Step 02

Swap the env var.

If you have a single env var (e.g. OPENAI_API_KEY, QUATARLY_API_KEY, LLM_KEY) that holds the bearer token, set it to the new sl- value. If you have two env vars (key + base URL), set both.

# .env (or your deploy secrets manager) OPENAI_BASE_URL=https://api.quatarly.ai/v1 OPENAI_API_KEY=qua-1234abcd_secretsecret... OPENAI_BASE_URL=https://api.slashed.pro/v1 OPENAI_API_KEY=sl-a7f3c2b4_secretsecret...
Step 03

Update the SDK constructor.

If your code passes base_url / baseURL in source code (rather than via env), update both. The SDK choice does not change — keep the official openai package.

# Python from openai import OpenAI client = OpenAI( base_url="https://api.quatarly.ai/v1", api_key="qua-...", base_url="https://api.slashed.pro/v1", api_key="sl-...", )
// Node import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.quatarly.ai/v1", apiKey: "qua-...", baseURL: "https://api.slashed.pro/v1", apiKey: "sl-...", });
Step 04

Drop any custom auth-header logic.

If you have code that injects X-Quatarly-Token via a custom HTTP middleware (because the OpenAI SDK does not set that header natively), remove it. SLASHED uses the standard Authorization: Bearer header that the SDK sets for you automatically.

# BEFORE — Quatarly required a custom header injection client.default_headers["X-Quatarly-Token"] = quatarly_key # AFTER — nothing. The SDK handles Authorization: Bearer for you.
Step 05

Update any error-parsing code.

If you parse the raw HTTP error body (rather than relying on the SDK's APIError exception class), switch from Quatarly's {"err_code", "err_msg"} envelope to OpenAI's {"error": {"message", "type", "code", "param"}}.

# BEFORE try: resp = client.chat.completions.create(...) except Exception as e: body = json.loads(e.response.text) log.error(body["err_code"], body["err_msg"]) # AFTER try: resp = client.chat.completions.create(...) except Exception as e: body = json.loads(e.response.text) log.error(body["error"]["code"], body["error"]["message"])

If you only catch the SDK's openai.APIError / RateLimitError / AuthenticationError classes, no change is needed. The SDK maps both envelopes onto the same exception types.

03Model ID mapping

Most Quatarly model IDs map 1:1 to SLASHED. The exceptions are listed below — if your code references a Quatarly-only ID, swap to the closest SLASHED equivalent.

Quatarly IDClosest SLASHED IDNote
gpt-5.4-minigpt-5.4-mini1:1
gpt-5.4gpt-5.41:1
gpt-5.5gpt-5.51:1
claude-opus-4.7claude-opus-4-7Dot → dash in segment
claude-sonnet-4.6claude-sonnet-4-6Dot → dash in segment
gemini-3.5-flashgemini-3.5-flash1:1
gemini-3.1-progemini-3.1-pro-previewSLASHED exposes the preview-tagged ID
gemini-2.5-progemini-2.5-pro1:1

For the full set of valid SLASHED IDs, hit GET /v1/models or see /docs/models.

04Smoke test

Confirm the swap took with a one-line cURL. If you get a 200 with a model reply, you are done.

curl https://api.slashed.pro/v1/chat/completions \ -H "Authorization: Bearer $SLASHED_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"gpt-5.4-mini","messages":[{"role":"user","content":"reply: migrated"}]}'

05Run both side-by-side (optional)

If you want a few days of dual-write before fully cutting over, the cleanest pattern is two SDK clients in the same process. The OpenAI SDK is stateless — instantiating two clients with different base_url / api_key is supported.

from openai import OpenAI quatarly = OpenAI( base_url="https://api.quatarly.ai/v1", api_key=os.environ["QUATARLY_KEY"], ) slashed = OpenAI( base_url="https://api.slashed.pro/v1", api_key=os.environ["SLASHED_KEY"], ) # Send the same prompt to both. Compare outputs & p99 latency. # When confident, drop the quatarly client and promote slashed.

06Things that will not change

// One known difference at migration Quatarly's older accounts surface a X-Quatarly-Request-Id header on every response. SLASHED does not document a request-id header today. If your observability layer reads that header, switch to relying on the response body's id field (e.g. chatcmpl-...), which both gateways emit.

07If you get stuck