PORDL API
Drop-in OpenAI replacement with smart model routing.
Send requests to api.pordl.dev instead of api.openai.com,
and PORDL routes each request to the cheapest model that can handle it.
Base URL for all API requests:
https://api.pordl.dev
All endpoints use JSON request/response bodies and follow OpenAI's API format — any OpenAI-compatible client works out of the box.
Quick Start
Node.js (SDK)
import Pordl from "@plagtech/pordl";
const client = new Pordl({ apiKey: "pd_live_..." });
const res = await client.chat.completions.create({
model: "auto",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(res.choices[0].message.content);
Node.js (OpenAI SDK directly)
import OpenAI from "openai";
const client = new OpenAI({
apiKey: "pd_live_...",
baseURL: "https://api.pordl.dev/v1",
});
Python
from openai import OpenAI
client = OpenAI(
api_key="pd_live_...",
base_url="https://api.pordl.dev/v1",
)
curl
curl https://api.pordl.dev/v1/chat/completions \
-H "Authorization: Bearer pd_live_..." \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"messages": [{"role": "user", "content": "Hello!"}]
}'
Sign Up
Create an account and receive your API key. Save the key — it won't be shown again.
Request
{
"email": "you@example.com", // required
"password": "your-password" // required
}
Response
{
"message": "Account created",
"user": {
"id": "a15769e8-...",
"email": "you@example.com",
"tier": "free"
},
"api_key": "pd_live_6b7c140dd949cac44b14bb23b6cfa19a",
"note": "Save this API key — it won't be shown again."
}
Log In
Log in and generate a new API key.
Request
{
"email": "you@example.com",
"password": "your-password"
}
API Keys
All authenticated requests require an API key in the Authorization header.
Keys start with pd_live_ for production or pd_test_ for testing.
Authorization: Bearer pd_live_your_key_here
Keys are hashed and stored securely — PORDL never stores your raw key. If you lose your key, log in again to generate a new one.
Chat Completions
Send a chat completion request. Follows the OpenAI format exactly.
Request Body
| Parameter | Type | Description |
|---|---|---|
model required |
string | Use "auto" for smart routing, or specify a model directly (e.g. "gpt-4o-mini") |
messages required |
array | Array of message objects with role and content |
temperature optional |
number | Sampling temperature, 0 to 2. Default: 1 |
max_tokens optional |
integer | Maximum tokens in the response |
Response
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 8,
"total_tokens": 20
}
}
Models
List available models. No authentication required.
Smart Routing
When you set model: "auto", PORDL classifies your request
by complexity and routes it to the cheapest model that can handle it:
| Complexity | Routed To | Example |
|---|---|---|
| Simple | gpt-4o-mini |
Factual Q&A, formatting, translation |
| Medium | gpt-4o |
SQL queries, code review, analysis |
| Complex | gpt-5.4 |
System design, multi-step reasoning |
You can also pass a specific model name to bypass routing.
The routing classification is returned in the x-pordl-complexity response header.
Response Headers
Every chat completion response includes routing metadata:
| Header | Description |
|---|---|
x-pordl-model |
Which model handled the request |
x-pordl-complexity |
How the request was classified (simple / medium / complex) |
x-pordl-routing |
Routing mode used (auto / direct) |
x-pordl-cost |
Cost of the call in USD |
x-pordl-savings |
Estimated savings vs. calling the most expensive model directly |
x-pordl-latency |
Total response time in ms |
x-pordl-cached |
true if response was served from cache |
x-monthly-limit |
Your tier's monthly token limit |
x-monthly-used |
Tokens used this billing period |
x-monthly-remaining |
Tokens remaining this billing period |
Pricing
Starter
Pro
Scale
Checkout
Create a Stripe checkout session to subscribe to a paid tier. Returns a URL to redirect the user to.
Request
// Header: Authorization: Bearer pd_live_...
{
"tier": "starter" // "starter" | "pro" | "scale"
}
Response
{
"url": "https://checkout.stripe.com/c/pay/cs_live_...",
"tier": "starter"
}
Customer Portal
Create a Stripe customer portal session to manage or cancel your subscription.
Usage
Get your current usage stats for the billing period.
Request
Authorization: Bearer pd_live_...
Errors
Errors follow a consistent JSON format:
{
"error": {
"message": "Invalid API key",
"type": "authentication_error",
"code": "invalid_api_key"
}
}
| HTTP Code | Type | Meaning |
|---|---|---|
| 400 | invalid_request_error | Bad request body or missing fields |
| 401 | authentication_error | Missing or invalid API key |
| 429 | rate_limit_error | Rate limit or token quota exceeded |
| 500 | server_error | Something went wrong on our end |
Rate Limits
Rate limits depend on your subscription tier:
| Tier | Monthly Tokens | Requests / min |
|---|---|---|
| Free | 10,000 | 10 |
| Starter | 50,000 | 60 |
| Pro | 250,000 | 120 |
| Scale | 1,000,000 | 300 |
Rate limit info is returned in response headers:
x-ratelimit-limit-requests,
x-ratelimit-remaining-requests,
x-ratelimit-reset-requests.
SDK
Install the official Node.js SDK:
npm install @plagtech/pordl
The SDK is a thin wrapper around the OpenAI Node.js SDK
— it sets baseURL to api.pordl.dev and handles auth.
All OpenAI methods and types work as-is.
import Pordl from "@plagtech/pordl";
const client = new Pordl({ apiKey: "pd_live_..." });
const res = await client.chat.completions.create({
model: "auto",
messages: [{ role: "user", content: "What is 2+2?" }],
});
console.log(res.choices[0].message.content);
// "4"
For Python, use the standard OpenAI library with a custom base_url.
See Quick Start for examples.
← Back to PORDL · GitHub · npm