Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
"getting-started/integration-method/mistral",
"getting-started/integration-method/nebius",
"getting-started/integration-method/novita",
"getting-started/integration-method/scalattice",
{
"group": "Nvidia",
"pages": [
Expand Down
90 changes: 90 additions & 0 deletions docs/getting-started/integration-method/scalattice.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
title: "Scalattice Integration"
sidebarTitle: "Scalattice"
description: "Connect Helicone with Scalattice, an OpenAI-compatible inference marketplace. Log requests, cost, and latency through a simple base URL change."
"twitter:title": "Scalattice Integration - Helicone OSS LLM Observability"
---

import LegacyWarning from "/snippets/legacy-provider-warning.mdx";

<LegacyWarning />

Scalattice is an OpenAI-compatible inference marketplace. Create a key from the [developer docs](https://scalattice.cloud/docs/developers).

# Gateway Integration

<Steps>
<Step title="Create a Helicone account">
Log into [helicone](https://www.helicone.ai) or create an account. Once you have an account, you
can generate an [API key](https://helicone.ai/developer).
</Step>
<Step title="Create a Scalattice API key">
Create an `slt_...` key from the [Scalattice developer dashboard](https://scalattice.cloud/developers).
</Step>
<Step title="Set HELICONE_API_KEY and SCALATTICE_API_KEY">
```javascript
HELICONE_API_KEY=<your Helicone API key>
SCALATTICE_API_KEY=<your Scalattice API key>
```
</Step>
<Step title="Point the OpenAI client at Helicone">

Replace `https://api.scalattice.cloud/v1` with `https://scalattice.helicone.ai/v1` and add the Helicone auth header:

```javascript
Authorization: Bearer <SCALATTICE_API_KEY>
Helicone-Auth: Bearer <HELICONE_API_KEY>
```

</Step>
</Steps>

## Example

```python
from openai import OpenAI
import os

client = OpenAI(
api_key=os.environ["SCALATTICE_API_KEY"],
base_url="https://scalattice.helicone.ai/v1",
default_headers={
"Helicone-Auth": f"Bearer {os.environ['HELICONE_API_KEY']}",
},
)

response = client.chat.completions.create(
model="qwen-3-14b",
messages=[{"role": "user", "content": "Hello from Scalattice"}],
)
print(response.choices[0].message.content)
```

```bash
curl https://scalattice.helicone.ai/v1/chat/completions \
-H "Authorization: Bearer $SCALATTICE_API_KEY" \
-H "Helicone-Auth: Bearer $HELICONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen-3-14b",
"messages": [{"role": "user", "content": "Hello from Scalattice"}]
}'
```

If the dedicated `scalattice.helicone.ai` host is not live yet, use the generic OpenAI proxy and set the target:

```python
client = OpenAI(
api_key=os.environ["SCALATTICE_API_KEY"],
base_url="https://oai.helicone.ai/v1",
default_headers={
"Helicone-Auth": f"Bearer {os.environ['HELICONE_API_KEY']}",
"Helicone-Target-URL": "https://api.scalattice.cloud",
},
)
```

Catalog IDs match `GET https://api.scalattice.cloud/v1/models`.

For more on headers, see [Helicone Headers](https://docs.helicone.ai/helicone-headers/header-directory#utilizing-headers).
For Scalattice itself, see the [developer docs](https://scalattice.cloud/docs/developers).
5 changes: 5 additions & 0 deletions packages/cost/models/provider-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export function heliconeProviderToModelProviderName(
return "fireworks";
case "CANOPYWAVE":
return "canopywave";
case "SCALATTICE":
return "scalattice";
// new registry does not have
case "LOCAL":
case "HELICONE":
Expand Down Expand Up @@ -159,6 +161,9 @@ export const dbProviderToProvider = (
if (provider === "nebius" || provider === "Nebius") {
return "nebius";
}
if (provider === "scalattice" || provider === "Scalattice") {
return "scalattice";
}
return null;
};

Expand Down
3 changes: 3 additions & 0 deletions packages/cost/models/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { NovitaProvider } from "./novita";
import { OpenAIProvider } from "./openai";
import { OpenRouterProvider } from "./openrouter";
import { PerplexityProvider } from "./perplexity";
import { ScalatticeProvider } from "./scalattice";
import { VertexProvider } from "./vertex";
import { XAIProvider } from "./xai";

Expand All @@ -41,6 +42,7 @@ export const providers = {
openai: new OpenAIProvider(),
openrouter: new OpenRouterProvider(),
perplexity: new PerplexityProvider(),
scalattice: new ScalatticeProvider(),
vertex: new VertexProvider(),
xai: new XAIProvider()
} as const;
Expand Down Expand Up @@ -84,6 +86,7 @@ export const ResponsesAPIEnabledProviders: ModelProviderName[] = [
"novita",
"openrouter",
"perplexity",
"scalattice",
"xai",
"baseten",
"fireworks",
Expand Down
1 change: 1 addition & 0 deletions packages/cost/models/providers/priorities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const PROVIDER_PRIORITIES: Record<ModelProviderName, number> = {
mistral: 4,
nebius: 4,
novita: 4,
scalattice: 4,

perplexity: 4,
vertex: 4,
Expand Down
14 changes: 14 additions & 0 deletions packages/cost/models/providers/scalattice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { BaseProvider } from "./base";
import type { Endpoint, RequestParams } from "../types";

export class ScalatticeProvider extends BaseProvider {
readonly displayName = "Scalattice";
readonly baseUrl = "https://api.scalattice.cloud/v1";
readonly auth = "api-key" as const;
readonly pricingPages = ["https://scalattice.com/pricing/"];
readonly modelPages = ["https://scalattice.cloud/docs/developers"];

buildUrl(endpoint: Endpoint, requestParams: RequestParams): string {
return `${this.baseUrl}/chat/completions`;
}
}
9 changes: 9 additions & 0 deletions packages/cost/providers/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ const cerebras = /^https:\/\/api\.cerebras\.ai/;
// https://inference.canopywave.io
const canopywave = /^https:\/\/inference\.canopywave\.io/;

// https://api.scalattice.cloud
const scalattice = /^https:\/\/api\.scalattice\.cloud/;

export const providersNames = [
"OPENAI",
"ANTHROPIC",
Expand Down Expand Up @@ -132,6 +135,7 @@ export const providersNames = [
"CEREBRAS",
"BASETEN",
"CANOPYWAVE",
"SCALATTICE",
] as const;

export type ProviderName = (typeof providersNames)[number];
Expand Down Expand Up @@ -325,6 +329,11 @@ export const providers: {
pattern: canopywave,
provider: "CANOPYWAVE",
costs: [],
},
{
pattern: scalattice,
provider: "SCALATTICE",
costs: [],
}
];

Expand Down
1 change: 1 addition & 0 deletions packages/cost/usage/getUsageProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export function getUsageProcessor(
case "fireworks":
case "cerebras":
case "perplexity":
case "scalattice":
return new OpenAIUsageProcessor();
case "anthropic":
return new AnthropicUsageProcessor();
Expand Down
11 changes: 11 additions & 0 deletions web/data/providers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,17 @@ export const providers: Provider[] = [
apiKeyPlaceholder: "...",
relevanceScore: 3,
},
{
id: "scalattice",
name: "Scalattice",
logoUrl: "/assets/home/providers/scalattice.svg",
description: "Configure your Scalattice API keys for OpenAI-compatible inference",
docsUrl:
"https://docs.helicone.ai/getting-started/integration-method/scalattice",
apiKeyLabel: "Scalattice API Key",
apiKeyPlaceholder: "slt_...",
relevanceScore: 3,
},
{
id: "helicone",
name: "Helicone Inference",
Expand Down
4 changes: 4 additions & 0 deletions web/public/assets/home/providers/scalattice.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions worker/test/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,15 @@ vi.mock("@supabase/supabase-js", () => ({
config: null,
byok_enabled: isByokEnabled,
},
scalattice: {
org_id: "test-org-id",
provider_name: "scalattice",
decrypted_provider_key: "test-scalattice-api-key",
decrypted_provider_secret_key: null,
auth_type: "api_key",
config: null,
byok_enabled: isByokEnabled,
},
openrouter: {
org_id: "test-org-id",
provider_name: "openrouter",
Expand Down Expand Up @@ -431,6 +440,15 @@ vi.mock("@supabase/supabase-js", () => ({
config: null,
byok_enabled: true,
},
scalattice: {
org_id: "0afe3a6e-d095-4ec0-bc1e-2af6f57bd2a5",
provider_name: "scalattice",
decrypted_provider_key: "helicone-scalattice-api-key",
decrypted_provider_secret_key: null,
auth_type: "api_key",
config: null,
byok_enabled: true,
},
nebius: {
org_id: "0afe3a6e-d095-4ec0-bc1e-2af6f57bd2a5",
provider_name: "nebius",
Expand Down