API Overview

2026-10-22

Overview

Praxis is the Agent Cloud Platform. The API is organized by service: agents, models, sandboxes, search, and automation, each under its own prefix. Requests and responses use JSON, streaming responses use SSE, and standard HTTP verbs and status codes apply. All prefixes share one address and one Key.

Base URL

https://api.deepraxis.com

Client libraries

Use the client libraries listed on each service's API page. Compatible APIs use official protocol SDKs. For local installation of the automation TypeScript SDK, see Automation API.

ServicePrefixAPI page
Agents/agentAgent API
Models/modelModel API
Sandboxes/sandboxSandbox API
Search/searchSearch API
Automation/automationAutomation API

Compatible APIs

Code already using OpenAI, Anthropic, Google, E2B, or Tavily doesn't need to be rewritten for Praxis: the platform offers compatible prefixes that match those vendors' official APIs — change the address and go.

VendorPrefixAPI page
OpenAI/openaiOpenAI compatible
Anthropic/anthropicAnthropic compatible
Google/googleGoogle compatible
E2B/e2bE2B compatible
Tavily/tavilyTavily compatible

One Key

All prefixes share the API Key created in the console, sent with each request in the Authorization header. See Authentication.

Global conventions

  • Errors use standard HTTP status codes for the class, with a body in the prefix's own format for the cause. See Errors.
  • Exceeding a quota returns 429, and a response header tells you when to retry. See Rate limits.
  • Versions live in the address; deprecations are announced 90 days ahead via standard headers. See Versioning.
  • Information about the API itself (OpenAPI description, health) lives under the /meta prefix.

First request

curl https://api.deepraxis.com/model/v1/chat/completions \
  -H "Authorization: Bearer $PRAXIS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "deepseek-flash", "messages": [{"role": "user", "content": "Hello"}]}'

Authentication

Every endpoint uses the same credential: an API Key created in the console, sent with each request in the Authorization header. There is no other authentication method and no per-endpoint rules.

One header

Authorization: Bearer {key}
PartMeaningExample
BearerLiteral schemeBearer
{key}Your API Key, starting with sk-praxis-sk-praxis-a1b2…

One Key works across every prefix. Keys are created, rotated, and revoked at Console → API Keys; revocation takes effect immediately.

Where each SDK puts the Key

You don't assemble the header yourself — the official SDKs do it; we also accept the header names those SDKs send by default.

SDKWhat you setHeader actually sent
OpenAI SDKapiKeyAuthorization: Bearer …
Anthropic SDKapiKeyX-API-Key: …
Google GenAI SDKapiKeyx-goog-api-key: …
E2B SDKapiKeyX-API-Key: …
Tavily SDK / HTTPapiKeyAuthorization: Bearer …

Try one

curl https://api.deepraxis.com/model/v1/models \
  -H "Authorization: Bearer $PRAXIS_API_KEY"

What an auth failure looks like

A missing, invalid, or revoked Key returns 401, with a body in the format of that prefix (see Errors). Never retry a 401 — fix the Key and send again.

Safekeeping

  • Use it server-side only; never ship it in a browser, mobile app, or public repository.
  • Use an environment variable (PRAXIS_API_KEY in the examples), not code.
  • If you suspect a leak, revoke it in the console and create a new one; the old Key stops working immediately.

Errors

When something fails, the HTTP status code tells you the class of the failure; the body gives the specific cause in the format of that prefix; and every error response also carries four x-praxis-problem-* headers plus one x-praxis-recovery-action, so retry logic only needs the headers, whatever the body looks like.

Status codes

StatusMeaningWhat to do
400Invalid request fields or formatCorrect the parameters; do not retry unchanged
401Missing or invalid credentialsCheck your API key
402Insufficient balance or paid allowanceAdd funds or contact your account administrator
403Access deniedCheck key permissions and resource ownership; contact support if needed
404Resource, model or route not foundCheck the ID, model name and path
408Request timed outCheck connectivity before retrying; verify whether writes completed first
409Resource state or concurrent update conflictRead the current state and adjust the request
413Payload or file too largeReduce the payload or use a URL input supported by the endpoint
422Request content cannot be processedCorrect parameters or input using the error details
429Rate, concurrency or model quota exceededHonor retry-after; let in-flight requests finish when concurrency is full
500Internal platform errorRetry later; contact support with X-Request-Id if it persists
501Capability not implementedUse a supported endpoint; do not retry
502Upstream call failed or returned an invalid responseBack off and retry; switch models or contact support if it persists
503Service or eligible route temporarily unavailableBack off and retry, or select another model
504Upstream response timed outBack off and retry; check write results first to avoid duplicate creation

Error codes

These are common machine-readable codes, not an exhaustive enum for every endpoint. Compatible error bodies may use protocol-specific code/type values. For cross-protocol handling, read x-praxis-problem-code, which can differ from the body code. Codes are case-sensitive.

