Developer API
API reference
Overview
EdifacePay exposes a documented subset of the OpenAI Chat Completions request shape: listing models and creating text chat completions, with or without streaming. Requests are billed to your prepaid balance through the same reservation and ledger path as the workspace.
It is not a full OpenAI-compatible API, and it is not compatible with the Anthropic SDK or with tools that require features outside this page. Parameters that are not listed here are rejected with HTTP 400 rather than silently ignored, so a request that succeeds did what it said.
Base URL: https://www.edifacepay.org/v1
Authentication
Create a key under API keys. The secret is shown once; only a keyed hash is stored. Send it as a Bearer token:
Authorization: Bearer efp_…Revoked, expired or unknown keys receive 401. Keys of a suspended account receive 403. Provider credentials are never exposed — your key only authenticates you to EdifacePay.
GET /v1/models
Returns the models that can be called right now (enabled, provider configured, last live test passed).
curl https://www.edifacepay.org/v1/models -H "Authorization: Bearer $EDIFACEPAY_API_KEY"{ "object": "list",
"data": [{ "id": "claude-opus-5", "object": "model", "owned_by": "…",
"context_window": 200000, "max_output_tokens": 64000 }] }POST /v1/chat/completions
curl https://www.edifacepay.org/v1/chat/completions \
-H "Authorization: Bearer $EDIFACEPAY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 6f1c…" # optional \
-d '{ "model": "claude-opus-5",
"max_completion_tokens": 1024,
"messages": [
{ "role": "system", "content": "Be concise." },
{ "role": "user", "content": "Explain idempotency in one paragraph." } ] }'| Field | Support |
|---|---|
| model | Required. An id from /v1/models. |
| messages | Required. Roles system, developer, user, assistant. system/developer messages are only accepted before the first user message and are joined into one system prompt. content is a string or an array of {"type":"text"} parts. |
| max_completion_tokens / max_tokens | Optional positive integer; if both are sent they must match. Bounds visible and hidden reasoning tokens. Default 16,000, capped at the model’s maximum. The full allowance is reserved from your balance before the request is sent. |
| stream | Optional boolean. See Streaming. |
| stream_options.include_usage | Optional. Adds a final usage chunk. |
| temperature, top_p | 0–1, only on models whose catalogue entry allows sampling parameters; otherwise 400 unsupported_parameter. |
| n | Only 1. |
| response_format | Only {"type":"text"}. |
| user, metadata | Accepted and ignored. Not forwarded to the provider. |
Response (non-streaming):
{ "id": "chatcmpl-req_…", "object": "chat.completion", "model": "claude-opus-5",
"choices": [{ "index": 0, "finish_reason": "stop",
"message": { "role": "assistant", "content": "…" } }],
"usage": { "prompt_tokens": 31, "completion_tokens": 58, "total_tokens": 89,
"prompt_tokens_details": { "cached_tokens": 0 } },
"edifacepay": { "request_id": "req_…", "status": "settled", "cost_usd": "0.000321" } }finish_reason is stop, length (output limit reached) or content_filter (the model declined). The edifacepay object is an extension: the request id you will find under Usage, and the exact amount debited. The header x-edifacepay-request-id carries the same id.
Streaming
With "stream": true the response is text/event-stream of chat.completion.chunk objects, ending with data: [DONE]. With include_usage, the last chunk before [DONE] has empty choices and carries usage and edifacepay. If the provider fails mid-stream, the stream ends with a single {"error":…} object and no [DONE].
Disconnecting cancels. If you close the connection, the upstream generation is aborted. Providers bill what was generated before the abort and do not report it; see below.
Billing behaviour
- Reserve: before the provider is called, a conservative maximum (estimated input + the full output allowance) is reserved atomically. If your available balance, your account limits or the key’s limits cannot cover it, the request is refused with
402and nothing is sent. Lowermax_completion_tokensto reserve less. - Settle: cost = provider-reported tokens × the price version captured at reservation, summed over input, cached input, cache write and output, rounded up once to $0.000001. The unused part of the reservation is released immediately.
- Uncertain usage: if a stream is cancelled or interrupted before the provider reports usage, the reservation stays held as
pending_reconciliation, then settles from an estimate (≈4 bytes per token over what was actually received, capped at the reservation) that is markedestimatedon the usage record. Requests the provider rejected outright are not charged. - No automatic retries. EdifacePay never re-sends a generation that may already have been billed upstream. Retry from your side; use
Idempotency-Keyso an accidental duplicate is refused with409instead of being billed twice.
Errors & limits
{ "error": { "message": "…", "type": "invalid_request_error", "param": "tools", "code": "unsupported_parameter" } }| Status | Meaning |
|---|---|
| 400 | Invalid or unsupported parameter, context length exceeded (nothing is truncated for you). |
| 401 / 403 | Missing, invalid, revoked or expired key / suspended account. |
| 402 | Insufficient credits, or an account or key spending limit would be exceeded. |
| 409 | An Idempotency-Key was reused. |
| 413 | Message content above 1,500,000 bytes. |
| 429 | More than 60 requests per minute on one key (see Retry-After), or the provider is rate limiting the service. |
| 502 / 503 | Provider error, or the model is not available on this deployment. |
A single generation is stopped after 280 seconds.
Not supported
Tool and function calling, JSON mode and structured outputs, images, audio and files, stop, seed, logprobs, logit_bias, penalties, reasoning_effort, n > 1, stored completions, embeddings, the Responses API, the Assistants API, batch and fine-tuning endpoints. Each is rejected with 400.