• Chat
  • Pricing
  • Blog
  • Downloads
  • API
    • Models
    • Rankings
    • API docs
    • Ditfa Platform
  • Company
    • About
    • Contact
    • Changelog
    • Roadmap
    • Contributors
  • Chat
  • Pricing
  • Blog
  • Downloads
  • API
    • Models
    • Rankings
    • API docs
    • Ditfa Platform
  • Company
    • About
    • Contact
    • Changelog
    • Roadmap
    • Contributors
DevelopersAPI reference

Get started

  • Quickstart
  • Authentication
  • SDKs & frameworks

API reference

  • Chat completionsPOST
  • ModelsGET
  • Streaming
  • Get the current key
  • Get credits
  • Get a generation

Guides

  • Errors & retries
  • Rate limits & quotas
  • App attribution
  • Choose your API
  • Billing & credits
  • Routing & fallback
  • Best practices
Model catalogGet support
Developers · Ditfa Platform $ Pay-as-you-go

Ditfa Platform API

One OpenAI-compatible endpoint for every model in the catalog. Bring any OpenAI SDK, use an sk-dp- key, and pay per token from prepaid credits. No subscription, no usage windows.

Base URL

https://gateway.ditfa.com/v1
Create an API key Browse models
Compatibility
OpenAI Chat Completions
Any OpenAI SDK or HTTP client
Auth
Bearer sk-dp-…
Per-key limits, models, IPs, expiry
Billing
Per token, in USD
Prepaid credits that never expire
Routing
Healthy providers first
Automatic fallback, up to 3 tries

Get started

Quickstart#

From zero to your first response in three steps.
  1. 1Add credits to your wallet ($5 minimum).
  2. 2Create an API key. It starts with sk-dp- and is shown only once; store it as DITFA_API_KEY.
  3. 3Point any OpenAI SDK at https://gateway.ditfa.com/v1 and pick a model slug from /models.
curl https://gateway.ditfa.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DITFA_API_KEY" \
  -d '{
  "model": "openai/gpt-4o-mini",
  "messages": [
    {
      "role": "user",
      "content": "Write a haiku about the ocean."
    }
  ]
}'

Authentication#

Every endpoint except GET /models needs a key, sent as a bearer token:

Authorization: Bearer sk-dp-…

Keys are stored hashed; the full key is shown once when you create it. Each key can be scoped in the dashboard:

SettingEffect
Spend limitPer day, week, month or in total. Windows are UTC; weeks start on Monday. Requests over the limit get 402 key_limit_reached.
Allowed modelsOnly these slugs can be called. Empty means every published model.
IP allowlistExact IPv4/IPv6 addresses. Empty means any IP.
Expiry dateAfter it, the key gets 401 key_expired.
Provider policyVerified providers only (no marketplace sellers) and/or no providers that log prompts. Also settable for the whole account.

Disable a key to pause it, or delete it to revoke it for good; request history is kept either way. Key changes take effect within a few seconds. Up to 25 keys can be active per account.

Keep keys on the server

The gateway accepts browser (CORS) requests, but a key in client-side code can be read and spent by anyone. Call the API from your backend, or use a separate key with a low spend limit and an allowlist.

SDKs & frameworks#

Anything that speaks the OpenAI Chat Completions API works: change the base URL and the key.
ClientConfiguration
OpenAI PythonOpenAI(base_url=…, api_key=…)
OpenAI Node / TypeScriptnew OpenAI({ baseURL, apiKey })
Vercel AI SDKcreateOpenAICompatible({ name: "ditfa", baseURL, apiKey })
LangChainChatOpenAI(base_url=…, api_key=…, model=…)
Tools that read env varsOPENAI_BASE_URL=https://gateway.ditfa.com/v1 OPENAI_API_KEY=sk-dp-…
Only Chat Completions is available. The Responses, Embeddings, Images and Audio endpoints of the OpenAI API are not served by the gateway.

API reference

Create a chat completion#

Generates a model response for a conversation. Request and response follow the OpenAI Chat Completions format.
POSThttps://gateway.ditfa.com/v1/chat/completionsRequires sk-dp- key

Request body