codeWhen it occurs and what to do
AUTHENTICATION_ERRORThe key is missing or invalid; check or replace your credentials.
VALIDATION_ERRORA parameter violates a format, type or range requirement; correct it using the details.
INPUT_NOT_REPRESENTABLEThe selected model or protocol cannot represent an input option; remove the option or switch models.
NOT_FOUNDThe resource is absent or not visible to this account; check the ID and account.
MODEL_NOT_FOUNDThe model is absent or not visible; select an available name from the model list.
MODEL_PROTOCOL_NOT_OFFEREDThe model does not offer this protocol; use a supported endpoint or another model.
MODEL_PROTOCOL_LINE_UNAVAILABLEQualified routes for the protocol are unavailable; back off and retry or switch models.
GENERATION_NOT_FOUNDThe generation is absent or belongs to another account; check the generation ID from the response headers and the key.
RATE_LIMITEDA rate or concurrency limit was exceeded; honor retry-after and reduce rate or concurrency.
UPSTREAM_ERRORThe upstream call failed or returned an invalid response; retry with backoff when retryable, then switch models or contact support if it persists.
PROVIDER_SELECTION_NOT_ALLOWEDProvider order/only was supplied without BYOK; remove provider selection or provide your own upstream key.
not_implementedThe endpoint or capability is not implemented; use a supported capability instead of retrying.
model_protocol_not_offeredHTTP 404: the model does not declare the requested protocol. Check supported_apis in GET /model/v1/models and use the corresponding endpoint. For Google models, use /google/v1beta/models/{model}:generateContent with a Google request body; changing only the prefix is insufficient.
provider_unavailableHTTP 502: all available routes for this request failed. Retry with backoff; if failures persist, switch models and contact support with X-Request-Id.
thinking_disable_unsupportedHTTP 400: thinking cannot be disabled, for example reasoning_effort="none" on glm-5.3. Omit the disabling setting or choose a supported effort level; switch models if you need thinking disabled.
insufficient_quota / INSUFFICIENT_BALANCEHTTP 402: insufficient balance; body or header codes vary by endpoint. Add funds or contact your account administrator before retrying; avoid immediate retry loops.
validation_error (response_format)HTTP 400, for example: Model "deepseek-flash" does not support json_schema on this API. Switch to a model supporting json_schema on this endpoint. If valid JSON alone is sufficient, use json_object; it does not enforce a schema.
validation_error (named parameter)HTTP 400: with provider.require_parameters=true, the model may reject a requested parameter. For example, param: "logprobs" accompanies does not support the requested logprobs value. Adjust the named parameter or switch models. Disabling the check does not prove the parameter takes effect.

Error body

The body format follows the first segment of the address, same as success responses — your SDK needs no special handling for errors.

Vendor prefixes (/openai /anthropic /google /e2b /tavily): identical to that vendor's official API error body.

// /openai
{ "error": { "code": 401, "message": "Invalid API key." } }
// /anthropic
{ "type": "error", "error": { "type": "authentication_error", "message": "Invalid API key." } }

Praxis prefixes (/agent /model /sandbox /search /meta): standard Problem Details (RFC 9457), Content-Type: application/problem+json.

{
  "type": "https://deepraxis.ai/problems/authentication_error",
  "title": "authentication_error",
  "status": 401,
  "detail": "Invalid API key.",
  "instance": "problem_eqfnxu",
  "code": "AUTHENTICATION_ERROR",
  "retryable": false
}
FieldMeaning
typeURL of the error type, stable, safe to branch on
title / detailHuman-readable summary and specific cause
statusSame as the HTTP status code
instanceID of this error, attach it when contacting support
codeMachine-readable error code
retryableWhether retrying verbatim might succeed

Error headers (five common + one rate-limit header)

The five common headers are independent of body format; the sixth, scope, applies to rate-limit errors:

HeaderMeaningExample
x-praxis-problem-codeCross-protocol classification; may differ from the body's codeAUTHENTICATION_ERROR
x-praxis-problem-kindBroad class — what brokeauthentication_failure
x-praxis-problem-originWho owns it — who can fix it: user (your request or credential), platform (us), upstream_provider (the vendor), etc.unknown
x-praxis-problem-retryableWhether retrying verbatim might succeedfalse
x-praxis-problem-scopeRate-limit layer, when applicable: platform or modelplatform
x-praxis-recovery-actionSuggested actionrelogin

Retrying

  • retryable is true (or status 429 502 503): retry with exponential backoff; for 429 honor retry-after first.
  • Everything else: never retry verbatim — fix the request or the Key first.

Rate limits

Praxis rate limiting has two layers: the platform layer caps requests per second and concurrent requests per Key; the model layer caps requests per minute (RPM) and tokens per minute (TPM) per model. Every response — success or 429 — carries three x-ratelimit-* headers stating your current allowance and when it resets, so you never have to guess or spend a request to check.

The two layers

LayerCounted byCappedWhen exceeded
PlatformYour Key (source IP when no credential is sent)Requests per second, concurrent requests429 + retry-after; wait and retry
ModelModel × tenantRequests per minute (RPM), tokens per minute (TPM), monthly budget429, see the model layer below

Both layers return the same three rate limit headers; which layer tripped is stated in the error body (Errors).

