Overview

Experience Platform AI is the unified orchestration layer for AI — connect any model, route intelligently, evaluate quality, and ship reliable AI apps.

Base URLhttps://api.experienceplatform.ai
All requests must be HTTPS and authenticated.

Authentication

Use your secret key in the Authorization header as a Bearer token.

Header

Authorization
Bearer <YOUR_API_KEY>
Content-Type
application/json

Security

  • Rotate keys regularly; keep them server-side.
  • Use per-project keys for isolation.
  • For web apps, proxy requests via your backend.

Quickstart

curl https://api.experienceplatform.ai/v1/chat/completions \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [
      {"role":"system","content":"You are helpful."},
      {"role":"user","content":"Write a haiku about alpine light."}
    ],
    "temperature": 0.3,
    "max_tokens": 128
  }'

POST /v1/chat/completions

Create chat responses with multi-model routing and evaluation hooks.

Request Body

FieldTypeDescription
modelstringTarget model (or routing profile) e.g. gpt-4o-mini, claude-3.5-sonnet, router:fast.
messagesarrayChat history: objects with role and content.
temperaturenumber0–2. Higher = more creative. Default 0.2
max_tokensintMax tokens to generate.
streamboolEnable SSE streaming of tokens.
metadataobjectArbitrary key/values for tracing.
routeobjectAdvanced routing hints (provider, latency_budget_ms, cost_ceiling_usd, fallback list).

Response (200)

{
  "id": "chatcmpl_abc123",
  "model": "gpt-4o-mini",
  "created": 1730240000,
  "usage": { "prompt_tokens": 24, "completion_tokens": 42, "total_tokens": 66, "cost_usd": 0.0012, "latency_ms": 612 },
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Snow on granite peaks..." },
      "finish_reason": "stop",
      "routing_decision": { "provider": "openai", "reason": "best_cost_latency" }
    }
  ]
}

POST /v1/embeddings

Create vector embeddings for search, RAG, or clustering.

Request

curl https://api.experienceplatform.ai/v1/embeddings \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "text-embedding-3-large",
    "input": ["alpine light on snow", "glass frames with matte black finish"]
  }'

Response (200)

{
  "model": "text-embedding-3-large",
  "data": [
    { "index": 0, "embedding": [0.013, -0.042, ...] },
    { "index": 1, "embedding": [0.021, 0.005, ...] }
  ],
  "usage": { "prompt_tokens": 14, "total_tokens": 14, "cost_usd": 0.0003 }
}

GET /v1/models

List available models and routing profiles.

Request

curl "https://api.experienceplatform.ai/v1/models" \
  -H "Authorization: Bearer <YOUR_API_KEY>"

Response (200)

{
  "data": [
    { "id": "gpt-4o-mini", "provider": "openai", "context": 128000, "type": "chat" },
    { "id": "claude-3.5-sonnet", "provider": "anthropic", "context": 200000, "type": "chat" },
    { "id": "text-embedding-3-large", "provider": "openai", "dims": 3072, "type": "embedding" },
    { "id": "router:fast", "provider": "router", "strategy": "cost_latency", "type": "profile" }
  ]
}

Streaming (SSE)

Set stream: true to receive incremental tokens as Server-Sent Events.

// JavaScript (browser/Node)
const resp = await fetch("https://api.experienceplatform.ai/v1/chat/completions", {
  method: "POST",
  headers: {
    "Authorization": "Bearer <YOUR_API_KEY>",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "router:fast",
    stream: true,
    messages: [{ role: "user", content: "Stream a limerick." }]
  })
});

const reader = resp.body.getReader();
const decoder = new TextDecoder();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value);
  // Each SSE line begins with "data: ..."
  for (const line of chunk.split("\n")) {
    if (line.startsWith("data: ")) {
      const payload = JSON.parse(line.slice(6));
      if (payload.choices?.[0]?.delta?.content) {
        process.stdout.write(payload.choices[0].delta.content);
      }
    }
  }
}

Intelligent Routing

Use a specific model, or a routing profile (e.g., router:fast, router:quality). You can also provide hints:

{
  "model": "router:quality",
  "messages": [{"role":"user","content":"Refactor this function."}],
  "route": {
    "provider": "anthropic",              // preferred provider
    "latency_budget_ms": 1200,            // soft target
    "cost_ceiling_usd": 0.02,             // soft ceiling
    "fallback": ["gpt-4o-mini","gemini-1.5-pro"]
  }
}

Rate Limits

PlanRequests / minTokens / minBurst
Developer6060k120
Pro300300k600
EnterpriseCustomCustomCustom

Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Errors

Structure

{
  "error": {
    "type": "invalid_request_error",
    "message": "Missing 'messages' field.",
    "param": "messages",
    "code": "ERR_MISSING_FIELD"
  },
  "request_id": "req_abc123",
  "status": 400
}

Common Codes

StatusTypeMeaning
400invalid_request_errorBad/missing params
401authentication_errorInvalid or missing key
403permission_errorKey not allowed on resource
429rate_limit_errorToo many requests/tokens
500+server_errorUpstream/provider issue

SDKs

JavaScript (fetch)

export async function chat(messages) {
  const r = await fetch("https://api.experienceplatform.ai/v1/chat/completions", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.EXP_API_KEY}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({ model: "router:fast", messages })
  });
  if (!r.ok) throw new Error(`HTTP ${r.status}`);
  const data = await r.json();
  return data.choices[0].message.content;
}

Python (requests)

import os, requests, json

API_KEY = os.getenv("EXP_API_KEY")
payload = { "model":"router:quality", "messages":[{"role":"user","content":"Hello!"}] }
res = requests.post(
  "https://api.experienceplatform.ai/v1/chat/completions",
  headers={"Authorization": f"Bearer {API_KEY}", "Content-Type":"application/json"},
  data=json.dumps(payload)
)
res.raise_for_status()
print(res.json()["choices"][0]["message"]["content"])
Questions or need higher limits? support@experienceplatform.ai · Request a demo