modelstringrequired
Model slug in author/name form, e.g. openai/gpt-4o-mini. See List models.
messagesarrayrequired
At least one message. Roles: system, developer, user, assistant, tool. content may be a string or an array of content parts (text and, for vision models, images).
streamboolean
Default false. When true, the response is a stream of server-sent events. See Streaming.
max_completion_tokensinteger
Output cap. max_tokens is accepted too (if both are sent, max_completion_tokens wins). Without either, the gateway applies a cap of 16,384 tokens or the model's maximum output, whichever is lower.
temperaturenumber
Sampling temperature, usually 0 to 2.
top_pnumber
Nucleus sampling probability mass.
stopstring | string[]
Sequences where generation stops.
presence_penalty / frequency_penaltynumber
Penalties for repeated topics and tokens, where the model supports them.
seedinteger
Best-effort deterministic sampling, where supported.
tools / tool_choice / parallel_tool_callsarray / string | object / boolean
Function calling in the OpenAI format. Only for models whose supported_parameters include tools.
response_formatobject
{ "type": "json_object" } or a json_schema for structured output, where supported.
logprobs / top_logprobsboolean / integer
Token log probabilities, where supported.

Unsupported fields are dropped

Only the fields above are forwarded to the provider. Others (for example user, n or vendor extensions) are ignored without an error. Support for optional parameters varies by model; check supported_parameters.

Response

A chat.completion object. id is the Ditfa generation id and model is the public slug you requested, whichever provider served it.

200 OK
{
  "id": "gen-3f1c2a7e-8b4d-4c1e-9a0f-5d6e7b8c9d0e",
  "object": "chat.completion",
  "created": 1793318400,
  "model": "openai/gpt-4o-mini",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Waves fold into foam…"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 14,
    "completion_tokens": 17,
    "total_tokens": 31
  }
}

Response headers

x-ditfa-generation-idstring
gen-… id of a successful request. Use it with /generation to read its final token counts and cost.
x-ratelimit-limit-requestsinteger
Requests allowed per minute for this key.
x-ratelimit-remaining-requestsinteger
Requests left in the current one-minute window.
retry-afterinteger
Seconds to wait. Sent with 429 rate_limit_exceeded.

Streaming#

Set stream: true to receive server-sent events (text/event-stream) in the OpenAI chunk format, ending with data: [DONE].
curl https://gateway.ditfa.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DITFA_API_KEY" \
  -d '{
  "model": "openai/gpt-4o-mini",
  "messages": [
    {
      "role": "user",
      "content": "Write a haiku about the ocean."
    }
  ]
}'
Event stream
data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[{"index":0,"delta":{"role":"assistant","content":"Waves"}}]}

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[{"index":0,"delta":{"content":" fold"}}]}

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-…","object":"chat.completion.chunk","model":"openai/gpt-4o-mini","choices":[],"usage":{"prompt_tokens":14,"completion_tokens":17,"total_tokens":31}}

data: [DONE]
  • The last chunk before [DONE] carries usage with an empty choices array. The gateway always requests it, so you do not need stream_options. Guard against empty choices when reading deltas.
  • Chunk ids come from the provider. Use the x-ditfa-generation-id response header to look the request up later.
  • If you disconnect mid-stream, you pay only for the output already delivered. A stream that delivered nothing is not charged.

List models#

Every published model with its context window, lowest available price and supported parameters. Cached for 60 seconds.
GEThttps://gateway.ditfa.com/v1/modelsPublic, no key
Request
curl https://gateway.ditfa.com/v1/models
200 OK
{
  "data": [
    {
      "id": "openai/gpt-4o-mini",
      "name": "GPT-4o mini",
      "author": "openai",
      "created": 1721260800,
      "description": "…",
      "context_length": 128000,
      "architecture": {
        "input_modalities": [
          "text",
          "image"
        ],
        "output_modalities": [
          "text"
        ]
      },
      "pricing": {
        "prompt": "0.000000155",
        "completion": "0.000000618",
        "input_cache_read": "0.0000000773",
        "request": "0"
      },
      "top_provider": {
        "context_length": 128000,
        "max_completion_tokens": 16384
      },
      "supported_parameters": [
        "max_tokens",
        "temperature",
        "top_p",
        "stop",
        "tools",
        "tool_choice"
      ]
    }
  ]
}

Fields

idstring
The slug to pass as model.
pricingobject
USD per token as decimal strings (OpenRouter format): prompt, completion, input_cache_read (absent when the model has no cached-input price) and request (fixed fee per request). Multiply by 1,000,000 for the per-million price shown on model pages.
context_lengthinteger
Maximum context window in tokens.
top_providerobject
Context window and max output tokens of the provider behind the listed price.
architectureobject
input_modalities and output_modalities, e.g. ["text", "image"].
supported_parametersstring[]
Optional request parameters the model accepts, including tools and reasoning.

Get the current key#

