Model API
One address speaks both the OpenAI and the Anthropic SDKs: point either SDK at its base URL below and change nothing else.
Model runs inference and lists model capabilities and prices through /model/v1. Each protocol surface follows its native provider (OpenAI / Anthropic / Google), so experience with that protocol applies. Differences: use catalog model ids unchanged, including creator prefixes, and only their declared supported_apis without protocol conversion; usage.cost, when present, is the customer charge in USD, not upstream cost; thinking levels map to the selected same-protocol model's effort or token budget, and unsupported disabling is rejected; explicitly unsupported fields return their documented error, ignored fields have no effect, and unknown top-level Chat, Responses, Messages and Embeddings fields pass to the same-protocol upstream. Allow room for reasoning within the completion-token cap before expecting tool arguments or structured output. Verify settled cost with praxis.model.generation.retrieve using X-Praxis-Generation-Id or chat providerMetadata.praxis.generationId; absent cost or id does not mean a free call. Start with praxis.model.models.list to choose a model by supported_apis, capabilities and per-unit prices.
Base URL
Get started
Loading…Configuring the two SDKs
| SDK | Base URL | Auth header | Endpoints |
|---|---|---|---|
| OpenAI SDK | Authorization: Bearer | chat, responses, embeddings, images, models, conversations | |
| Anthropic SDK | (the SDK appends /v1) | x-api-key or Authorization: Bearer | messages, count tokens |
Both use the same key, the same model names and the same bill — switching SDKs changes nothing else. Conversations (create, items, delete) are the cross-call state container, shaped like the official OpenAI conversations API.
Model fallback and your own keys
The chat request body accepts providerOptions.praxis:
| Field | Effect |
|---|---|
models | Candidate models, tried in order when the requested model fails |
byok | Your own upstream keys, by provider name; if yours fails, the platform's key is used |
order / only | Provider order or allow-list, accepted only together with byok |
The response's providerMetadata.praxis reports the call's generationId, cost, credential (platform or byok) and the model that served it; use generationId to look up the generation. Other endpoints do not accept providerOptions.praxis yet and answer 400.
Endpoints
| Method | Path | Description | Support |
|---|---|---|---|
| POST | /v1/chat/completions | Create chat completion | ● Supported |
| POST | /v1/responses | Create a model response | ● Supported |
| GET | /v1/responses/{response_id} | Retrieve a response | ● Supported |
| DELETE | /v1/responses/{response_id} | Delete a response | ● Supported |
| POST | /v1/responses/{response_id}/cancel | Cancel a response | ◐ Partial |
| GET | /v1/responses/{response_id}/input_items | List input items | ● Supported |
| POST | /v1/responses/compact | Compact a response | ○ Unsupported |
| POST | /v1/responses/input_tokens | Count input tokens | ○ Unsupported |
| POST | /v1/embeddings | Create embeddings | ● Supported |
| POST | /v1/rerank | Rerank documents | ● Supported |
| POST | /v1/audio/speech | Generate speech | ● Supported |
| POST | /v1/audio/transcriptions | Transcribe audio | ● Supported |
| POST | /v1/images/generations | Create image | ● Supported |
| POST | /v1/images/edits | Create image edit | ● Supported |
| POST | /v1/ocr | Extract document text | ● Supported |
| POST | /v1/videos | Create video | ● Supported |
| GET | /v1/videos | List videos | ● Supported |
| GET | /v1/videos/{video_id} | Retrieve video | ● Supported |
| GET | /v1/videos/{video_id}/content | Download video content | ● Supported |
| DELETE | /v1/videos/{video_id} | Delete video | ● Supported |
| POST | /v1/videos/{video_id}/remix | Remix video | ○ Unsupported |
| POST | /v1/messages | Create a Message | ● Supported |
| POST | /v1/messages/count_tokens | Count tokens | ◐ Partial |
| GET | /v1/models | List models | ● Supported |
| GET | /v1/models/{model} | Retrieve model | ● Supported |
| GET | /v1/generation | Look up a generation | ● Supported |
| POST | /v1/conversations | Create a conversation | ● Supported |
| GET | /v1/conversations/{conversation_id} | Retrieve a conversation | ● Supported |
| POST | /v1/conversations/{conversation_id} | Update a conversation | ● Supported |
| POST | /v1/conversations/{conversation_id}/items | Create conversation items | ● Supported |
| GET | /v1/conversations/{conversation_id}/items | List conversation items | ● Supported |
| GET | /v1/conversations/{conversation_id}/items/{item_id} | Retrieve a conversation item | ● Supported |
| DELETE | /v1/conversations/{conversation_id}/items/{item_id} | Delete a conversation item | ● Supported |
| DELETE | /v1/conversations/{conversation_id} | Delete a conversation | ● Supported |
Differences from OpenAI / Anthropic
- Create chat completion:Unknown top-level fields are forwarded unchanged to same-protocol upstream providers, which decide whether to accept them. Declared fields still undergo type and range validation; invalid values return 400 naming the field.
- Create a model response:Unknown top-level fields are forwarded unchanged to same-protocol upstream providers, which decide whether to accept them. Declared fields still undergo type and range validation; invalid values return 400 naming the field.
- Retrieve a response:Reads a stored response by ID. If it was created with store set to false we did not store it, and the read returns 404 response_not_found; after the retention period (30 days by default) the read returns the same 404.
- Delete a response:Deletes a stored response by ID immediately. If it was created with store set to false we did not store it, and the delete returns 404 response_not_found.
- Cancel a response:Available only for responses created with background:true and routed to a model that can generate in the background. Cancel is idempotent — repeated calls return the same terminal response. Cancelling stops us reading the upstream stream; it cannot guarantee that compute already sent upstream stops, and usage is billed for what was actually received. Calling cancel on a non-background (synchronous) response returns 404 object_not_found if the response id does not exist (not stored, expired or wrong id), or 400 native_responses_operation_unsupported if the response exists but its provider does not declare cancel support (none of the upstreams we connect declares it for synchronous responses). Neither case is the not-implemented 501.
- List input items:Lists the input items of a stored response. Supports limit (1–100, default 20), order (asc/desc, default desc, as in the official API) and cursor pagination by item id with after; has_more / first_id / last_id match the page actually returned, so you can page through without gaps or repeats. Every item carries a server-issued id (msg_ for messages, and each of function_call / function_call_output / reasoning has its own prefix); older data stored before ids existed gets deterministic ids on read, without a destructive migration, so repeated reads with the same cursor stay stable. For a response created with previous_response_id, the list shows the full resolved input: the input and output items of the earlier responses in the chain plus the input submitted this turn; if an ancestor response was not stored on the platform (for example created with store false) or has expired, only this turn's own input is listed. If the response was created with store set to false we did not store it, and the list returns 404 response_not_found.
- Compact a response:Compacts a response's input into a summary. It depends on OpenAI Responses' official server-side storage (store) semantics, which we have not implemented yet; calling it returns 501 (message “This platform has not implemented … yet.”, with the x-should-retry header set to false), has no side effects, and the official SDK will not retry.
- Count input tokens:Counts the tokens the request input would consume without generating content. It depends on OpenAI Responses' official server-side storage (store) semantics, which we have not implemented yet; calling it returns 501 (message “This platform has not implemented … yet.”, with the x-should-retry header set to false), has no side effects, and the official SDK will not retry.
- Create embeddings:Unknown top-level fields are forwarded unchanged to same-protocol upstream providers, which decide whether to accept them. Declared fields still undergo type and range validation; invalid values return 400 naming the field.
- Rerank documents:Standard request fields; unrepresentable parameters return input_not_representable.
- Generate speech:melotts outputs WAV and supports input (including text/prompt aliases), lang and default audio options; aura-2-en uses native speaker names. See per-field limits below.
- Transcribe audio:Standard request fields; unrepresentable parameters return input_not_representable.
- Extract document text:Uses the Mistral OCR request and response shape at /model/v1/ocr only. model is required; document accepts document_url or image_url (HTTPS or base64 data URL), or
{type:"file", file_id:"<uploaded ID>"}to read a File owned by the authenticated tenant. The file_id read limit is 24 MiB (25,165,824 bytes: the shared 96 MiB memory budget divided by four). Larger files return 413 with guidance to use HTTPS document_url (PDF limit: 50 MiB). PNG/JPEG remain limited to 10 MiB; the bytes determine the type. Missing and other-tenant files both return 404. pages is an array of zero-based page indices; for images, only[0]is supported when supplied. File read failures are not billed, and request logs retain only the file_id, never the file content. Optional features depend on the model; unsupported options return 400. Errors use problem+json; providerOptions.praxis is not supported here. - Create video:Billed per second of output video; GET /model/v1/models exposes pricing.video_second in USD per second.
- List videos:Billed per second of output video; GET /model/v1/models exposes pricing.video_second in USD per second.
- Retrieve video:Billed per second of output video; GET /model/v1/models exposes pricing.video_second in USD per second.
- Download video content:Billed per second of output video; GET /model/v1/models exposes pricing.video_second in USD per second.
- Delete video:Billed per second of output video; GET /model/v1/models exposes pricing.video_second in USD per second.
- Remix video:Unsupported; returns HTTP 400. Do not retry.
- Create a Message:Unknown top-level fields are forwarded unchanged to same-protocol upstream providers, which decide whether to accept them. Declared fields still undergo type and range validation; invalid values return 400 naming the field.
- Count tokens:Returns a model-family-calibrated estimate, including Chinese text and tool definitions, with the response header x-praxis-token-count: estimated. Do not use it as an exact usage or billing count.
- List models:OCR models have type ocr and pricing.page as a decimal string in USD per page, a Praxis extension to the Vercel model list shape; the four token prices are 0. Other models omit pricing.page.
- Create a conversation:Creates a conversation, optionally with initial items (up to 20 per call) and metadata. Conversations are tenant-partitioned; the creating tenant is the only one that can reference it.
- Retrieve a conversation:Reads a conversation by ID. A missing or foreign-tenant conversation answers 404 conversation_not_found.
- Update a conversation:Replaces a conversation's metadata wholesale — it does not merge with existing metadata.
- Create conversation items:Appends items to a conversation (up to 20 per call) and returns exactly the appended items.
- List conversation items:Lists a conversation's items in creation order, with limit/after/order pagination.
- Retrieve a conversation item:Reads a single conversation item by ID.
- Delete a conversation item:Deletes one conversation item and returns the conversation object (not the deleted item).
- Delete a conversation:Deletes a conversation. Afterwards neither it nor its items can be referenced again (including as the conversation parameter of Responses create).
For authoritative request and response fields, see the OpenAI, Anthropic or Mistral documentation linked from each endpoint page. Call OCR over HTTP; it is not an OpenAI or Anthropic SDK endpoint.
Platform errors (auth, rate limits, validation) and OCR errors use problem+json; other model call errors follow the endpoint's own format (OpenAI or Anthropic), see errors; quotas and response headers are covered in rate limits.