Platform layer: requests per second and concurrency

By default, each API key allows 5 requests per second and 4 concurrent in-flight requests. Streams occupy a concurrency slot until they finish. Exceeding either limit returns 429 with ratelimit-limit, ratelimit-remaining, ratelimit-reset and retry-after; when concurrency is full, let an existing request finish.

Configured limits may differ; use the actual response headers and concurrency error details.

Three response headers

x-ratelimit-limit-requests: 5
x-ratelimit-remaining-requests: 4
x-ratelimit-reset-requests: 850ms
HeaderMeaning
x-ratelimit-limit-requestsThis credential's requests-per-second ceiling
x-ratelimit-remaining-requestsRequests still available in this second
x-ratelimit-reset-requestsTime until the allowance resets: 850ms under a second, 1s or more above it

The same three numbers are also available under the IETF names RateLimit-Limit / RateLimit-Remaining / RateLimit-Reset (whole seconds). The default is 5 requests/second and 4 in flight; response headers reflect configured request-rate overrides.

Exceeding the per-second limit

The (N+1)th request within one second — N being the Key's per-second ceiling — is answered 429 with a retry-after header (whole seconds, usually 1). Rejected requests do not consume the allowance: x-ratelimit-remaining-requests stays 0, and the window simply resets.

Exceeding the concurrency limit

When the number of in-flight requests — including unfinished streaming responses, which hold their slot until the stream ends — exceeds the Key's concurrency ceiling, extra requests get 429 with retry-after: 1. Resetting the per-second window does not free a concurrency slot: an in-flight request must finish first. Which limit tripped is spelled out in the error message ("Concurrent request limit …" / "Requests per second limit …").

Error body

The error body follows the first path segment (see Errors). Native endpoints such as /model/v1/chat/completions return Problem Details:

{
  "type": "https://deepraxis.ai/problems/rate_limit",
  "title": "rate_limited",
  "status": 429,
  "detail": "Requests per second limit of 5 exceeded for this credential. Retry after the listed wait.",
  "instance": "problem_eqfnxu",
  "kind": "rate_limit",
  "scope": "platform",
  "retryable": true
}

scope: "platform" means the platform layer triggered it. Vendor-prefixed endpoints speak that vendor's own error format — for the OpenAI-compatible endpoints:

{ "error": { "code": 429, "type": "rate_limit_error", "message": "Requests per second limit of 5 exceeded for this credential. Retry after the listed wait." } }

Requests without a credential

Public endpoints (such as GET /model/v1/models) can be called without a Key; those are counted per source IP against a smaller anonymous allowance, with the same response headers. Sending a Key switches accounting to the Key, regardless of IP.

GET /meta/v1/health is never rate limited — point uptime monitors at it freely.

Model layer: requests and tokens per minute

The model layer counts per model × tenant × minute, not per API Key:

  • Each model carries its own RPM and TPM in its model metadata; unset or 0 means unlimited.
  • Hitting either limit returns 429 with type rate_limit_error, Retry-After: 60, and problem.details.rateLimit carrying the current value and the cap.
  • BYOK calls bring their own provider credentials and do not count against platform model limits.
  • Upstream provider rate limits are handled by automatic failover to other providers; when none remain, the upstream 429 is returned.

Models also carry a monthly budget based on cumulative revenue for the month; exceeding it returns 429 with type budget_error (QUOTA_EXHAUSTED) and no Retry-After — waiting does not help; the model's budget must be raised.

For status codes and error bodies see Errors; for account quotas see Quotas & rate limits.

Versioning

The version is part of the address, immediately after the first segment; each prefix is versioned independently — there is no site-wide version number.

The version segment in the address

https://api.deepraxis.com/{protocol}/{version}/…
PrefixVersion segmentDecided by
/openai /anthropicv1Follows the vendor
/googlev1betaFollows the vendor
/e2b /tavilynoneFollows the vendor
/agent /model /sandbox /search /metav1Praxis

Under vendor prefixes, version-related headers (such as Anthropic's anthropic-version) are passed through to the vendor as-is, behaving exactly like the official API.

What counts as breaking

Removing fields, changing a field's type or meaning, changing defaults, tightening validation, changing what an error code means. Adding fields, adding endpoints, and loosening validation are not breaking.

Beta and GA

  • Beta: marked "Beta" on the endpoint page. May change at any time with no compatibility promise; fine for trying out, not recommended for production.
  • GA: breaking changes ship only as a new version segment (e.g. /model/v2/…); the old version keeps working.

How deprecation is announced

When an old version or endpoint is deprecated:

  1. A changelog announcement, with a replacement path;
  2. That endpoint's responses carry two standard headers: Deprecation (RFC 9745, when it was deprecated) and Sunset (RFC 8594, when it goes away), plus a Link header pointing to migration notes;
  3. At least 90 days between announcement and shutdown; afterwards it returns 404.
Deprecation: @1767225600
Sunset: Sat, 04 Apr 2026 00:00:00 GMT
Link: </docs/changelog>; rel="deprecation"