The calling key's spend limit, spend in the current period and allowed models.
GEThttps://gateway.ditfa.com/v1/keyRequires sk-dp- key
Request
curl https://gateway.ditfa.com/v1/key \
  -H "Authorization: Bearer $DITFA_API_KEY"
200 OK
{
  "data": {
    "limit": 50,
    "limit_period": "month",
    "usage": 12.4,
    "limit_remaining": 37.6,
    "allowed_models": []
  }
}

Amounts are USD. limit and limit_remaining are null when the key has no spend limit; usage is then the key's lifetime spend.

Get credits#

The wallet balance of the account that owns the key.
GEThttps://gateway.ditfa.com/v1/creditsRequires sk-dp- key
200 OK
{
  "data": {
    "balance": 24.5,
    "reserved": 0.02,
    "available": 24.48
  }
}

reserved is held for requests in flight; available = balance − reserved is what new requests can use.

Get a generation#

Final status, token counts, cost and timing of one request. Useful for streams and for reconciling spend.
GEThttps://gateway.ditfa.com/v1/generation?id=gen-…Requires sk-dp- key
200 OK
{
  "data": {
    "id": "gen-3f1c2a7e-8b4d-4c1e-9a0f-5d6e7b8c9d0e",
    "model": "openai/gpt-4o-mini",
    "created_at": "2026-10-30T09:12:44.512Z",
    "status": "ok",
    "streamed": true,
    "tokens_prompt": 14,
    "tokens_completion": 17,
    "tokens_cached": 0,
    "tokens_reasoning": 0,
    "total_cost": 0.000013,
    "latency_ms": 812,
    "ttft_ms": 241
  }
}

total_cost is the USD amount charged. status is ok, error or canceled; ttft_ms (time to first token) is set for streams. Usage is written once the request finishes, so query it after the response or stream ends. Any key of the same account can read it.

Guides

Billing & credits#

You pay per token in USD from a prepaid wallet. Prompt tokens are billed at the input rate, cached prompt tokens at the cache-read rate when the model has one, and output tokens (including reasoning tokens) at the output rate, plus any fixed per-request fee.

How a request is charged

  1. Reserve. Before calling the model, the gateway holds an upper bound: the estimated prompt plus the maximum output (max_tokens, else 16,384, capped by the model). If available credits or the key's limit cannot cover it, you get 402.
  2. Settle. When the response ends, the real usage is charged and the rest of the hold is released.
  3. Release. A failed request releases the whole hold. You are never charged for 4xx errors or for 502s.

Low balance, long answers?

Set max_tokens to what you really need. The hold shrinks with it, so requests keep working on a small balance instead of failing with insufficient_credits.

Top-ups are $5 to $1,000 each and credits never expire. A low-balance email alert can be set in the settings.

Routing & fallback#

A model can be served by several providers. The gateway tries up to three of them in priority order and moves providers that are currently failing for several users to the back of the line.

  • If a provider times out, returns 408, 429 or 5xx, or cannot be reached, the next one is tried automatically. Nothing has been sent to you yet, so fallback is invisible.
  • A 400 from a provider means the request itself was rejected; it is not retried elsewhere.
  • You are billed at the rate of the provider that answered. The catalog shows the lowest available price; /generation shows exactly what you paid.
  • The provider policy on a key or the account (verified providers only, no prompt logging) removes providers from routing. If none are left you get 403 no_allowed_provider.

Errors#

Errors use the OpenAI shape. Branch on error.code (stable); message is for humans and may change.
402 Payment Required
{
  "error": {
    "message": "Insufficient credits. Top up your wallet at https://platform.ditfa.com/credits.",
    "type": "payment_required",
    "code": "insufficient_credits",
    "param": null
  }
}
StatusCodeMeaningRetry?
400nullinvalid_request_errorThe body is not valid JSON, model or messages is missing, or the model rejected the parameters. The message names the problem.No
401missing_api_keyauthentication_errorNo Authorization: Bearer header was sent.No
401invalid_api_keyauthentication_errorThe key is malformed, wrong, disabled or deleted.No
401wrong_key_typeauthentication_errorA Plan API key (dt-…) was sent to Ditfa Platform. Platform keys start with sk-dp-.No
401key_expiredauthentication_errorThe key passed its expiry date.No
402insufficient_creditspayment_requiredAvailable credits cannot cover the reserved cost of this request. Add credits or lower max_tokens.No
402key_limit_reachedpayment_requiredThe key reached its own spend limit for the current period. Raise the limit or wait for the next period.No
403account_disabledpermission_errorThe account that owns the key cannot use the API. Contact support.No
403ip_not_allowedpermission_errorThe request came from an IP outside the key's allowlist.No
403model_not_allowedpermission_errorThe key's allowed-models list does not include this model.No
403no_allowed_providerpermission_errorNo provider of this model matches the key or account provider settings (verified providers only / no prompt logging).No
404model_not_foundinvalid_request_errorThe model slug does not exist or is not published.No
404not_foundinvalid_request_error/generation: no request with this id belongs to your account.No
429rate_limit_exceededrate_limit_errorToo many requests per minute for this key. Wait for the retry-after header.Yes
429model_overloadedrate_limit_errorEvery provider of this model is busy right now.Yes
502upstream_unavailableserver_errorNo provider could serve the request. You are not charged.Yes
502upstream_errorserver_errorThe provider returned an unreadable response. You are not charged.Yes

Handling errors

Retry only 429 and 5xx, with exponential backoff and jitter, and honour retry-after. Treat 401, 402, 403 and 404 as configuration problems: retrying will not help.

TypeScript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://gateway.ditfa.com/v1',
  apiKey: process.env.DITFA_API_KEY,
  maxRetries: 3, // retries 429 and 5xx with backoff, honouring retry-after
});

try {
  const completion = await client.chat.completions.create({
    model: 'openai/gpt-4o-mini',
    messages: [{ role: 'user', content: 'Hello' }],
  });
  console.log(completion.choices[0].message.content);
} catch (error) {
  if (error instanceof OpenAI.APIError) {
    switch (error.code) {
      case 'insufficient_credits':
      case 'key_limit_reached':
        // Not retryable: alert someone to top up or raise the key limit.
        break;
      case 'model_not_found':
      case 'model_not_allowed':
        // Fix the model slug or the key's allowed models.
        break;
      default:
        console.error(error.status, error.code, error.message);
    }
  }
  throw error;
}

Used the wrong key?

A dt- key sent to Ditfa Platform (or an sk-dp- key sent to the Plan API) gets 401 wrong_key_type with a message that says which product it belongs to.

Rate limits & quotas#

LimitValue
Requests per key600 per minute by default. Read x-ratelimit-* headers on every response.
Requests per IP1,000 per minute across all keys from one address.
Active keys25 per account.
Top-up size$5 to $1,000 per payment; credits do not expire.
Default output cap16,384 tokens, or the model's maximum when lower. Set max_tokens to change it.
Context & max outputPer model; see /models or each model page.

Need a higher request rate? Contact us with your expected volume.

App attribution#

Optional headers that put your app on the public rankings and model pages.
HTTP-Referer: https://your-app.example
X-Title: Your App

Referer is accepted when HTTP-Referer is absent. Only the origin of the referer is ever shown publicly, never its path or query. Both values also appear in your own request log.

Best practices#

  • Use one key per app or environment, each with its own spend limit, so a leak or a bug has a ceiling.
  • Add an IP allowlist for keys used from fixed servers, and an expiry for temporary keys.
  • Restrict production keys to the models you actually use, so a typo cannot route to a much pricier model.
  • Log x-ditfa-generation-id with your own request ids; it makes cost questions and support tickets quick to answer.
  • Check GET /credits from a cron job or set a low-balance alert so production never hits insufficient_credits.

Plan API vs Ditfa Platform: which one do I need?#

Ditfa has two separate APIs. Keys, base URLs and billing are not shared.
Plan API Included in your planDitfa Platform $ Pay-as-you-go
BillingIncluded in your Ditfa plan (usage quota)Pay-as-you-go from prepaid USD credits
Base URLhttps://api.ditfa.com/api/v1https://gateway.ditfa.com/v1
Key prefixdt-…sk-dp-…
Where to manageChat → Integrations → APIplatform.ditfa.com
ModelsModels your plan enables for the APIThe full public catalog with per-token prices
When it runs outWait for the next usage window or upgrade your planAdd credits; no windows
Best forTesting and personal scriptsProducts, higher volume and specific models

Open the Plan API

Testing and personal use, within your plan's usage.

Open Ditfa Platform

Products, volume and any model, paid per token.

Host your own model? Sell it to every Ditfa Platform developer at your own price through the Ditfa Provider Program.Become a provider

Build something with Ditfa.Create your API key
Terms of ServicePrivacy PolicyRefund PolicyAcceptable UseContact

© 2026 Ditfa. All rights reserved.

TeamtemGitHubHuggingface

Your analytics choice

Allow Google Analytics to measure visits and public-page clicks so we can improve Ditfa? Optional analytics stays off until you choose. Privacy policy